<?php

use App\Models\Auth\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\PermissionRegistrar;

/**
 * Asignaciones de rol de usuarios que no existen.
 *
 * **El hallazgo.** Al pintar la columna «Usuarios» de la pantalla de Acceso, el rol
 * Support salía con **1 persona contándolo por la tabla pivote y con 0 contándolo por la
 * relación**. Los dos números no podían tener razón:
 *
 * ```
 * Support   withCount('users')=0   model_has_roles=1   User::role('Support')=0
 * ```
 *
 * La fila apunta a `model_id = 999`, y **ese usuario no existe en `users`** —ni borrado
 * en blando—. Es un resto de datos de prueba: alguien asignó el rol a un id inventado, o
 * se borró el usuario a pelo con SQL sin limpiar sus asignaciones.
 *
 * **Por qué importa y no es solo suciedad.** `model_has_roles` no tiene clave ajena a
 * `users`, así que nada impide que se quede colgando. Y cualquier recuento hecho contra
 * la pivote —lo natural cuando se quiere evitar un N+1— empieza a mentir: la pantalla
 * diría «lo tiene 1 persona» y quien fuera a buscarla a Usuarios no encontraría a nadie.
 * Un número que no se puede explicar es peor que no tener el número.
 *
 * Se borran solo las filas cuyo `model_id` **no aparece en `users` ni entre los borrados
 * en blando**: un usuario dado de baja conserva sus roles a propósito, porque se puede
 * recuperar.
 *
 * `Access::roles()` cuenta con `withCount('users')`, que hace el join y por tanto ya
 * ignoraba estas filas. Esta migración quita la fuente de la discrepancia.
 */
return new class extends Migration
{
    public function up(): void
    {
        // Los ids que sí existen, borrados incluidos.
        $vivos = User::withTrashed()->pluck('id');

        $huerfanas = DB::table('model_has_roles')
            ->where('model_type', User::class)
            ->whereNotIn('model_id', $vivos)
            ->get();

        if ($huerfanas->isEmpty()) {
            return;
        }

        DB::table('model_has_roles')
            ->where('model_type', User::class)
            ->whereNotIn('model_id', $vivos)
            ->delete();

        // Queda dicho en el log del panel: se está borrando una asignación de permisos,
        // y aunque no afecte a nadie —el usuario no existe— el rastro de por qué el
        // recuento de un rol cambió de 1 a 0 tiene que estar en algún sitio.
        \App\Models\Monitoring\Log::db(
            'info',
            '16027',
            'Limpiadas ' . $huerfanas->count() . ' asignación(es) de rol de usuarios que no existen'
            . ' (ids: ' . $huerfanas->pluck('model_id')->implode(', ') . '). Hacían que el recuento'
            . ' de usuarios por rol no cuadrara con la lista de Usuarios.',
            'Role',
            $huerfanas->pluck('role_id')->unique()->implode(',')
        );

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

    /**
     * No se restauran.
     *
     * Apuntaban a usuarios que no existen: recrearlas solo devolvería la discrepancia.
     */
    public function down(): void
    {
        // Nada que deshacer.
    }
};
