<?php

namespace App\Console\Commands;

use App\Mail\ApiBlocksDigest;
use App\Models\Monitoring\ApiBlock;
use App\Models\Monitoring\Log as MonitoringLog;
use App\Services\System\Settings;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;

/**
 * Resumen diario de los bloqueos de la API.
 *
 * Complementa al aviso inmediato, que solo salta en la **transición** a bloqueado. Sin
 * esto, un bloqueo que lleva tres días abierto no vuelve a decir nada: se avisó una vez
 * y si ese correo se perdió entre otros, el problema sigue ahí y nadie lo sabe.
 *
 * Se ejecuta cada hora desde el planificador y **decide dentro** si le toca, comparando
 * con la hora configurada en la pantalla de ajustes. Es a propósito: si la hora fuera
 * parte de la programación, cambiarla en el panel no tendría efecto hasta redesplegar,
 * y el sentido de tenerla en el panel es justamente no depender de eso.
 */
class SendBlocksDigest extends Command
{
    protected $signature = 'api-blocks:digest
                            {--force : Envía ahora, sin comprobar la hora configurada}';

    protected $description = 'Envía el resumen diario de bloqueos de la API a la hora configurada';

    public function handle(Settings $ajustes): int
    {
        if (!$ajustes->mandaResumenDiario() && !$this->option('force')) {
            $this->line('El resumen diario está desactivado en la configuración.');

            return self::SUCCESS;
        }

        if (!$this->option('force') && (int) now()->hour !== $ajustes->horaDelResumen()) {
            // Silencioso: esto corre cada hora y 23 de 24 veces no le toca.
            return self::SUCCESS;
        }

        $destinatarios = $ajustes->destinatariosDeAvisos();

        if ($destinatarios === []) {
            $this->warn('No hay destinatarios configurados: no se envía el resumen.');

            return self::SUCCESS;
        }

        $activos = ApiBlock::blocked()
            ->with(['environment.client', 'licenseToken'])
            ->orderByDesc('last_blocked_at')
            ->get();

        $nuevos = ApiBlock::where('first_blocked_at', '>=', now()->subDay())
            ->with(['environment.client', 'licenseToken'])
            ->orderByDesc('first_blocked_at')
            ->get();

        $revisados = ApiBlock::where('cleared_at', '>=', now()->subDay())
            ->with('clearedBy')
            ->count();

        // Se envía **aunque no haya nada**, y es deliberado: un resumen que solo llega
        // cuando hay problemas no permite distinguir "todo bien" de "el resumen se ha
        // roto". Un correo diario que dice "sin bloqueos" es la prueba de que el
        // mecanismo sigue vivo.
        Mail::to($destinatarios)->send(new ApiBlocksDigest($activos, $nuevos, $revisados));

        MonitoringLog::db(
            'info',
            '16009',
            'Resumen diario de bloqueos enviado a ' . implode(', ', $destinatarios)
            . ' (' . $activos->count() . ' activo(s), ' . $nuevos->count() . ' nuevo(s) en 24 h)'
        );

        $this->info('Resumen enviado a ' . implode(', ', $destinatarios) . '.');
        $this->line('  Activos: ' . $activos->count() . ' · Nuevos en 24 h: ' . $nuevos->count()
            . ' · Revisados en 24 h: ' . $revisados);

        return self::SUCCESS;
    }
}
