<?php

namespace App\Mail;

use App\Models\MailingBounce;
use Illuminate\Mail\MailManager;
use Illuminate\Mail\PendingMail;
use Illuminate\Support\Facades\Log;

class BounceAwareMailManager extends MailManager
{
    /**
     * Begin the process of mailing a mailable class instance with bounce checking
     */
    public function to($users, $name = null)
    {
        $pendingMail = new BounceAwarePendingMail($this);
        return $pendingMail->to($users, $name);
    }

    /**
     * Send a mailable with bounce suppression checking
     */
    public function send($view, array $data = [], $callback = null)
    {
        // If this is called directly with a mailable, we need to intercept
        if (is_object($view) && method_exists($view, 'build')) {
            return $this->sendWithBounceCheck($view);
        }

        return parent::send($view, $data, $callback);
    }

    /**
     * Send mailable with bounce checking
     */
    protected function sendWithBounceCheck($mailable)
    {
        // Extract recipient email addresses
        $recipients = $this->extractRecipients($mailable);

        // Filter out suppressed emails
        $filteredRecipients = [];
        foreach ($recipients as $recipient) {
            $email = is_string($recipient) ? $recipient : ($recipient['address'] ?? $recipient->email ?? null);

            if ($email && MailingBounce::isSuppressed($email)) {
                Log::info("Email sending blocked for suppressed address: {$email}", [
                    'mailable_class' => get_class($mailable),
                    'suppressed' => true
                ]);
                continue;
            }

            $filteredRecipients[] = $recipient;
        }

        // If all recipients are suppressed, don't send
        if (empty($filteredRecipients)) {
            Log::info("All recipients suppressed, skipping email send", [
                'mailable_class' => get_class($mailable),
                'original_recipients' => count($recipients),
                'suppressed_count' => count($recipients)
            ]);
            return;
        }

        // Update mailable recipients
        $this->updateMailableRecipients($mailable, $filteredRecipients);

        // Add bounce tracking if the mailable supports it
        if (method_exists($mailable, 'configureBounceTracking') || in_array('App\Mail\Concerns\TracksBounces', class_uses_recursive($mailable))) {
            $mailable->configureBounceTracking = true;
        }

        return parent::send($mailable);
    }

    /**
     * Extract recipient email addresses from mailable
     */
    protected function extractRecipients($mailable): array
    {
        $recipients = [];

        // Get recipients from the mailable's to property
        if (property_exists($mailable, 'to') && $mailable->to) {
            $recipients = array_merge($recipients, $mailable->to);
        }

        return $recipients;
    }

    /**
     * Update mailable recipients after filtering
     */
    protected function updateMailableRecipients($mailable, array $filteredRecipients): void
    {
        if (property_exists($mailable, 'to')) {
            $mailable->to = $filteredRecipients;
        }
    }
}