<?php

namespace App\Livewire\Monitoring;

use App\Models\Monitoring\Notice;
use App\Models\Products\LicenseToken;
use Livewire\Component;
use Livewire\WithPagination;

/**
 * Qué avisos automáticos se han enviado, a quién y cuándo.
 *
 * Responde a la pregunta que siempre aparece cuando algo se ha escapado: **"¿se avisó
 * de esto?"**. Sin esta pantalla, la única forma de saberlo era buscar en el buzón del
 * destinatario —si es que sigue trabajando aquí—.
 *
 * Y responde también a la contraria, que es la que salva: **un aviso que falló al
 * enviarse** aparece con su error y sin fecha de envío, así que se ve que no llegó en
 * vez de suponer que sí.
 */
class Notices extends Component
{
    use WithPagination;

    /** all | sent | failed */
    public string $estado = 'all';

    public string $tipo = 'all';

    public function updatedEstado(): void
    {
        $this->resetPage();
    }

    public function updatedTipo(): void
    {
        $this->resetPage();
    }

    /**
     * Abre la limpieza del histórico.
     *
     * **Y aquí borrar tiene efecto, no solo pérdida**: la tabla existe para no repetir
     * avisos, así que quitar una fila rearma el aviso. La modal lo cuenta aparte.
     */
    public function abrirLimpieza(): void
    {
        // La pantalla la ve quien tiene lectura de monitorización; vaciarla, solo Admin.
        $this->authorize('admin.configs.edit');

        $this->dispatch('openModal', component: LimpiezaDeAvisosModal::class);
    }

    #[\Livewire\Attributes\On('avisosLimpiados')]
    public function refrescar(): void
    {
        $this->resetPage();
    }

    public function render()
    {
        $avisos = Notice::query()
            ->when($this->estado === 'sent', fn ($q) => $q->whereNotNull('sent_at'))
            ->when($this->estado === 'failed', fn ($q) => $q->whereNull('sent_at'))
            ->when($this->tipo !== 'all', fn ($q) => $q->where('kind', $this->tipo))
            ->orderByDesc('updated_at')
            ->paginate(25);

        // El sujeto se resuelve aquí y no con una relación polimórfica: la tabla guarda
        // `subject_type` como cadena a propósito, para que la fila sobreviva al borrado
        // del sujeto. Así un aviso de una licencia ya eliminada sigue en el histórico,
        // aunque se quede sin nombre.
        $licencias = LicenseToken::with('client')
            ->whereIn('id', $avisos->where('subject_type', Notice::SUBJECT_LICENSE_TOKEN)->pluck('subject_id'))
            ->get()
            ->keyBy('id');

        return view('livewire.monitoring.notices', [
            'avisos' => $avisos,
            'licencias' => $licencias,
            // La lista sale del modelo: ver {@see Notice::NOMBRES}. Aquí vivía una copia, y
            // se había quedado sin el aviso de soporte.
            'tipos' => ['all' => 'Todos los tipos'] + Notice::NOMBRES,
            'resumen' => [
                'enviados' => Notice::whereNotNull('sent_at')->count(),
                'fallidos' => Notice::whereNull('sent_at')->count(),
                'ultimos7' => Notice::where('sent_at', '>=', now()->subWeek())->count(),
            ],
        ])->layout('layouts.app');
    }
}
