<?php

namespace Database\Seeders;

use App\Domains\Authorization\Enums\PermissionCode;
use App\Domains\Authorization\Enums\RoleCode;
use App\Domains\Authorization\Models\Permission;
use App\Domains\Authorization\Models\Role;
use Illuminate\Database\Seeder;

class AuthorizationSeeder extends Seeder
{
    /**
     * @var array<string, array{nombre: string, descripcion: string}>
     */
    private const PERMISSIONS = [
        'tenant.ver' => [
            'nombre' => 'Ver configuración del tenant',
            'descripcion' => 'Permite consultar la configuración general de un tenant.',
        ],
        'tenant.editar' => [
            'nombre' => 'Editar configuración del tenant',
            'descripcion' => 'Permite modificar los datos generales, dominio, colores y recursos visuales del tenant.',
        ],
        'usuarios.ver' => [
            'nombre' => 'Ver usuarios',
            'descripcion' => 'Permite consultar los usuarios asociados al tenant.',
        ],
        'usuarios.gestionar' => [
            'nombre' => 'Gestionar usuarios',
            'descripcion' => 'Permite invitar, editar, desactivar y asignar roles permitidos a los usuarios del tenant.',
        ],
        'roles.ver' => [
            'nombre' => 'Ver roles',
            'descripcion' => 'Permite consultar los roles y sus permisos.',
        ],
        'roles.gestionar' => [
            'nombre' => 'Gestionar roles',
            'descripcion' => 'Permite crear, modificar y asignar permisos a roles.',
        ],
        'catalogo.ver' => [
            'nombre' => 'Ver catálogo',
            'descripcion' => 'Permite consultar administrativamente productos, variantes, categorías, marcas y bundles.',
        ],
        'catalogo.gestionar' => [
            'nombre' => 'Gestionar catálogo',
            'descripcion' => 'Permite crear, modificar, archivar y eliminar productos, variantes, categorías, marcas y bundles.',
        ],
        'inventario.ver' => [
            'nombre' => 'Ver inventario',
            'descripcion' => 'Permite consultar el stock y la información de inventario.',
        ],
        'inventario.ajustar' => [
            'nombre' => 'Ajustar inventario',
            'descripcion' => 'Permite modificar el stock disponible.',
        ],
        'pedidos.ver' => [
            'nombre' => 'Ver pedidos',
            'descripcion' => 'Permite consultar los pedidos del tenant.',
        ],
        'pedidos.gestionar' => [
            'nombre' => 'Gestionar pedidos',
            'descripcion' => 'Permite modificar estados y datos operativos de los pedidos.',
        ],
        'pedidos.cancelar' => [
            'nombre' => 'Cancelar pedidos',
            'descripcion' => 'Permite cancelar pedidos y liberar sus reservas de inventario.',
        ],
        'pagos.ver' => [
            'nombre' => 'Ver pagos',
            'descripcion' => 'Permite consultar el estado y la información de los pagos.',
        ],
        'pagos.gestionar' => [
            'nombre' => 'Gestionar pagos',
            'descripcion' => 'Permite confirmar, rechazar o devolver pagos.',
        ],
        'tickets.ver' => [
            'nombre' => 'Ver tickets',
            'descripcion' => 'Permite consultar los tickets emitidos.',
        ],
        'tickets.gestionar' => [
            'nombre' => 'Gestionar tickets',
            'descripcion' => 'Permite emitir, invalidar o regenerar tickets.',
        ],
        PermissionCode::ScanTickets->value => [
            'nombre' => 'Escanear tickets',
            'descripcion' => 'Permite validar y consumir tickets de las categorías asignadas al usuario.',
        ],
        'contenido.gestionar' => [
            'nombre' => 'Gestionar contenido',
            'descripcion' => 'Permite administrar menús, carruseles, destacados y redes sociales.',
        ],
        'integraciones.ver' => [
            'nombre' => 'Ver integraciones',
            'descripcion' => 'Permite consultar la configuración y el estado de las integraciones.',
        ],
        'integraciones.gestionar' => [
            'nombre' => 'Gestionar integraciones',
            'descripcion' => 'Permite configurar credenciales y proveedores de integraciones.',
        ],
        'reportes.ver' => [
            'nombre' => 'Ver reportes',
            'descripcion' => 'Permite consultar reportes de ventas y métricas.',
        ],
        'reportes.exportar' => [
            'nombre' => 'Exportar reportes',
            'descripcion' => 'Permite descargar reportes e información comercial.',
        ],
    ];

    /**
     * @var array<string, array{nombre: string, descripcion: string, permisos: list<string>}>
     */
    private const ROLES = [
        RoleCode::Admin->value => [
            'nombre' => 'Administrador general',
            'descripcion' => 'Administra la plataforma y todos sus tenants.',
            'permisos' => [],
        ],
        RoleCode::AdminApp->value => [
            'nombre' => 'Administrador de la aplicación',
            'descripcion' => 'Accede a los menús administrativos de la aplicación.',
            'permisos' => [PermissionCode::ScanTickets->value],
        ],
        RoleCode::Scanner->value => [
            'nombre' => 'Scanner',
            'descripcion' => 'Valida y consume tickets de las categorías que tiene asignadas.',
            'permisos' => [PermissionCode::ScanTickets->value],
        ],
        RoleCode::User->value => [
            'nombre' => 'Usuario',
            'descripcion' => 'Cliente final limitado a sus propios datos y operaciones.',
            'permisos' => [],
        ],
    ];

    public function run(): void
    {
        foreach (self::PERMISSIONS as $code => $attributes) {
            Permission::query()->updateOrCreate(
                ['codigo' => $code],
                $attributes
            );
        }

        foreach (self::ROLES as $code => $attributes) {
            $role = Role::query()->updateOrCreate(
                ['codigo' => $code],
                [
                    'nombre' => $attributes['nombre'],
                    'descripcion' => $attributes['descripcion'],
                ]
            );

            $permissionCodes = $code === RoleCode::Admin->value
                ? array_keys(self::PERMISSIONS)
                : $attributes['permisos'];

            $role->permissions()->sync($permissionCodes);
        }
    }
}
