<?php

namespace App\Livewire\Environments;

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

/**
 * Apagar o encender un entorno, diciendo antes qué va a pasar.
 *
 * **Lo que había.** Una casilla «Activo» dentro del formulario de edición, entre el
 * nombre y el dominio. Dos problemas, y el segundo peor que el primero:
 *
 * 1. Estaba validada con `sometimes|accepted`, y `accepted` exige que el valor sea
 *    verdadero. Desmarcarla y guardar daba «The active field must be accepted» y el
 *    entorno se quedaba encendido: **no se podía apagar ningún entorno desde el panel**.
 * 2. Aun funcionando, apagar un entorno hace que `ProductToken` responda
 *    `403 Entorno inactivo` a **todas** las acciones de ese sitio en la siguiente
 *    petición. Eso pasaba sin confirmación, sin decir a qué afecta y sin dejar rastro
 *    de quién lo hizo.
 *
 * Es la misma decisión que ya se tomó con la baja de un cliente y con el corte de los
 * límites de la API: **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?».
 *
 * El aviso cuenta lo que este sitio está recibiendo hoy —productos, licencia—, si tiene
 * soporte en vigor —apagar un entorno que se está cobrando es casi siempre un error— y
 * cuánto lleva sin dar señal, porque un sitio que no llama desde febrero se apaga con
 * mucha menos ceremonia que uno que llamó hace diez minutos.
 */
class EnvironmentStatusModal extends ModalComponent
{
    public Environment $environment;

    /** Motivo del apagado. Obligatorio: es lo que responde «¿por qué no recibimos nada?». */
    public string $motivo = '';

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

        // Por id y con `findOrFail`: el id llega en el snapshot de Livewire, así que la
        // consulta es el único sitio donde se puede acotar. Ver MGR-006.
        $this->environment = Environment::with(['client', 'licenseToken', 'soporteVigente'])
            ->findOrFail($environmentId);
    }

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

    public function apagar(): void
    {
        $this->authorize('admin.environments.edit');

        $datos = $this->validate([
            // Obligatorio y con un mínimo: un «pruebas» de siete letras no le sirve a
            // nadie en seis meses, que es cuando se lee.
            'motivo' => ['required', 'string', 'min:5', 'max:500'],
        ], [
            'motivo.required' => 'Escribe el motivo: es lo que se leerá cuando alguien pregunte por qué este sitio no recibe nada.',
            'motivo.min' => 'Un motivo de menos de 5 caracteres no explica nada.',
        ], ['motivo' => 'motivo']);

        $impacto = $this->environment->impactoDeApagarlo();

        $this->environment->apagar($datos['motivo'], Auth::id());

        MonitoringLog::db(
            'warning',
            '16031',
            'Entorno APAGADO: ' . $this->environment->name
            . ' (' . $this->environment->domain . ')'
            . ' — su Moodle recibe «Entorno inactivo» y deja de recibir '
            . $impacto['productos'] . ' producto(s).'
            . ($impacto['soporteVigente'] ? ' TENÍA SOPORTE EN VIGOR.' : '')
            . ' Motivo: ' . $datos['motivo']
            . ' (por ' . (Auth::user()?->name ?? 'desconocido') . ')',
            'Environment',
            (string) $this->environment->id
        );

        session()->flash('warning', $this->environment->name . ' está apagado: su Moodle '
            . 'ya recibe «Entorno inactivo» y deja de recibir licencias y contenido'
            . ($impacto['productos'] > 0 ? ' (' . $impacto['productos'] . ' producto(s))' : '')
            . '.');

        // 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(['environmentStatusChanged']);
    }

    public function encender(): void
    {
        $this->authorize('admin.environments.edit');

        $this->environment->encender(Auth::id());

        MonitoringLog::db(
            'info',
            '16031',
            'Entorno encendido: ' . $this->environment->name
            . ' (' . $this->environment->domain . ')'
            . ' — vuelve a recibir licencias y contenido'
            . ' (por ' . (Auth::user()?->name ?? 'desconocido') . ')',
            'Environment',
            (string) $this->environment->id
        );

        session()->flash('success', $this->environment->name . ' vuelve a estar activo: '
            . 'su Moodle recibirá licencias y contenido en la siguiente petición.');

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

    public function render()
    {
        return view('livewire.environments.environment-status-modal', [
            'impacto' => $this->environment->impactoDeApagarlo(),
        ]);
    }
}
