<?php

namespace App\Mail;

use App\Models\Mailing;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\App;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;

class NewsletterMail extends Mailable
{
    use Queueable, SerializesModels;

    protected $mailing;
    protected $recipient;
    protected $contentBlocks;
    protected $recipientLocale;
    protected $isTestMail;
    protected $fromBulkJob = false;

    /**
     * Create a new message instance.
     */
    public function __construct(Mailing $mailing, $recipientOrLocale, $contentBlocksOrIsTest = null, $locale = null, $fromBulkJob = false)
    {
        $this->mailing = $mailing;
        $this->fromBulkJob = $fromBulkJob;

        // Handle test mail mode (when second parameter is a locale string and third is boolean)
        if (is_string($recipientOrLocale) && is_bool($contentBlocksOrIsTest)) {
            $this->recipientLocale = $recipientOrLocale;
            $this->isTestMail = $contentBlocksOrIsTest;
            $this->recipient = null;
            $this->contentBlocks = $this->generateContentBlocksForLocale($this->recipientLocale);
        } else {
            // Normal mode (backward compatibility)
            $this->recipient = $recipientOrLocale;
            $this->recipientLocale = $locale ?: ($recipientOrLocale->lang_preference ?? timebank_config('base_language', 'en'));
            $this->isTestMail = false;
            $this->contentBlocks = $contentBlocksOrIsTest ?: $this->generateContentBlocks();
        }
    }


    /**
     * Build the message.
     */
    public function build()
    {
        // Set locale for the email
        App::setLocale($this->recipientLocale);

        $fromAddress = timebank_config("mailing.from_address.{$this->mailing->type}");

        $subject = $this->mailing->getSubjectForLocale($this->recipientLocale);
        if ($this->isTestMail) {
            $subject = "[TEST - {$this->recipientLocale}] " . $subject;
        }

        $mail = $this
            ->from($fromAddress, config('app.name'))
            ->subject($subject)
            ->view('emails.newsletter.wrapper')
            ->with([
                'subject' => $subject,
                'mailingTitle' => $this->mailing->title,
                'locale' => $this->recipientLocale,
                'contentBlocks' => $this->contentBlocks,
                'unsubscribeUrl' => $this->generateUnsubscribeUrl(),
                'isTestMail' => $this->isTestMail,
            ]);

        // Add bounce tracking headers
        $bounceEmail = config('mail.bounce_processing.bounce_address', config('mail.from.address'));
        if ($bounceEmail && !$this->isTestMail) {
            $mail->withSymfonyMessage(function ($message) use ($bounceEmail) {
                $headers = $message->getHeaders();

                // Set Return-Path for bounce handling
                $headers->addPathHeader('Return-Path', $bounceEmail);

                // Add custom tracking headers
                $headers->addTextHeader('X-Mailing-ID', $this->mailing->id);
                $headers->addTextHeader('X-Recipient-Email', $this->recipient->email ?? '');

                // Add envelope sender
                $message->returnPath($bounceEmail);
            });
        }

        return $mail;
    }

    /**
     * Generate content blocks with proper translations
     */
    protected function generateContentBlocks()
    {
        $blocks = [];

        foreach ($this->mailing->getSelectedPostsWithTranslations() as $post) {
            // Get translation for recipient's language with fallback
            $translation = $this->mailing->getPostTranslationForLocale($post->id, $this->recipientLocale);

            if (!$translation) {
                continue; // Skip posts without translations
            }

            // Determine post type for template selection
            $postType = $this->determinePostType($post);

            // Prepare post data for template
            $postData = $this->preparePostData($post, $translation);

            $blocks[] = [
                'type' => $postType,
                'data' => $postData,
                'template' => timebank_config("mailing.templates.{$postType}_block")
            ];
        }

        return $blocks;
    }

