<?php

namespace App\Jobs;

use App\Models\CampaignLog;
use App\Models\Campaign;
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\Storage;
use Illuminate\Support\Facades\Log;

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

    public $tries = 3;
    public $timeout = 60;

    protected $logId;

    public function __construct(CampaignLog $log)
    {
        $this->logId = $log->id;
    }

    public function handle(): void
    {
        $log = CampaignLog::find($this->logId);
        if (!$log) return;

        $contact = $log->contact;
        $campaign = $log->campaign;
        
        if (!$contact || !$campaign) {
            $log->update(['status' => 'failed']);
            return;
        }

        $voiceRecord = $campaign->voiceRecord;
        if (!$voiceRecord) {
            $log->update(['status' => 'failed']);
            return;
        }

        // All config from .env
        $host = env('FREESWITCH_ESL_HOST', '127.0.0.1');
        $port = (int) env('FREESWITCH_ESL_PORT', 8021);
        $password = env('FREESWITCH_ESL_PASSWORD', 'ClueCon');
        $gateway = env('FREESWITCH_GATEWAY', 'default');
        $callerId = env('FREESWITCH_CALLER_ID', '09600000000');
        $domain = env('FREESWITCH_DOMAIN');

        $phone = $contact->phone;
        
        // Audio URL using mod_shout (HTTP playback)
        $audioUrl = url(Storage::url($voiceRecord->file_path));

        Log::info("ProcessCall: Attempting call to {$phone} via gateway {$gateway}" . ($domain ? " for domain {$domain}" : ""));

        // Connect to FreeSWITCH ESL
        $fp = @fsockopen($host, $port, $errno, $errstr, 10);
        if (!$fp) {
            Log::error("ESL Connection failed to {$host}:{$port} - {$errstr} ({$errno})");
            $log->update(['status' => 'failed']);
            return;
        }

        // Read initial auth request
        stream_set_blocking($fp, true);
        stream_set_timeout($fp, 10);
        $response = fread($fp, 1024);

        // Authenticate
        fwrite($fp, "auth {$password}\n\n");
        $response = fread($fp, 1024);

        if (strpos($response, '+OK accepted') !== false) {
            // Originate the call with optional multi-domain support
            $vars = "origination_caller_id_number={$callerId},ignore_early_media=true,hangup_after_bridge=true";
            if ($domain) {
                $vars .= ",accountcode={$domain},domain_name={$domain}";
            }
            
            $cmd = "bgapi originate {{$vars}}sofia/gateway/{$gateway}/{$phone} &playback({$audioUrl})\n\n";
            fwrite($fp, $cmd);
            $response = fread($fp, 1024);
            
            Log::info("Call originated to {$phone}. Response: " . trim($response));
            $log->update(['status' => 'initiated']);
        } else {
            Log::error("ESL Auth failed. Response: " . trim($response));
            $log->update(['status' => 'failed']);
        }

        fclose($fp);

        // Check if all logs for this campaign are done
        $this->checkCampaignCompletion($campaign);
    }

    protected function checkCampaignCompletion(Campaign $campaign)
    {
        $pendingCount = CampaignLog::where('campaign_id', $campaign->id)
            ->whereIn('status', ['pending'])
            ->count();
        
        if ($pendingCount === 0) {
            $campaign->update(['status' => 'completed']);
        }
    }

    public function failed(\Throwable $exception): void
    {
        Log::error("ProcessCall job failed: " . $exception->getMessage());
        
        $log = CampaignLog::find($this->logId);
        if ($log) {
            $log->update(['status' => 'failed']);
        }
    }
}
