<?php

namespace App\Livewire\Traits;

use Spatie\Permission\Models\Role;

/**
 * Qué se puede tocar de los roles que crea `RoleSeeder`, y qué no.
 *
 * **Hasta el 2026-09-15 estaban bloqueados los seis**, y eso era pasarse. Un Admin no podía
 * cambiar los permisos de Soporte, que es exactamente la clase de decisión que un Admin
 * toma: el alcance de Soporte cambia con el equipo, no con un despliegue. Que eso exigiera
 * tocar el seeder y desplegar convertía una decisión de organización en una tarea de
 * desarrollo.
 *
 * ## Lo único que se protege ahora: los permisos de Admin
 *
 * Y por una razón muy concreta, no por precaución general: **es el único rol desde el que
 * uno puede cerrarse la puerta por dentro**. Quitarle `admin.roles.edit` a Admin deja el
 * panel sin ninguna forma de volver a editar roles — ni ese, ni ningún otro—, y la única
 * salida sería entrar a la base a mano. Ver MGR-018.
 *
 * `System` y `WebService` **sí** se pueden editar, y conviene saber por qué no da miedo: las
 * rutas de la API no llevan un solo middleware `permission:` —la autenticación es por token,
 * en `ProductToken`—, así que los permisos de esos dos roles no abren ni cierran nada del
 * contrato con los plugins. Lo que sí depende de ellos es su **nombre**.
 *
 * ## El nombre sí se queda fijo en los seis
 *
 * Es otra cosa y más pequeña: el seeder y las migraciones de permisos buscan los roles **por
 * nombre** (`Role::firstOrCreate(['name' => 'Manager'])`). Renombrar «Manager» no da ningún
 * error: la siguiente migración crea un Manager nuevo y vacío, los usuarios se quedan en el
 * renombrado con los permisos viejos, y nadie se entera hasta que alguien pregunta por qué
 * no ve una pantalla. Los permisos se cambian; la etiqueta visible es `fullname`.
 */
trait ProtectsSystemRoles
{
    /**
     * El único rol cuyos permisos no se tocan desde el panel.
     *
     * En minúscula: la comparación es case-insensitive a propósito, porque la comprobación
     * vieja era `$role->name === 'admin'` y el rol real se llama `Admin` — o sea que la
     * protección no se activaba nunca (MGR-018).
     */
    private const ROL_BLINDADO = 'admin';

    /** Los seis del seeder: su nombre es una clave, no una etiqueta. */
    private const NOMBRES_DEL_SEEDER = ['admin', 'manager', 'developer', 'support', 'system', 'webservice'];

    /** ¿Es el rol del que uno puede cerrarse la puerta por dentro? */
    protected function isSystemRole(Role $role): bool
    {
        return strtolower($role->name) === self::ROL_BLINDADO;
    }

    /**
     * ¿Tiene el nombre fijo porque el seeder y las migraciones lo buscan por él?
     *
     * Sus permisos sí se pueden cambiar: lo que no se cambia es cómo se llama.
     */
    protected function tieneNombreFijo(Role $role): bool
    {
        return in_array(strtolower($role->name), self::NOMBRES_DEL_SEEDER, true);
    }
}
