<?php

namespace App\Services\Email;

use App\Models\EmailTemplate;
use App\Models\Invoice;
use App\Models\Quotation;
use App\Models\Receipt;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;

class DocumentEmailService
{
    public function __construct(
        private readonly EmailTemplateService $templates,
        private readonly EmailPlaceholderService $placeholders,
        private readonly EmailSenderService $sender,
    ) {}

    /**
     * @param  array<string, mixed>  $input
     */
    public function sendDocument(
        Model $document,
        string $category,
        array $input,
        User $sender,
    ): \App\Models\EmailMessage {
        $template = isset($input['email_template_id'])
            ? EmailTemplate::query()->findOrFail($input['email_template_id'])
            : $this->templates->defaultForCategory($category);

        if ($template === null) {
            throw new \RuntimeException('No email template found for this document type.');
        }

        $placeholderData = $this->placeholders->build($document, [
            'custom_message' => $input['custom_message'] ?? '',
            'payment_link' => $input['payment_link'] ?? null,
        ], $sender);

        $rendered = $this->templates->render($template, $placeholderData);

        $to = $input['to'] ?? $placeholderData['client_email'] ?? null;

        if (! filled($to)) {
            throw new \InvalidArgumentException('No recipient email address found. Enter a recipient manually.');
        }

        $message = $this->sender->compose([
            'email_template_id' => $template->id,
            'to' => $to,
            'cc' => $input['cc'] ?? null,
            'bcc' => $input['bcc'] ?? null,
            'subject' => $input['subject'] ?? $rendered['subject'],
            'body_html' => $input['body_html'] ?? $rendered['body_html'],
            'related_module' => match (true) {
                $document instanceof Invoice => 'invoice',
                $document instanceof Quotation => 'quotation',
                $document instanceof Receipt => 'receipt',
                default => 'general',
            },
        ], $document, $sender->id);

        return $this->sender->queueSend(
            $message,
            $input['attachments'] ?? null,
            (bool) ($input['attach_pdf'] ?? true),
        );
    }

    public function composePreview(Model $document, string $category, ?EmailTemplate $template = null, ?User $sender = null): array
    {
        $template ??= $this->templates->defaultForCategory($category);

        if ($template === null) {
            throw new \RuntimeException('No template available.');
        }

        $placeholderData = $this->placeholders->build($document, [], $sender);
        $rendered = $this->templates->render($template, $placeholderData);

        return [
            'template' => $template,
            'to' => $placeholderData['client_email'] ?? '',
            'subject' => $rendered['subject'],
            'body_html' => $this->templates->wrapPreview($rendered['body_html']),
            'placeholders' => $placeholderData,
        ];
    }
}
