<?php

namespace App\Mail;

use App\Models\MailingBounce;
use Illuminate\Mail\Events\MessageSending;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Mime\Email;

class UniversalBounceHandler
{
    /**
     * Handle the message sending event to check for suppressed recipients
     */
    public function handle(MessageSending $event): bool
    {
        $message = $event->message;

        // Extract all recipients from the message
        $allRecipients = $this->extractAllRecipients($message);
        $suppressedRecipients = [];

        // Check each recipient for suppression
        foreach ($allRecipients as $email) {
            if (MailingBounce::isSuppressed($email)) {
                $suppressedRecipients[] = $email;
            }
        }

        // If any recipients are suppressed, log and potentially block the email
        if (!empty($suppressedRecipients)) {
            Log::info("Email contains suppressed recipients", [
                'total_recipients' => count($allRecipients),
                'suppressed_recipients' => $suppressedRecipients,
                'subject' => $message->getSubject(),
            ]);

            // If ALL recipients are suppressed, block the email entirely
            if (count($suppressedRecipients) === count($allRecipients)) {
                Log::info("All recipients suppressed, blocking email", [
                    'suppressed_recipients' => $suppressedRecipients,
                    'subject' => $message->getSubject(),
                ]);
                return false; // Block the email
            }

            // If only some recipients are suppressed, remove them from the message
            $this->removeSuppressedRecipients($message, $suppressedRecipients);
        }

        // Add bounce tracking headers to all outgoing emails
        $this->addBounceTrackingHeaders($message);

        return true; // Allow the email to be sent
    }

    /**
     * Extract all recipient email addresses from the message
     */
    protected function extractAllRecipients($message): array
    {
        $recipients = [];

        // Get TO recipients
        if ($message->getTo()) {
            foreach ($message->getTo() as $address) {
                $recipients[] = $address->getAddress();
            }
        }

        // Get CC recipients
        if ($message->getCc()) {
            foreach ($message->getCc() as $address) {
                $recipients[] = $address->getAddress();
            }
        }

        // Get BCC recipients
        if ($message->getBcc()) {
            foreach ($message->getBcc() as $address) {
                $recipients[] = $address->getAddress();
            }
        }

        return array_unique($recipients);
    }

    /**
     * Remove suppressed recipients from the message
     */
    protected function removeSuppressedRecipients($message, array $suppressedEmails): void
    {
        // Remove from TO recipients
        $toAddresses = $message->getTo();
        if ($toAddresses) {
            $filteredTo = [];
            foreach ($toAddresses as $address) {
                if (!in_array($address->getAddress(), $suppressedEmails)) {
                    $filteredTo[] = $address;
                }
            }
            $message->to(...$filteredTo);
        }

        // Remove from CC recipients
        $ccAddresses = $message->getCc();
        if ($ccAddresses) {
            $filteredCc = [];
            foreach ($ccAddresses as $address) {
                if (!in_array($address->getAddress(), $suppressedEmails)) {
                    $filteredCc[] = $address;
                }
            }
            $message->cc(...$filteredCc);
        }

        // Remove from BCC recipients
        $bccAddresses = $message->getBcc();
        if ($bccAddresses) {
            $filteredBcc = [];
            foreach ($bccAddresses as $address) {
                if (!in_array($address->getAddress(), $suppressedEmails)) {
                    $filteredBcc[] = $address;
                }
            }
            $message->bcc(...$filteredBcc);
        }
    }

    /**
     * Add bounce tracking headers to outgoing emails
     */
    protected function addBounceTrackingHeaders($message): void
    {
        $bounceEmail = timebank_config('mailing.bounce_address');

        if (!$bounceEmail) {
            return;
        }

        if ($message instanceof Email) {
            $headers = $message->getHeaders();

            // Add Return-Path for bounce routing (if not already set)
            if (!$headers->has('Return-Path')) {
                $headers->addPathHeader('Return-Path', $bounceEmail);
            }

            // Add bounce tracking headers
            $headers->addTextHeader('X-Bounce-Tracking', 'universal');
            $headers->addTextHeader('X-Bounce-Handler', 'timebank-cc');

            // Add recipient tracking for the first recipient (for bounce processing)
            $recipients = $this->extractAllRecipients($message);
            if (!empty($recipients)) {
                $headers->addTextHeader('X-Primary-Recipient', $recipients[0]);
            }

            // Set Return-Path on the message
            $message->returnPath($bounceEmail);
        }
    }
}