<?php

namespace App\Console\Commands;

use App\Models\Dialler\AgentStatus;
use App\Services\Dialler\AgentStatusService;
use Illuminate\Console\Command;

/**
 * Closes agent presence sessions abandoned without an explicit logout (e.g. the
 * browser tab was closed). Without this, an agent who vanishes mid-shift would
 * stay "available"/"busy" forever and their final interval would never close.
 *
 * The close is backdated to last_seen_at so the idle gap after they disappeared
 * is not counted as working time.
 */
class ReapStaleAgentStatuses extends Command
{
    protected $signature = 'dialler:reap-stale-agents {--minutes=10 : Idle threshold (minutes) before an open session is closed}';

    protected $description = 'Close agent presence sessions abandoned without logout, backdated to last_seen_at.';

    public function handle(AgentStatusService $service): int
    {
        $minutes   = max(1, (int) $this->option('minutes'));
        $threshold = now()->subMinutes($minutes);

        // Runs in console: the BelongsToSolicitor global scope is inactive and the
        // service takes solicitor_id explicitly, so this is correct across every
        // tenant without rebinding Solicitor. AgentStatus has no global scope.
        $stale = AgentStatus::query()
            ->where('status', '!=', 'offline')
            ->where(function ($q) use ($threshold) {
                $q->where('last_seen_at', '<', $threshold)
                    ->orWhere(function ($q2) use ($threshold) {
                        $q2->whereNull('last_seen_at')
                            ->where('status_changed_at', '<', $threshold);
                    });
            })
            ->get();

        foreach ($stale as $snapshot) {
            $seenAt = $snapshot->last_seen_at ?? $snapshot->status_changed_at ?? $threshold;

            $service->transitionTo(
                $snapshot->solicitor_id,
                $snapshot->agent_id,
                'offline',
                ['source' => 'reaper_stale'],
                $seenAt,
            );
        }

        $this->info("Reaped {$stale->count()} stale agent session(s).");

        return self::SUCCESS;
    }
}
