<?php

namespace App\Mail;

use Illuminate\Support\Facades\Http;
use Symfony\Component\Mailer\Exception\TransportException;
use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mailer\Transport\AbstractTransport;
use Symfony\Component\Mime\Email;

class MailketingTransport extends AbstractTransport
{
    public function __construct(
        protected string $apiToken,
        protected string $endpoint,
        protected ?string $defaultFromName = null,
        protected ?string $defaultFromEmail = null,
        protected int $timeoutSeconds = 10,
    ) {
        parent::__construct();
    }

    public function __toString(): string
    {
        return 'mailketing';
    }

    protected function doSend(SentMessage $message): void
    {
        $email = $message->getOriginalMessage();

        if (! $email instanceof Email) {
            throw new TransportException('Mailketing transport only supports Symfony Email messages.');
        }

        if ($email->getAttachments()) {
            throw new TransportException('Mailketing transport does not support attachments without URL references.');
        }

        $from = $email->getFrom()[0] ?? null;
        $fromName = $from?->getName() ?: $this->defaultFromName ?: '';
        $fromEmail = $from?->getAddress() ?: $this->defaultFromEmail ?: '';

        if ($fromEmail === '') {
            throw new TransportException('Mailketing transport requires a from email address.');
        }

        $subject = $email->getSubject() ?? '';
        $content = $email->getHtmlBody() ?? $email->getTextBody() ?? '';

        $recipients = array_merge(
            $email->getTo(),
            $email->getCc(),
            $email->getBcc(),
        );

        if ($recipients === []) {
            throw new TransportException('Mailketing transport requires at least one recipient.');
        }

        foreach ($recipients as $recipient) {
            $response = Http::asForm()
                ->timeout($this->timeoutSeconds)
                ->post($this->endpoint, [
                    'api_token' => $this->apiToken,
                    'from_name' => $fromName,
                    'from_email' => $fromEmail,
                    'recipient' => $recipient->getAddress(),
                    'subject' => $subject,
                    'content' => $content,
                ]);

            if (! $response->ok()) {
                throw new TransportException(sprintf(
                    'Mailketing request failed (%s): %s',
                    $response->status(),
                    $response->body()
                ));
            }

            $payload = $response->json();
            if (is_array($payload) && (($payload['status'] ?? null) !== 'success')) {
                $detail = $payload['response'] ?? $payload['message'] ?? 'unknown';
                throw new TransportException('Mailketing responded with an error: '.$detail);
            }
        }
    }
}
