<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Str;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use App\Models\User;
use Illuminate\Support\Facades\Hash;

class ScanResourcesPermissions extends Command
{
    protected $signature = 'permissions:scan
                            {--create-user= : Email del usuario a crear}
                            {--password= : Contraseña para el usuario (si se usa --create-user)}
                            {--role=Administrador : Nombre del rol a crear}';

    protected $description = 'Escanea app/Filament/Resources para generar permisos CRUD, crear rol y asignar permisos. Opcionalmente crea un usuario y le asigna el rol.';

    public function handle()
    {
        $this->info('Escaneando recursos Filament...');

        $fs = new Filesystem();
        $resourcesPath = app_path('Filament/Resources');

        if (! $fs->isDirectory($resourcesPath)) {
            $this->error("No se encontró la carpeta {$resourcesPath}. Ningún permiso fue creado.");
            return 1;
        }

        $files = $fs->allFiles($resourcesPath);

        $created = [];

        foreach ($files as $file) {
            if (! Str::endsWith($file->getFilename(), 'Resource.php')) {
                continue;
            }

            $filename = pathinfo($file->getFilename(), PATHINFO_FILENAME);
            $className = 'App\\Filament\\Resources\\' . $filename;

            // Intentar obtener un label legible: preferimos el método getPluralModelLabel(), luego getNavigationLabel(), luego la propiedad estática
            $label = null;
            $pluralLabel = null;

            if (class_exists($className)) {
                if (method_exists($className, 'getPluralModelLabel')) {
                    $pluralLabel = $className::getPluralModelLabel();
                }

                if (! $pluralLabel && method_exists($className, 'getNavigationLabel')) {
                    $pluralLabel = $className::getNavigationLabel();
                }

                if (! $pluralLabel && isset($className::$navigationLabel)) {
                    $pluralLabel = $className::$navigationLabel;
                }
            }

            // Si no hay label plural, usar el nombre del archivo sin sufijo Resource
            if ($pluralLabel) {
                $base = Str::lower($pluralLabel);
            } else {
                $base = Str::lower(Str::replaceLast('Resource', '', $filename));
            }

            // Normalizar: eliminar espacios extra y restos de extensión
            $base = trim((string) Str::of($base)->lower());
            $base = preg_replace('/\.php$/', '', $base);

            // Generar formas singular y plural
            $plural = Str::lower(Str::plural($base));
            $singular = Str::lower(Str::singular($base));

            // Generar permisos comunes
            $perms = [
                "ver {$plural}",
                "crear {$singular}",
                "editar {$singular}",
                "eliminar {$singular}",
            ];

            foreach ($perms as $permName) {
                $permission = Permission::firstOrCreate(['name' => $permName]);
                $created[] = $permission->name;
            }
        }

        // Asegurar permisos para roles y permisos (usados en Resource::canViewAny en algunos casos)
        Permission::firstOrCreate(['name' => 'ver roles']);
        Permission::firstOrCreate(['name' => 'ver permisos']);

        $this->info('Permisos generados/asegurados: ' . count($created));
        $this->line(implode("\n", array_slice($created, 0, 200)));

        // Eliminar permisos mal formados (ej. que contienen '.php') generados por escaneos previos
        Permission::where('name', 'like', '%.php%')->orWhere('name', 'like', '%.phps%')->delete();

        // Crear rol y asignar todos los permisos
        $roleName = $this->option('role') ?? 'Administrador';
        $role = Role::firstOrCreate(['name' => $roleName]);
        $all = Permission::all();
        $role->syncPermissions($all);

        $this->info("Rol '{$roleName}' creado/actualizado y se le asignaron " . $all->count() . " permisos.");

        // Si se solicita, crear usuario y asignar rol
        $createUserEmail = $this->option('create-user');
        $password = $this->option('password');

        if ($createUserEmail) {
            if (! $password) {
                $this->error('Si usas --create-user debes pasar también --password.');
                return 1;
            }

            $user = User::updateOrCreate(
                ['email' => $createUserEmail],
                ['name' => $roleName, 'password' => Hash::make($password)]
            );

            $user->assignRole($role);
            $this->info("Usuario '{$createUserEmail}' creado/actualizado y se le asignó el rol '{$roleName}'.");
        }

        $this->info('Finalizado.');

        return 0;
    }
}
