<?php

namespace App\Jobs;

use App\Mail\NewMessageMail;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Namu\WireChat\Events\MessageCreated;

class SendDelayedEmail implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    public $event;
    public $sender;
    public $recipient;
    public $participant;

    /**
     * Create a new job instance.
     *
     * @param  MessageCreated  $event
     * @param  mixed  $sender
     * @param  mixed  $recipient
     * @param  mixed  $participant
     * @return void
     */
    public function __construct(MessageCreated $event, $sender, $recipient, $participant)
    {
        $this->event = $event;
        $this->sender = $sender;
        $this->recipient = $recipient;
        $this->participant = $participant;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            Log::info('SendDelayedEmail job starting (v2)', [
                'recipient_id' => $this->recipient->id,
                'recipient_type' => get_class($this->recipient),
                'participant_id' => $this->participant->id ?? 'null',
                'message_id' => $this->event->message->id ?? 'null',
            ]);

            // Refresh the participant to get the latest data
            $this->participant->refresh();

            // Check if the message has been read
            // WireChat uses 'conversation_read_at' on the participant model
            $lastRead = $this->participant->conversation_read_at ? Carbon::parse($this->participant->conversation_read_at) : null;
            $messageCreatedAt = Carbon::parse($this->event->message->created_at);

            Log::info('Read status check', [
                'conversation_read_at' => $lastRead ? $lastRead->toDateTimeString() : 'null',
                'message_created' => $messageCreatedAt->toDateTimeString(),
            ]);

            if ($lastRead && $lastRead->greaterThanOrEqualTo($messageCreatedAt)) {
                // The recipient has already read the message; do not send the email
                Log::info('Recipient has already read the message', [
                    'recipient_id' => $this->recipient->id,
                    'recipient_type' => get_class($this->recipient),
                    'message_id' => $this->event->message->id,
                ]);
                return;
            }

            // Get the recipient's language preference
            $language = $this->recipient->lang_preference ?? config('app.locale', 'en');

            Log::info('Language detection', [
                'recipient_lang_preference' => $this->recipient->lang_preference ?? 'null',
                'fallback_locale' => config('app.locale', 'en'),
                'selected_language' => $language,
            ]);

            // Send the email with the appropriate language
            Mail::to($this->recipient->email)
                ->locale($language)
                ->send(new NewMessageMail(
                    $this->event,
                    $this->sender,
                    $this->recipient,
                    $language
                ));

            Log::info('Email sent to recipient', [
                'recipient_id' => $this->recipient->id,
                'recipient_type' => get_class($this->recipient),
                'email' => $this->recipient->email,
                'language' => $language,
                'message_id' => $this->event->message->id,
            ]);
        } catch (\Exception $e) {
            Log::error('Error sending SendDelayedEmail', [
                'recipient_id' => $this->recipient->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            // Re-throw the exception so the job can be retried
            throw $e;
        }
    }

    /**
     * The job failed to process.
     *
     * @param  \Throwable  $exception
     * @return void
     */
    public function failed(\Throwable $exception)
    {
        Log::error('SendDelayedEmail job failed', [
            'recipient_id' => $this->recipient->id,
            'recipient_type' => get_class($this->recipient),
            'message_id' => $this->event->message->id,
            'error' => $exception->getMessage(),
        ]);
    }
}
