<?php

namespace App\Jobs;

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\Mail;
use Illuminate\Support\Facades\Log;
use App\Models\Campaign;
use App\Models\Message;
use App\Models\Sender;
use App\Models\DataExcel;
use App\Models\EmailLog;
use App\Mail\SendMultiMails;

class SendSingleEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $campaignId;
    public $messageId;
    public $senderId;
    public $receiverId;

    public function __construct(int $campaignId, ?int $messageId, int $senderId, int $receiverId)
    {
        $this->campaignId = $campaignId;
        $this->messageId = $messageId;
        $this->senderId = $senderId;
        $this->receiverId = $receiverId;
    }

    public function handle()
    {
        $campaign = Campaign::find($this->campaignId);
        $message = Message::find($this->messageId);
        $sender = Sender::find($this->senderId);
        $receiver = DataExcel::find($this->receiverId);

        if (!$campaign || !$message || !$sender || !$receiver) {
            Log::error("SendSingleEmailJob: missing model for campaign={$this->campaignId}, message={$this->messageId}");
            return;
        }

        // create pending log
        $log = EmailLog::create([
            'campaign_id' => $this->campaignId,
            'message_id' => $this->messageId,
            'sender_id' => $this->senderId,
            'receiver_id' => $this->receiverId,
            'receiver_email' => $receiver->email ?? null,
            'subject' => $message->subject ?? null,
            'content' => $message->content ?? null,
            'status' => 'pending'
        ]);

        // If campaign is cancelled -> abort
        if ($campaign->status === 'cancelled') {
            $log->update(['status' => 'failed', 'error_message' => 'Campaign cancelled']);
            Log::info("SendSingleEmailJob: campaign cancelled, skip job campaign={$this->campaignId}");
            return;
        }

        // If campaign paused -> re-dispatch job after a short delay (30s)
        if ($campaign->status === 'paused') {
            Log::info("SendSingleEmailJob: campaign paused, rescheduling job campaign={$this->campaignId}");
            // re-dispatch same job with short delay
            self::dispatch($this->campaignId, $this->messageId, $this->senderId, $this->receiverId)
                ->delay(now()->addSeconds(30))
                ->onQueue($campaign->queue_name ?? ('emails_' . preg_replace('/\s+/', '_', strtolower($campaign->country ?? 'default'))));
            return;
        }

        $receiverEmail = $receiver->email ?? null;
        $subject = $message->subject ?? null;
        $content = $message->content ?? null;

        if (!filter_var($sender->email ?? '', FILTER_VALIDATE_EMAIL)) {
            $log->update(['status' => 'failed', 'error_message' => 'Invalid sender email']);
            Log::error("SendSingleEmailJob: invalid sender email for sender_id={$this->senderId}");
            if ($message) $message->update(['status' => 'failed']);
            return;
        }

        if (!filter_var($receiverEmail ?? '', FILTER_VALIDATE_EMAIL)) {
            $log->update(['status' => 'failed', 'error_message' => 'Invalid receiver email: ' . ($receiverEmail ?? '')]);
            Log::error("SendSingleEmailJob: invalid receiver email for receiver_id={$this->receiverId}");
            if ($message) $message->update(['status' => 'failed']);
            return;
        }

        try {
            Mail::to($receiverEmail)
                ->send(new SendMultiMails( $sender->name ?? '', $sender->email ?? '', $receiverEmail, $content, $subject, $message->file ?? null ));

            $log->update(['status' => 'sent', 'sent_at' => now()]);
            if ($message) $message->update(['send_at' => now(), 'status' => 'sent']);
        } catch (\Exception $e) {
            $log->update(['status' => 'failed', 'error_message' => $e->getMessage()]);
            if ($message) $message->update(['status' => 'failed']);
            Log::error("SendSingleEmailJob failed: {$e->getMessage()} for receiver {$receiverEmail}");
        }
    }
}
