<?php

declare(strict_types=1);

namespace App\Models;

use App\Core\Database;

class Role extends BaseModel
{
    protected string $table = 'roles';
    protected ?string $tenantColumn = null;

    public function activeRoles(bool $includeSuperadmin = false): array
    {
        $sql = 'SELECT id, nombre, slug, descripcion, activo
                FROM roles
                WHERE activo = 1';
        $params = [];

        if (!$includeSuperadmin) {
            $sql .= ' AND slug <> :superadmin_slug';
            $params[':superadmin_slug'] = 'superadmin';
        }

        $sql .= ' ORDER BY id ASC';

        $stmt = $this->db()->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll() ?: [];
    }

    public function permissionsCatalog(bool $includeSuperadmin = false): array
    {
        $sql = 'SELECT id, nombre, codigo, modulo
                FROM permisos
                WHERE 1 = 1';
        $params = [];

        if (!$includeSuperadmin) {
            $sql .= ' AND modulo <> :superadmin_module
                      AND codigo NOT LIKE :superadmin_code';
            $params[':superadmin_module'] = 'superadmin';
            $params[':superadmin_code'] = 'superadmin.%';
        }

        $sql .= ' ORDER BY modulo ASC, codigo ASC';

        $stmt = $this->db()->prepare($sql);
        $stmt->execute($params);

        return $stmt->fetchAll() ?: [];
    }

    public function findActiveById(int $roleId, bool $includeSuperadmin = false): ?array
    {
        if ($roleId <= 0) {
            return null;
        }

        $sql = 'SELECT id, nombre, slug, descripcion, activo
                FROM roles
                WHERE id = :id
                  AND activo = 1';
        $params = [':id' => $roleId];

        if (!$includeSuperadmin) {
            $sql .= ' AND slug <> :superadmin_slug';
            $params[':superadmin_slug'] = 'superadmin';
        }

        $sql .= ' LIMIT 1';

        $stmt = $this->db()->prepare($sql);
        $stmt->execute($params);
        $role = $stmt->fetch();

        return is_array($role) ? $role : null;
    }

    public function permissionIdsByRole(int $roleId): array
    {
        $stmt = $this->db()->prepare(
            'SELECT permiso_id
             FROM rol_permiso
             WHERE rol_id = :rol_id'
        );
        $stmt->execute([':rol_id' => $roleId]);

        return array_map(
            static fn (array $row): int => (int) ($row['permiso_id'] ?? 0),
            $stmt->fetchAll() ?: []
        );
    }

    public function syncPermissions(int $roleId, array $permissionIds): void
    {
        $normalized = [];
        foreach ($permissionIds as $permissionId) {
            $value = (int) $permissionId;
            if ($value > 0) {
                $normalized[] = $value;
            }
        }
        $normalized = array_values(array_unique($normalized));

        Database::transaction(function () use ($roleId, $normalized): void {
            $pdo = Database::connection();

            $deleteStmt = $pdo->prepare('DELETE FROM rol_permiso WHERE rol_id = :rol_id');
            $deleteStmt->execute([':rol_id' => $roleId]);

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

            $insertStmt = $pdo->prepare(
                'INSERT INTO rol_permiso (rol_id, permiso_id, created_at)
                 VALUES (:rol_id, :permiso_id, NOW())'
            );

            foreach ($normalized as $permissionId) {
                $insertStmt->execute([
                    ':rol_id' => $roleId,
                    ':permiso_id' => $permissionId,
                ]);
            }
        });
    }
}
