<?php

namespace App\Console\Commands;

use App\Jobs\SendVoiceJob;
use App\Models\Client;
use App\Models\VoiceBroadcast;
use App\Models\VoiceGateway;
use Carbon\Carbon;
use Illuminate\Console\Command;

class SendReminderVoiceCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'voice:send-reminder
                            {--voice= : ID of the saved voice to use}
                            {--days-before=3 : Days before expiry to target customers}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send due reminder voice calls using an enabled saved voice asset.';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $daysBefore = (int) $this->option('days-before');
        if ($daysBefore < 1 || $daysBefore > 60) {
            $this->error('The --days-before option must be between 1 and 60.');

            return Command::FAILURE;
        }

        $gateway = VoiceGateway::where('status', 'enable')->first();
        if (!$gateway) {
            $this->error('No active voice gateway is configured.');

            return Command::FAILURE;
        }

        $voice = $this->resolveVoice();
        if (!$voice) {
            return Command::FAILURE;
        }

        $absolutePath = $voice->absolutePath();
        if (!file_exists($absolutePath)) {
            $this->error("Voice file for asset #{$voice->id} is missing from storage.");

            return Command::FAILURE;
        }

        $targetDate = Carbon::today()->addDays($daysBefore);

        $this->info("Queuing reminder voices for customers expiring on {$targetDate->toDateString()} using voice #{$voice->id}.");

        $totalQueued = 0;

        Client::with(['clientsinfo', 'customerAccount'])
            ->whereDate('expire_date', $targetDate)
            ->whereHas('customerAccount', function ($query) {
                $query->where('dueAmount', '>', 0);
            })
            ->orderBy('id')
            ->chunkById(200, function ($clients) use (&$totalQueued, $absolutePath, $voice, $gateway) {
                foreach ($clients as $client) {
                    $contact = optional($client->clientsinfo)->contact_no;

                    if (!$contact) {
                        continue;
                    }

                    SendVoiceJob::dispatch([
                        'contact' => $contact,
                        'voice_file_path' => $absolutePath,
                        'voice_file' => $voice->file_path,
                        'caller_id' => $gateway->caller_id,
                        'retry_count' => $gateway->retry_count,
                        'type' => 'due_reminder_voice_send',
                    ]);

                    $totalQueued++;
                }
            });

        if ($totalQueued === 0) {
            $this->warn('No due customers matched the criteria.');
        } else {
            $this->info("Queued {$totalQueued} reminder voice call(s).");
        }

        return Command::SUCCESS;
    }

    /**
     * Resolve the voice asset that should be used for reminders.
     */
    protected function resolveVoice(): ?VoiceBroadcast
    {
        $voiceId = $this->option('voice');

        $query = VoiceBroadcast::enabled();
        if ($voiceId) {
            $query->where('id', $voiceId);
        }

        $voice = $query->latest()->first();

        if (!$voice) {
            $message = $voiceId
                ? "No enabled voice found with ID {$voiceId}."
                : 'No enabled voice assets are available. Enable one from the voice library first.';

            $this->error($message);
        }

        return $voice;
    }
}

