<?php

use Illuminate\Database\Migrations\Migration;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

/**
 * El rol Support, que no podía abrir ni una pantalla.
 *
 * **El problema.** `Support` tenía **cero de los 126 permisos**: entraba al panel y no
 * veía nada. Y revisar incidencias es precisamente el trabajo de Soporte —los briefs de
 * Entornos, Clientes, Licencias y Monitorización dicen «esto lo mira Soporte» en cinco
 * pantallas distintas, todas construidas para un rol que no podía abrirlas—.
 *
 * **Por qué en una migración y no solo en el seeder.** El seeder ya le daba un permiso
 * (`admin.api-logs.index`) y la base no lo tenía: el seeder completo no se vuelve a pasar
 * en un entorno con datos. Esto se despliega con `migrate`, que es lo que sí se ejecuta.
 * El seeder se actualiza también, para que una instalación nueva salga igual.
 *
 * **El criterio: Soporte lee todo y toca lo que no rompe nada.**
 *
 * Lo que puede hacer es responder «este cliente dice que no le llega el contenido»:
 * encontrar el sitio, ver si su licencia está viva, ver qué versión hay publicada, ver el
 * inventario de plugins, mirar el log de peticiones y comprobar si se avisó. Y
 * **sincronizar**, que es la acción de diagnóstico principal —no cambia datos
 * comerciales: le pide los suyos al Moodle del cliente—.
 *
 * **Lo que deliberadamente NO tiene:**
 *
 * - **Nada de crear, editar ni borrar** clientes, entornos, licencias, productos ni
 *   contenido. Soporte diagnostica; corregir un dato comercial es de otro.
 * - **`admin.configs.edit`**, que es bloquear IPs y liberar bloqueos. Ya se decidió al
 *   diseñar Monitorización: no es lo mismo mirar que tocar.
 * - **`admin.tokens.index`**, que es ver el token de servicios web del Moodle del
 *   cliente. Es **una credencial de un tercero**, cifrada en reposo a propósito
 *   (MGR-038): no se reparte por comodidad.
 * - **`admin.api-logs.destroy`**: borrar el log de peticiones es irreversible.
 * - **Usuarios, roles y permisos.**
 */
return new class extends Migration
{
    /**
     * La lista vive en el seeder, que es donde se define el rol.
     *
     * **A propósito, y no es la costumbre**: normalmente una migración no depende de
     * código de la aplicación, porque es un registro histórico. Aquí sí, porque esto
     * no es un cambio de datos puntual: es **la definición vigente de un rol**, y si
     * mañana se ajusta la lista, esta migración tiene que aplicar la nueva —no la de
     * hoy—. Con la lista duplicada, las dos se desincronizan y nadie se enteraría.
     *
     * @return array<int, string>
     */
    private function permisosDeSoporte(): array
    {
        return \Database\Seeders\RoleSeeder::PERMISOS_DE_SOPORTE;
    }

    public function up(): void
    {
        $support = Role::where('name', 'Support')->first();

        if ($support === null) {
            // Sin el rol no hay nada que hacer: lo crea el seeder en una instalación
            // nueva, y ahí ya sale con estos permisos.
            return;
        }

        // Solo los que existen de verdad. Un permiso que no está en la base es un
        // nombre mal escrito aquí, y `givePermissionTo` con un nombre inexistente lanza
        // excepción y dejaría la migración a medias.
        $existentes = Permission::whereIn('name', $this->permisosDeSoporte())
            ->pluck('name')
            ->all();

        $faltan = array_diff($this->permisosDeSoporte(), $existentes);

        if ($faltan !== []) {
            // Se avisa pero no se aborta: puede pasar en una base antigua a la que le
            // falte un módulo, y es mejor darle los 30 que tenemos que ninguno.
            logger()->warning('Permisos de Support que no existen en la base', $faltan);
        }

        // `syncPermissions` y no `givePermissionTo`: la lista de arriba es **la
        // definición** del rol, no un añadido. Si mañana se quita uno de aquí, se quita
        // del rol.
        $support->syncPermissions($existentes);
    }

    public function down(): void
    {
        Role::where('name', 'Support')->first()?->syncPermissions([]);
    }
};
