<?php

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

/**
 * Los permisos del catálogo de usos del entorno.
 *
 * **Vienen con su pantalla en el mismo cambio**, que es la regla que se estableció al
 * limpiar los 27 permisos huérfanos (MGR-101):
 *
 * > Un permiso nuevo o tiene su pantalla en el mismo cambio, o se declara en
 * > `PERMISOS_DE_ROADMAP` con el motivo. No hay tercera opción.
 *
 * ## Por qué no reutilizan los de los tipos de entorno
 *
 * Se ven en la misma hoja —Configuración › Catálogos— y era tentador colgarlos de
 * `admin.configurations.environments-types.*`. Son dos catálogos distintos, y este es el
 * más delicado de los dos:
 *
 * - De él depende **la validación de la API pública**: `MoodleApiRequest` acepta el `env`
 *   que manda cada Moodle contra esta tabla, así que borrar una fila hace que ese Moodle
 *   empiece a recibir un 422.
 * - Y decide **qué se ve al abrir el listado de entornos**, que es la pantalla que más se
 *   usa del panel.
 *
 * Quién puede tocar eso se decide aparte de quién puede añadir una plataforma al catálogo.
 *
 * ## El reparto
 *
 * `index` no existe como permiso propio: el listado vive dentro de la hoja de Catálogos,
 * que ya está gateada por `admin.configurations.environments-types.index`. Un permiso más
 * para ver una tabla que se pinta en una pantalla que ya se está viendo sería justo el
 * patrón que se limpió en MGR-101 — un permiso que no gatea nada.
 *
 * `create` y `edit` para Admin y System —System monta el Manager—, y `destroy` **solo
 * Admin**: igual que en el resto de catálogos, retirar una fila es una decisión de
 * catálogo y no de gestión diaria.
 */
return new class extends Migration
{
    /** @var array<string, string> */
    private const PERMISOS = [
        'admin.configurations.envs.create' => 'Configuraciones: Crear uso de entorno',
        'admin.configurations.envs.edit' => 'Configuraciones: Editar uso de entorno',
        'admin.configurations.envs.destroy' => 'Configuraciones: Borrar uso de entorno',
    ];

    private const SOLO_ADMIN = ['admin.configurations.envs.destroy'];

    public function up(): void
    {
        $admin = Role::where('name', 'Admin')->first();
        $system = Role::where('name', 'System')->first();

        foreach (self::PERMISOS as $nombre => $descripcion) {
            $permiso = Permission::firstOrCreate(
                ['name' => $nombre, 'guard_name' => 'web'],
                ['model' => 'configurations', 'description' => $descripcion]
            );

            $roles = in_array($nombre, self::SOLO_ADMIN, true)
                ? [$admin]
                : [$admin, $system];

            foreach (array_filter($roles) as $rol) {
                if (! $rol->hasPermissionTo($permiso)) {
                    $rol->givePermissionTo($permiso);
                }
            }
        }

        app(PermissionRegistrar::class)->forgetCachedPermissions();
    }

    public function down(): void
    {
        Permission::whereIn('name', array_keys(self::PERMISOS))->delete();

        app(PermissionRegistrar::class)->forgetCachedPermissions();
    }
};