    /**
     * Generate content blocks for a specific locale (test mode)
     */
    protected function generateContentBlocksForLocale($locale)
    {
        $blocks = [];
        $contentBlocks = $this->mailing->getContentBlocksForLocale($locale);

        foreach ($contentBlocks as $block) {
            $post = \App\Models\Post::with(['translations', 'category'])->find($block['post_id']);

            if (!$post) {
                continue;
            }

            // Get translation for the specific locale
            $translation = $this->mailing->getPostTranslationForLocale($post->id, $locale);

            if (!$translation) {
                continue; // Skip posts without translations in this locale
            }

            // Determine post type for template selection
            $postType = $this->determinePostType($post);

            // Prepare post data for template
            $postData = $this->preparePostData($post, $translation);

            $blocks[] = [
                'type' => $postType,
                'data' => $postData,
                'template' => timebank_config("mailing.templates.{$postType}_block")
            ];
        }

        return $blocks;
    }

    /**
     * Determine post type based on category or content
     */
    protected function determinePostType($post)
    {
        // Check for ImagePost category type first
        if ($post->category && $post->category->type && str_starts_with($post->category->type, 'App\\Models\\ImagePost')) {
            return 'image';
        }

        if ($post->category && $post->category->id) {
            // Map category IDs to post types - adjust based on your category structure
            $categoryMappings = [
                4 => 'news',      // News category
                5 => 'article',   // Article category
                6 => 'event',     // Event category
                7 => 'event',     // Meeting category
                8 => 'news',      // General category
            ];

            return $categoryMappings[$post->category->id] ?? 'news';
        }

        // Check if post has meeting/event data
        if ($post->meeting || (isset($post->from) && $post->from)) {
            return 'event';
        }

        return 'news'; // Default to news
    }

    /**
     * Prepare post data for email template
     */
    protected function preparePostData($post, $translation)
    {
        // Generate fully localized URL with translated route path for recipient's language
        $url = LaravelLocalization::getURLFromRouteNameTranslated(
            $this->recipientLocale,
            'routes.post.show_by_slug',
            ['slug' => $translation->slug]
        );

        $data = [
            'title' => $translation->title,
            'excerpt' => $translation->excerpt,
            'content' => $translation->content,
            'url' => $url,
            'date' => $post->updated_at->locale($this->recipientLocale)->translatedFormat('M j, Y'),
            'author' => $post->author ? $post->author->name : null,
        ];

        // Add category information
        if ($post->category) {
            $categoryTranslation = $post->category->translations()->where('locale', $this->recipientLocale)->first();
            $data['category'] = $categoryTranslation ? $categoryTranslation->name : $post->category->translations()->first()->name;
        }

        // Add location prefix for news (based on existing news-card-full logic)
        if ($post->category && $post->category->categoryable && $post->category->categoryable->translations) {
            $locationTranslation = $post->category->categoryable->translations->where('locale', $this->recipientLocale)->first();
            if ($locationTranslation && $locationTranslation->name) {
                $data['location_prefix'] = strtoupper($locationTranslation->name);
            }
        }

        // Add event-specific data
        if ($post->meeting) {
            $data['venue'] = $post->meeting->venue;
            $data['address'] = $post->meeting->address;
        }

        // Add event date/time if available
        if ($translation->from) {
            $eventDate = \Carbon\Carbon::parse($translation->from);
            $data['event_date'] = $eventDate->locale($this->recipientLocale)->translatedFormat('F j');
            $data['event_time'] = $eventDate->locale($this->recipientLocale)->translatedFormat('H:i');
        }

        // Add image if available - use email conversion (resized without cropping)
        if ($post->getFirstMediaUrl('posts')) {
            $data['image'] = $post->getFirstMediaUrl('posts', 'email');

            // Add media caption and owner for image posts
            $media = $post->getFirstMedia('posts');
            if ($media) {
                $captionKey = 'caption-' . $this->recipientLocale;
                $data['media_caption'] = $media->getCustomProperty($captionKey, '');
                $data['media_owner'] = $media->getCustomProperty('owner', '');
            }
        }

        return $data;
    }

    /**
     * Generate unsubscribe URL for the recipient
     */
    protected function generateUnsubscribeUrl()
    {
        // For test mails, return a placeholder URL
        if ($this->isTestMail || !$this->recipient) {
            return '#test-unsubscribe-link';
        }

        // Create signed URL for unsubscribing from this mailing type
        return route('newsletter.unsubscribe', [
            'email' => $this->recipient->email,
            'type' => $this->mailing->type,
            'signature' => hash_hmac('sha256', $this->recipient->email . $this->mailing->type, config('app.key'))
        ]);
    }
}