<?php

namespace Database\Seeders;

use App\Models\Permiso;
use App\Models\Rol;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class RoleProfileSeeder extends Seeder
{
    public function run(): void
    {
        $this->call(PermissionCatalogSeeder::class);

        $admin = $this->upsertRole(
            slug: 'admin',
            nombre: 'Administrador',
            descripcion: 'Perfil administrativo con acceso ampliado.'
        );

        $cajero = $this->upsertRole(
            slug: 'cajero',
            nombre: 'Cajero',
            descripcion: 'Perfil operativo de caja y ventas.'
        );

        $bodega = $this->upsertRole(
            slug: 'bodega',
            nombre: 'Bodega',
            descripcion: 'Perfil operativo de inventario y compras.'
        );

        $allPermissionIds = Permiso::query()->pluck('id')->all();
        $this->replaceRolePermissions($admin, $allPermissionIds);

        $this->replaceRolePermissionsByCodes($cajero, [
            'dashboard.ver',
            'clientes.ver',
            'clientes.crear',
            'pos.vender',
            'ventas.ver',
            'caja.ver',
            'caja.abrir',
            'caja.cerrar',
            'cuentas_cobrar.ver',
            'cuentas_cobrar.abonar',
            'reportes.ver',
            'productos.ver',
            'categorias.ver',
        ]);

        $this->replaceRolePermissionsByCodes($bodega, [
            'dashboard.ver',
            'inventario.ver',
            'movimientos_inventario.ver',
            'inventario.ajustar',
            'productos.ver',
            'categorias.ver',
            'proveedores.ver',
            'compras.ver',
            'compras.ordenes',
            'compras.recibir',
            'reportes.ver',
        ]);
    }

    private function upsertRole(string $slug, string $nombre, string $descripcion): Rol
    {
        return Rol::query()->updateOrCreate(
            ['slug' => $slug],
            [
                'nombre' => $nombre,
                'descripcion' => $descripcion,
                'activo' => 1,
            ]
        );
    }

    /**
     * @param  array<int, string>  $codes
     */
    private function replaceRolePermissionsByCodes(Rol $rol, array $codes): void
    {
        $permissionIds = Permiso::query()
            ->whereIn('codigo', $codes)
            ->pluck('id')
            ->all();

        $this->replaceRolePermissions($rol, $permissionIds);
    }

    /**
     * @param  array<int, int|string>  $permissionIds
     */
    private function replaceRolePermissions(Rol $rol, array $permissionIds): void
    {
        DB::table('rol_permiso')->where('rol_id', $rol->id)->delete();

        if ($permissionIds === []) {
            return;
        }

        $now = now();
        $rows = [];

        foreach ($permissionIds as $permissionId) {
            $rows[] = [
                'rol_id' => $rol->id,
                'permiso_id' => (int) $permissionId,
                'created_at' => $now,
            ];
        }

        DB::table('rol_permiso')->insert($rows);
    }
}
