<?php

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

return new class extends Migration
{
    /**
     * Helper method to create permission and assign to roles
     */
    private function createPermissionAndAssign(string $name, string $model, string $description, array $roles): void
    {
        $perm = Permission::firstOrCreate(
            ['name' => $name],
            ['model' => $model, 'description' => $description, 'guard_name' => 'web']
        );
        
        foreach ($roles as $role) {
            if ($role && !$role->hasPermissionTo($perm)) {
                $role->givePermissionTo($perm);
            }
        }
    }

    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Obtener roles existentes
        $role_admin = Role::where('name', 'Admin')->first();
        $role_system = Role::where('name', 'System')->first();
        $role_support = Role::where('name', 'Support')->first();
        $role_manager = Role::where('name', 'Manager')->first();
        $role_developer = Role::where('name', 'Developer')->first();
        $role_ws = Role::where('name', 'WebService')->first();

        // Si los roles no existen, no continuar
        if (!$role_admin) {
            return;
        }

        // Dashboard
        $this->createPermissionAndAssign(
            'admin.dashboard.index',
            'dashboard',
            'Dashboard: Ver panel principal',
            [$role_admin]
        );

        // Users
        $this->createPermissionAndAssign('admin.users.index', 'users', 'Usuarios: Ver listado', [$role_admin]);
        $this->createPermissionAndAssign('admin.users.create', 'users', 'Usuarios: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.users.edit', 'users', 'Usuarios: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.users.destroy', 'users', 'Usuarios: Eliminar', [$role_admin]);

        // Roles
        $this->createPermissionAndAssign('admin.roles.index', 'roles', 'Roles: Ver Listado', [$role_admin]);
        $this->createPermissionAndAssign('admin.roles.create', 'roles', 'Roles: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.roles.edit', 'roles', 'Roles: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.roles.destroy', 'roles', 'Roles: Eliminar', [$role_admin]);

        // Permissions
        $this->createPermissionAndAssign('admin.permissions.index', 'permissions', 'Permisos: Ver listado', [$role_admin]);
        $this->createPermissionAndAssign('admin.permissions.create', 'permissions', 'Permisos: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.permissions.edit', 'permissions', 'Permisos: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.permissions.destroy', 'permissions', 'Permisos: Eliminar', [$role_admin]);

        // Environments
        $this->createPermissionAndAssign('admin.environments.index', 'environments', 'Entornos: Ver listado', [$role_admin, $role_ws]);
        $this->createPermissionAndAssign('admin.environments.create', 'environments', 'Entornos: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.edit', 'environments', 'Entornos: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.destroy', 'environments', 'Entornos: Eliminar', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.refresh', 'environments', 'Entornos: Refrescar Plugin Moodle', [$role_admin]);

        // Clients
        $this->createPermissionAndAssign('admin.clients.index', 'clients', 'Clientes: Ver listado', [$role_admin]);
        $this->createPermissionAndAssign('admin.clients.create', 'clients', 'Clientes: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.clients.edit', 'clients', 'Clientes: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.clients.destroy', 'clients', 'Clientes: Eliminar', [$role_admin]);

        // Supports
        $this->createPermissionAndAssign('admin.supports.index', 'supports', 'Soporte: Ver listado', [$role_admin]);
        $this->createPermissionAndAssign('admin.supports.create', 'supports', 'Soporte: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.supports.edit', 'supports', 'Soporte: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.supports.destroy', 'supports', 'Soporte: Eliminar', [$role_admin]);

        // Environment Supports
        $this->createPermissionAndAssign('admin.environments.supports.index', 'environment_support', 'Soporte Entorno: Ver', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.supports.create', 'environment_support', 'Soporte Entorno: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.supports.edit', 'environment_support', 'Soporte Entorno: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.supports.destroy', 'environment_support', 'Soporte Entorno: Borrar', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.supports.activate', 'environment_support', 'Soporte Entorno: Activar', [$role_admin]);
        $this->createPermissionAndAssign('admin.environments.supports.disactivate', 'environment_support', 'Soporte Entorno: Desactivar', [$role_admin]);

        // Types
        $this->createPermissionAndAssign('admin.types.index', 'types', 'Tipo: Ver listado', [$role_admin]);
        $this->createPermissionAndAssign('admin.types.create', 'types', 'Tipo: Crear', [$role_admin]);
        $this->createPermissionAndAssign('admin.types.edit', 'types', 'Tipo: Editar', [$role_admin]);
        $this->createPermissionAndAssign('admin.types.destroy', 'types', 'Tipo: Eliminar', [$role_admin]);
        $this->createPermissionAndAssign('admin.types.list', 'types', 'Tipo: Listar WS', [$role_admin, $role_ws]);

        // Datas
        $this->createPermissionAndAssign('admin.datas.environment', 'datas', 'Datos: Ver datos de Entorno', [$role_admin]);
        $this->createPermissionAndAssign('api.datas.store', 'datas', 'Datos: Grabar datos desde Moodle API', [$role_admin, $role_ws]);

        // Plugins
        $this->createPermissionAndAssign('admin.plugins.environment', 'plugins', 'Plugins: Ver datos de los Plugins de Entorno', [$role_admin]);
        $this->createPermissionAndAssign('api.plugins.store', 'plugins', 'Plugins: Grabar datos desde Moodle API', [$role_admin, $role_ws]);

        // Updates
        $this->createPermissionAndAssign('admin.updates.environment', 'updates', 'Actualizaciones: Ver actualizaciones del core disponibles en el entorno', [$role_admin]);
        $this->createPermissionAndAssign('api.updates.store', 'updates', 'Actualizaciones Core: Grabar datos de actualizaciones del core desde Moodle API', [$role_admin, $role_ws]);

        // Reports
        $this->createPermissionAndAssign('admin.reports.environment', 'reports', 'Reports: Ver reportes gráficos', [$role_admin]);

        // Configs
        $this->createPermissionAndAssign('admin.configs.index', 'configs', 'Configs: Ver parámetros de configuración', [$role_admin]);
        $this->createPermissionAndAssign('admin.configs.edit', 'configs', 'Configs: Editar parámetros de configuración', [$role_admin]);

        // Tokens
        $this->createPermissionAndAssign('admin.tokens.index', 'tokens', 'Tokens: Ver token WS', [$role_admin]);

        // Logs
        $this->createPermissionAndAssign('admin.logs.index', 'logs', 'Logs: Ver listado', [$role_admin]);

        // Notices
        $this->createPermissionAndAssign('admin.notices.index', 'notices', 'Avisos: Ver listado', [$role_admin]);

        // Products
        $this->createPermissionAndAssign('admin.products.index', 'products', 'Productos: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.products.create', 'products', 'Productos: Crear', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.products.edit', 'products', 'Productos: Editar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.products.destroy', 'products', 'Productos: Eliminar', [$role_admin]);
        $this->createPermissionAndAssign('admin.products.show', 'products', 'Productos: Ver detalle', [$role_admin, $role_manager, $role_developer]);

        // Setups
        $this->createPermissionAndAssign('admin.setups.index', 'setups', 'Setups: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.setups.create', 'setups', 'Setups: Crear', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.setups.edit', 'setups', 'Setups: Editar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.setups.show', 'setups', 'Setups: Ver detalle', [$role_admin, $role_manager, $role_developer]);

        // Features
        $this->createPermissionAndAssign('admin.features.index', 'features', 'Features: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.features.create', 'features', 'Features: Crear', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.features.edit', 'features', 'Features: Editar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.features.destroy', 'features', 'Features: Eliminar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.features.version.create', 'features', 'Features: Crear versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.features.version.edit', 'features', 'Features: Editar versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.features.version.show', 'features', 'Features: Ver versión', [$role_admin, $role_manager, $role_developer]);

        // Tutorials
        $this->createPermissionAndAssign('admin.tutorials.index', 'tutorials', 'Tutoriales: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.tutorials.create', 'tutorials', 'Tutoriales: Crear', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.tutorials.edit', 'tutorials', 'Tutoriales: Editar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.tutorials.destroy', 'tutorials', 'Tutoriales: Eliminar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.tutorials.version.create', 'tutorials', 'Tutoriales: Crear versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.tutorials.version.edit', 'tutorials', 'Tutoriales: Editar versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.tutorials.version.show', 'tutorials', 'Tutoriales: Ver versión', [$role_admin, $role_manager, $role_developer]);

        // Resources
        $this->createPermissionAndAssign('admin.resources.index', 'resources', 'Recursos: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.resources.create', 'resources', 'Recursos: Crear', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.resources.edit', 'resources', 'Recursos: Editar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.resources.destroy', 'resources', 'Recursos: Eliminar', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.resources.version.create', 'resources', 'Recursos: Crear versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.resources.version.edit', 'resources', 'Recursos: Editar versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.resources.version.show', 'resources', 'Recursos: Ver versión', [$role_admin, $role_manager, $role_developer]);

        // SCSS
        $this->createPermissionAndAssign('admin.scss.index', 'scss', 'SCSS: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.create', 'scss', 'SCSS: Crear archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.edit', 'scss', 'SCSS: Editar archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.show', 'scss', 'SCSS: Ver archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.version.create', 'scss', 'SCSS: Crear versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.version.edit', 'scss', 'SCSS: Editar versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.version.show', 'scss', 'SCSS: Ver versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.files.upload', 'scss', 'SCSS: Subir archivos', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.file.create', 'scss', 'SCSS: Crear archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.file.show', 'scss', 'SCSS: Ver archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.file.edit', 'scss', 'SCSS: Editar archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss.file.destroy', 'scss', 'SCSS: Eliminar archivo', [$role_admin, $role_manager, $role_developer]);

        // JS
        $this->createPermissionAndAssign('admin.js.index', 'js', 'JS: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.create', 'js', 'JS: Crear archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.edit', 'js', 'JS: Editar archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.show', 'js', 'JS: Ver archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.version.create', 'js', 'JS: Crear versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.version.edit', 'js', 'JS: Editar versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.version.show', 'js', 'JS: Ver versión', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.files.upload', 'js', 'JS: Subir archivos', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.file.create', 'js', 'JS: Crear archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.file.show', 'js', 'JS: Ver archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.file.edit', 'js', 'JS: Editar archivo', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.js.file.destroy', 'js', 'JS: Eliminar archivo', [$role_admin, $role_manager, $role_developer]);

        // SCSS CDN
        $this->createPermissionAndAssign('admin.scss-cdn.index', 'scss_cdn', 'SCSS CDN: Ver listado', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.create', 'scss_cdn', 'SCSS CDN: Crear bundle', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.edit', 'scss_cdn', 'SCSS CDN: Editar bundle', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.show', 'scss_cdn', 'SCSS CDN: Ver bundle', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.bundle.show', 'scss_cdn', 'SCSS CDN: Ver bundle', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.bundle.edit', 'scss_cdn', 'SCSS CDN: Editar bundle', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.bundle.upload', 'scss_cdn', 'SCSS CDN: Subir bundle', [$role_admin, $role_manager, $role_developer]);
        $this->createPermissionAndAssign('admin.scss-cdn.file.edit', 'scss_cdn', 'SCSS CDN: Editar archivo', [$role_admin, $role_manager, $role_developer]);

        // License Tokens
        $this->createPermissionAndAssign('admin.license-tokens.index', 'license_tokens', 'Tokens de Licencia: Ver listado', [$role_admin, $role_manager]);
        $this->createPermissionAndAssign('admin.license-tokens.create', 'license_tokens', 'Tokens de Licencia: Crear', [$role_admin, $role_manager]);
        $this->createPermissionAndAssign('admin.license-tokens.edit', 'license_tokens', 'Tokens de Licencia: Editar', [$role_admin, $role_manager]);
        $this->createPermissionAndAssign('admin.license-tokens.destroy', 'license_tokens', 'Tokens de Licencia: Eliminar', [$role_admin]);
        $this->createPermissionAndAssign('admin.license-tokens.show', 'license_tokens', 'Tokens de Licencia: Ver detalle', [$role_admin, $role_manager]);
        $this->createPermissionAndAssign('admin.license-tokens.manage-environments', 'license_tokens', 'Tokens de Licencia: Gestionar entornos', [$role_admin, $role_manager]);
        $this->createPermissionAndAssign('admin.license-tokens.associate-license', 'license_tokens', 'Tokens de Licencia: Asociar licencia', [$role_admin, $role_manager]);

        // Configurations - Environments Types
        $this->createPermissionAndAssign('admin.configurations.environments-types.index', 'configurations', 'Configuraciones: Ver tipos de entornos', [$role_admin, $role_system]);
        $this->createPermissionAndAssign('admin.configurations.environments-types.create', 'configurations', 'Configuraciones: Crear tipo de entorno', [$role_admin, $role_system]);
        $this->createPermissionAndAssign('admin.configurations.environments-types.edit', 'configurations', 'Configuraciones: Editar tipo de entorno', [$role_admin, $role_system]);

        // Configurations - Products
        $this->createPermissionAndAssign('admin.configurations.products.index', 'configurations', 'Configuraciones: Ver productos', [$role_admin, $role_system]);
        $this->createPermissionAndAssign('admin.configurations.products.create', 'configurations', 'Configuraciones: Crear producto', [$role_admin, $role_system]);
        $this->createPermissionAndAssign('admin.configurations.products.edit', 'configurations', 'Configuraciones: Editar producto', [$role_admin, $role_system]);

        // Asignar permisos adicionales a roles según estrategia
        // System: Permisos de lectura y gestión técnica
        if ($role_system) {
            $systemPermissions = [
                'admin.environments.index',
                'admin.types.index',
                'admin.supports.index',
                'admin.logs.index',
            ];
            
            foreach ($systemPermissions as $permName) {
                $perm = Permission::where('name', $permName)->first();
                if ($perm && !$role_system->hasPermissionTo($perm)) {
                    $role_system->givePermissionTo($perm);
                }
            }
        }

        // Support: Permisos de lectura y gestión de soporte
        if ($role_support) {
            $supportPermissions = [
                'admin.environments.supports.index',
                'admin.environments.supports.create',
                'admin.environments.supports.edit',
                'admin.clients.index',
                'admin.reports.environment',
            ];
            
            foreach ($supportPermissions as $permName) {
                $perm = Permission::where('name', $permName)->first();
                if ($perm && !$role_support->hasPermissionTo($perm)) {
                    $role_support->givePermissionTo($perm);
                }
            }
        }

        // Asegurar que el rol Admin tenga TODOS los permisos existentes
        $allPermissions = Permission::all();
        foreach ($allPermissions as $permission) {
            if (!$role_admin->hasPermissionTo($permission)) {
                $role_admin->givePermissionTo($permission);
            }
        }

        // Limpiar caché de permisos
        app()['cache']->forget('spatie.permission.cache');
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        // No eliminamos permisos en el rollback para evitar problemas
        // Si es necesario hacer rollback, se debe hacer manualmente
        // ya que puede haber usuarios con estos permisos asignados
    }
};
