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

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

    public $campaignId;
    public $senderIds;
    public $receiverIds; // array of receiver ids

    public function __construct(int $campaignId, array $senderIds, array $receiverIds)
    {
        $this->campaignId = $campaignId;
        $this->senderIds = $senderIds;
        $this->receiverIds = $receiverIds;
    }

    public function handle()
    {
        $campaign = Campaign::find($this->campaignId);
        if (!$campaign) {
            Log::error("CampaignJob: campaign not found id={$this->campaignId}");
            return;
        }

        // set running (unless already paused/cancelled)
        if ($campaign->status !== 'paused' && $campaign->status !== 'cancelled') {
            $campaign->update(['status' => 'running', 'started_at' => now()]);
        }

        $senders = Sender::whereIn('id', $this->senderIds)->get();
        if ($senders->isEmpty()) {
            $campaign->update(['status' => 'failed']);
            Log::error("CampaignJob: no senders for campaign {$this->campaignId}");
            return;
        }

        $receivers = DataExcel::whereIn('id', $this->receiverIds)
            ->whereNotNull('email')->where('email', '<>', '')->get();

        $total = $receivers->count();
        if ($total === 0) {
            $campaign->update(['status' => 'completed', 'completed_at' => now()]);
            return;
        }

        $interval = max(0, (int) floor($campaign->duration_seconds / $total)); // seconds between dispatches

        foreach ($receivers as $index => $receiver) {
            $sender = $senders[$index % $senders->count()];
            $delaySeconds = $index * $interval;

            // dispatch single email job into the campaign queue
            \App\Jobs\SendSingleEmailJob::dispatch(
                $campaign->id, $campaign->message_id, $sender->id, $receiver->id
            )->delay(now()->addSeconds($delaySeconds))
              ->onQueue($campaign->queue_name ?? ('emails_' . preg_replace('/\s+/', '_', strtolower($campaign->country ?? 'default'))));
        }

        $campaign->update(['status' => 'dispatched']);
        // actual completion (sent/failed per email) handled in SendSingleEmailJob
    }
}
