<?php

namespace App\Livewire\LicenseTokens;

use App\Models\Monitoring\Log as MonitoringLog;
use App\Models\Products\LicenseToken;
use Illuminate\Support\Facades\Auth;
use LivewireUI\Modal\ModalComponent;

/**
 * Apagar o volver a encender una licencia, diciendo antes qué va a pasar.
 *
 * **Lo que había** era un botón que llamaba a `toggleActive()`: invertía `active`, lo
 * guardaba y ya. Un clic y todos los entornos de esa licencia empiezan a recibir
 * «Licencia desactivada» en la siguiente sincronización, sin confirmación, sin decir a
 * cuántos afecta y sin dejar rastro de quién lo hizo ni por qué.
 *
 * Es el mismo problema que tenían las bajas de cliente (MGR-046) un nivel más abajo, y
 * se resuelve igual: **el impacto en números y el motivo obligatorio**. Lo que hace que
 * alguien lea un aviso es que le diga qué va a pasar y a cuántos, no un «¿estás seguro?».
 *
 * **Lo que NO hace**: tocar los productos ni sus fechas. Una licencia apagada y vuelta a
 * encender queda exactamente como estaba —esa es la diferencia con caducar, que sí
 * necesita renovación— y la modal lo dice para que nadie evite el botón por miedo.
 */
class LicenseStatusModal extends ModalComponent
{
    public LicenseToken $licenseToken;

    /** Motivo del apagado. Obligatorio: es lo que se lee seis meses después. */
    public string $motivo = '';

    public function mount(int $licenseTokenId): void
    {
        // El permiso de la ruta no se reaplica en /livewire/update. Ver MGR-005.
        $this->authorize('admin.license-tokens.edit');

        $this->licenseToken = LicenseToken::withCount('environments')->findOrFail($licenseTokenId);
    }

    public static function modalMaxWidth(): string
    {
        return '2xl';
    }

    public function desactivar(): void
    {
        $this->authorize('admin.license-tokens.edit');

        $datos = $this->validate([
            'motivo' => ['required', 'string', 'min:5', 'max:500'],
        ], [
            'motivo.required' => 'Escribe el motivo: es lo que se leerá dentro de seis meses.',
            'motivo.min' => 'Un motivo de menos de 5 caracteres no explica nada.',
        ], ['motivo' => 'motivo']);

        $entornos = $this->licenseToken->environments()->count();

        // Por el modelo: las tres columnas del apagado no son asignables en masa a
        // propósito, así que un `update()` las habría ignorado **en silencio**.
        $this->licenseToken->apagar($datos['motivo'], Auth::id());

        MonitoringLog::db(
            'warning',
            '16022',
            'Licencia APAGADA: ' . $this->licenseToken->token
            . ' (' . ($this->licenseToken->name ?: 'sin nombre') . ')'
            . ' — ' . $entornos . ' entorno(s) dejan de recibir contenido.'
            . ' Motivo: ' . $datos['motivo']
            . ' (por ' . (Auth::user()?->name ?? 'desconocido') . ')',
            'LicenseToken',
            (string) $this->licenseToken->id
        );

        session()->flash('warning', 'Licencia apagada: ' . $entornos
            . ' entorno(s) recibirán «Licencia desactivada» en su siguiente sincronización.');

        // Clave numérica: el paquete hace `[$event, $params] = $event` cuando el valor es
        // un array, así que `['evento' => []]` revienta con "Undefined array key 0".
        $this->closeModalWithEvents(['licenseStatusChanged']);
    }

    public function reactivar(): void
    {
        $this->authorize('admin.license-tokens.edit');

        $entornos = $this->licenseToken->environments()->count();

        // `encender()` limpia el registro del apagado y devuelve si **sigue caducada**:
        // esa es la trampa del botón —el middleware mira las dos cosas—, y si no se
        // dice, alguien pulsa y se va pensando que ya está.
        $caducada = $this->licenseToken->encender();

        MonitoringLog::db(
            'info',
            '16022',
            'Licencia reactivada: ' . $this->licenseToken->token
            . ' (' . ($this->licenseToken->name ?: 'sin nombre') . ')'
            . ' — ' . $entornos . ' entorno(s) vuelven a recibir contenido'
            . ($caducada ? ', pero la licencia está CADUCADA y sigue sin servir' : '')
            . ' (por ' . (Auth::user()?->name ?? 'desconocido') . ')',
            'LicenseToken',
            (string) $this->licenseToken->id
        );

        if ($caducada) {
            session()->flash('warning', 'La licencia está encendida, pero SIGUE CADUCADA'
                . ' (' . $this->licenseToken->end_at->format('d/m/Y') . '), así que todavía no da servicio.'
                . ' Hay que renovarla.');
        } else {
            session()->flash('success', 'Licencia encendida: ' . $entornos
                . ' entorno(s) vuelven a recibir contenido. Los productos y sus fechas siguen como estaban.');
        }

        $this->closeModalWithEvents(['licenseStatusChanged']);
    }

    public function render()
    {
        return view('livewire.license-tokens.license-status-modal', [
            'entornos' => $this->licenseToken->environments_count,
        ]);
    }
}
