<?php
declare(strict_types=1);

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_start();
}

function tiPermNormalizar(string $texto): string
{
    $texto = trim($texto);
    $texto = function_exists('mb_strtolower')
        ? mb_strtolower($texto, 'UTF-8')
        : strtolower($texto);

    $texto = strtr($texto, [
        'á'=>'a','à'=>'a','â'=>'a','ã'=>'a','ä'=>'a',
        'é'=>'e','è'=>'e','ê'=>'e','ë'=>'e',
        'í'=>'i','ì'=>'i','î'=>'i','ï'=>'i',
        'ó'=>'o','ò'=>'o','ô'=>'o','õ'=>'o','ö'=>'o',
        'ú'=>'u','ù'=>'u','û'=>'u','ü'=>'u','ç'=>'c'
    ]);

    return preg_replace('/[^a-z0-9]+/', '', $texto) ?? '';
}

function tiPermE(mixed $valor): string
{
    return htmlspecialchars((string) $valor, ENT_QUOTES, 'UTF-8');
}

function tiPermBaseUrl(): string
{
    $script = str_replace('\\', '/', (string) ($_SERVER['SCRIPT_NAME'] ?? '/'));

    foreach (['/central_ativos/', '/governanca_ti/'] as $marcador) {
        $posicao = strpos($script, $marcador);
        if ($posicao !== false) {
            return rtrim(substr($script, 0, $posicao), '/') . '/';
        }
    }

    $diretorio = str_replace('\\', '/', dirname($script));
    return rtrim($diretorio === '.' ? '/' : $diretorio, '/') . '/';
}

function tiPermUrl(string $arquivo = ''): string
{
    return tiPermBaseUrl() . ltrim($arquivo, '/');
}

function tiPermTabelaExiste(mysqli $mysqli, string $tabela): bool
{
    $nome = $mysqli->real_escape_string($tabela);
    $resultado = $mysqli->query("SHOW TABLES LIKE '{$nome}'");

    return $resultado instanceof mysqli_result && $resultado->num_rows > 0;
}

function tiPermEstruturaDisponivel(mysqli $mysqli): bool
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $cache = tiPermTabelaExiste($mysqli, 'ti_usuarios_config')
        && tiPermTabelaExiste($mysqli, 'ti_usuario_permissoes')
        && tiPermTabelaExiste($mysqli, 'ti_modulos');

    return $cache;
}

function tiPermUsuarioId(): int
{
    return (int) ($_SESSION['user_id'] ?? 0);
}

function tiPermUsuario(): string
{
    return trim((string) ($_SESSION['usuario'] ?? ''));
}

function tiPermEhRenan(): bool
{
    return tiPermNormalizar(tiPermUsuario()) === 'renan';
}

function tiPermModuloDoArquivo(?string $arquivo = null): ?string
{
    $arquivo = strtolower(str_replace('\\', '/', $arquivo ?: (string) (
        $_SERVER['SCRIPT_FILENAME'] ?? $_SERVER['SCRIPT_NAME'] ?? ''
    )));
    $base = basename($arquivo);

    if ($base === 'logout.php' || $base === 'login.php' || $base === 'auth.php') {
        return null;
    }

    if (str_contains($arquivo, '/central_ativos/')) return 'central_ativos';
    if (str_contains($arquivo, '/governanca_ti/inventario/')) return 'inventario_geral';
    if (str_contains($arquivo, '/governanca_ti/usuarios/')) return 'usuarios_permissoes';

    if (in_array($base, [
        'usuarios_permissoes.php','instalar_governanca_ti.php'
    ], true)) return 'usuarios_permissoes';

    if (str_starts_with($base, 'inventario_geral')
        || str_starts_with($base, 'inventario_campanha')
        || str_starts_with($base, 'inventario_conferir')
        || str_starts_with($base, 'inventario_relatorio')
        || str_starts_with($base, 'inventario_configuracoes')) {
        return 'inventario_geral';
    }

    if ($base === 'central_ativos.php') return 'central_ativos';
    if ($base === 'dashboard_cynthia.php') return 'painel_cynthia';
    if ($base === 'dashboard.php') return 'dashboard';

    if (str_contains($base, 'impressora')) return 'impressoras';
    if (str_contains($base, 'computador') || $base === 'mapa_computadores.php') return 'computadores';
    if (str_starts_with($base, 'inventario_equipamentos') || str_starts_with($base, 'inventario_dispositivo') || str_starts_with($base, 'inventario_mobile') || $base === 'instalar_inventario_mobile.php') return 'inventario_mobile';
    if (str_contains($base, 'smartphone')) return 'smartphones';
    if (str_contains($base, 'chip') || $base === 'telecom_historico.php') return 'chips';
    if (str_contains($base, 'tonner') || str_contains($base, 'toner')) return 'toner';
    if (str_contains($base, 'almoxarifado')) return 'almoxarifado';
    if (str_contains($base, 'rastrear')) return 'rastreador';
    if ($base === 'inteligencia.php' || $base === 'ia_analise.php') return 'inteligencia';
    if (str_contains($base, 'relatorio') || $base === 'exportar_excel.php') return 'relatorios';
    if (str_contains($base, 'alerta_global')) return 'alertas';

    $arquivosOs = [
        'listar_os.php','nova_os.php','detalhes_os.php','finalizar_os.php',
        'marcar_finalizado.php','confirmar_retirada.php','historico.php',
        'exportar_os_pdf.php','comprovante_os.php','comprovante_abertura_os.php',
        'comprovante_movimentacao.php','anexar_termo_assinado.php',
        'visualizar_termo_assinado.php','registrar_ciencia_os.php',
        'avaliar_os.php','gerenciar_acompanhamento_os.php'
    ];
    if (in_array($base, $arquivosOs, true)) return 'os';

    return null;
}

function tiPermAcaoDoArquivo(?string $arquivo = null): string
{
    $base = strtolower(basename($arquivo ?: (string) (
        $_SERVER['SCRIPT_FILENAME'] ?? $_SERVER['SCRIPT_NAME'] ?? ''
    )));

    if (str_contains($base, 'instalar') || str_contains($base, 'configuracoes')) return 'administrar';
    if (str_contains($base, 'excluir') || str_contains($base, 'deletar')) return 'excluir';
    if (str_contains($base, 'exportar') || str_contains($base, 'relatorio')) return 'exportar';
    if (str_contains($base, 'finalizar') || str_contains($base, 'retirada') || str_contains($base, 'encerrar')) return 'finalizar';
    if (str_contains($base, 'transfer') || str_contains($base, 'moviment')) return 'transferir';
    if (str_contains($base, 'nova_') || str_contains($base, 'novo_') || str_contains($base, 'criar') || str_contains($base, 'receber') || str_contains($base, 'anexar')) return 'cadastrar';
    if (str_contains($base, 'editar') || str_contains($base, 'manutencao') || str_contains($base, 'conferir')) return 'editar';

    return 'visualizar';
}

function tiPermConfigUsuario(mysqli $mysqli, int $userId): ?array
{
    static $cache = [];
    if (array_key_exists($userId, $cache)) return $cache[$userId];
    if (!tiPermEstruturaDisponivel($mysqli)) return $cache[$userId] = null;

    $stmt = $mysqli->prepare('SELECT * FROM ti_usuarios_config WHERE user_id=? LIMIT 1');
    if (!$stmt) return $cache[$userId] = null;
    $stmt->bind_param('i', $userId);
    $stmt->execute();
    $linha = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    return $cache[$userId] = ($linha ?: null);
}

function tiPermPode(mysqli $mysqli, string $modulo, string $acao = 'visualizar', ?int $userId = null): bool
{
    if (tiPermEhRenan() && ($userId === null || $userId === tiPermUsuarioId())) {
        return true;
    }

    if (!tiPermEstruturaDisponivel($mysqli)) {
        return true;
    }

    $userId = $userId ?? tiPermUsuarioId();
    if ($userId <= 0) return false;

    $config = tiPermConfigUsuario($mysqli, $userId);
    if ($config && (int) $config['ativo'] !== 1) return false;
    if ($config && (int) $config['admin_global'] === 1) return true;

    $campos = [
        'visualizar'=>'pode_visualizar','cadastrar'=>'pode_cadastrar',
        'editar'=>'pode_editar','excluir'=>'pode_excluir',
        'transferir'=>'pode_transferir','finalizar'=>'pode_finalizar',
        'exportar'=>'pode_exportar','administrar'=>'pode_administrar'
    ];
    $campo = $campos[$acao] ?? 'pode_visualizar';

    static $cache = [];
    $chave = $userId . '|' . $modulo . '|' . $campo;
    if (array_key_exists($chave, $cache)) return $cache[$chave];

    $stmt = $mysqli->prepare("SELECT {$campo} permitido FROM ti_usuario_permissoes WHERE user_id=? AND modulo_slug=? LIMIT 1");
    if (!$stmt) return $cache[$chave] = false;
    $stmt->bind_param('is', $userId, $modulo);
    $stmt->execute();
    $linha = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    return $cache[$chave] = ((int) ($linha['permitido'] ?? 0) === 1);
}

function tiPermRegistrarAuditoria(
    mysqli $mysqli,
    string $acao,
    ?string $modulo = null,
    ?int $alvoUserId = null,
    ?string $detalhes = null
): void {
    if (!tiPermTabelaExiste($mysqli, 'ti_permissoes_auditoria')) return;

    $usuarioId = tiPermUsuarioId();
    $usuario = tiPermUsuario() ?: 'Sistema';
    $ip = substr((string) ($_SERVER['REMOTE_ADDR'] ?? ''), 0, 45);
    $navegador = substr((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 500);

    $stmt = $mysqli->prepare(
        'INSERT INTO ti_permissoes_auditoria '
        . '(usuario_id,usuario,acao,modulo_slug,alvo_user_id,detalhes,ip,navegador) '
        . 'VALUES(NULLIF(?,0),?,?,?,?,?,?,?)'
    );
    if (!$stmt) return;
    $stmt->bind_param('isssisss', $usuarioId, $usuario, $acao, $modulo, $alvoUserId, $detalhes, $ip, $navegador);
    $stmt->execute();
    $stmt->close();
}

function tiPermPaginaInicial(mysqli $mysqli, ?int $userId = null): string
{
    $userId = $userId ?? tiPermUsuarioId();
    $config = tiPermConfigUsuario($mysqli, $userId);
    $preferida = trim((string) ($config['pagina_inicial'] ?? ''));
    if ($preferida !== '') return tiPermUrl($preferida);

    $rotas = [
        'painel_cynthia'=>'dashboard_cynthia.php',
        'os'=>'listar_os.php','central_ativos'=>'central_ativos.php',
        'inventario_geral'=>'inventario_geral.php','inventario_mobile'=>'inventario_equipamentos.php','computadores'=>'computadores.php',
        'impressoras'=>'impressoras.php','toner'=>'tonner.php',
        'chips'=>'chips.php','smartphones'=>'smartphones.php',
        'almoxarifado'=>'almoxarifado.php','dashboard'=>'dashboard.php'
    ];

    foreach ($rotas as $modulo => $rota) {
        if (tiPermPode($mysqli, $modulo, 'visualizar', $userId)) return tiPermUrl($rota);
    }

    return tiPermUrl('logout.php');
}

function tiPermNegar(mysqli $mysqli, string $modulo, string $acao): never
{
    tiPermRegistrarAuditoria($mysqli, 'ACESSO_NEGADO', $modulo, tiPermUsuarioId(), 'Ação solicitada: ' . $acao);

    if (tiPermNormalizar(tiPermUsuario()) === 'cynthia') {
        header('Location: ' . tiPermUrl('dashboard_cynthia.php?acesso_restrito=1'));
        exit;
    }

    $json = strtolower((string) ($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '')) === 'xmlhttprequest'
        || str_contains(strtolower((string) ($_SERVER['HTTP_ACCEPT'] ?? '')), 'application/json');

    if ($json) {
        http_response_code(403);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=>false,'message'=>'Seu usuário não possui permissão para esta ação.'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    http_response_code(403);
    $voltar = tiPermPaginaInicial($mysqli);
    echo '<!doctype html><html lang="pt-BR"><head><meta charset="utf-8">';
    echo '<meta name="viewport" content="width=device-width,initial-scale=1">';
    echo '<title>Acesso restrito</title><style>';
    echo 'body{margin:0;min-height:100vh;display:grid;place-items:center;padding:20px;font-family:Inter,Arial,sans-serif;background:#edf3f8;color:#172438}';
    echo '.box{width:min(620px,100%);padding:36px;border-radius:28px;background:#fff;box-shadow:0 30px 90px rgba(8,57,111,.18);text-align:center}';
    echo '.icon{width:72px;height:72px;display:grid;place-items:center;margin:0 auto 18px;border-radius:22px;color:#fff;background:#bf263d;font-size:32px}';
    echo 'h1{margin:0;color:#08396f}p{color:#62738a;line-height:1.65}a{display:inline-flex;margin-top:14px;padding:12px 17px;border-radius:13px;color:#fff;background:#08396f;text-decoration:none;font-weight:800}</style></head><body><main class="box">';
    echo '<div class="icon">!</div><h1>Acesso não autorizado</h1>';
    echo '<p>Seu perfil não possui permissão para acessar este módulo ou executar esta ação.</p>';
    echo '<a href="' . tiPermE($voltar) . '">Voltar ao meu painel</a></main></body></html>';
    exit;
}

function tiPermExigir(mysqli $mysqli, string $modulo, string $acao = 'visualizar'): void
{
    if (!tiPermPode($mysqli, $modulo, $acao)) {
        tiPermNegar($mysqli, $modulo, $acao);
    }
}

function tiPermAplicarProtecaoArquivoAtual(mysqli $mysqli): void
{
    if (!tiPermEstruturaDisponivel($mysqli)) return;

    $config = tiPermConfigUsuario($mysqli, tiPermUsuarioId());
    if ($config && (int) $config['ativo'] !== 1) {
        $_SESSION = [];
        if (ini_get('session.use_cookies')) {
            $params = session_get_cookie_params();
            setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
        }
        session_destroy();
        header('Location: ' . tiPermUrl('login.php?conta_inativa=1'));
        exit;
    }

    $modulo = tiPermModuloDoArquivo();
    if ($modulo === null) return;
    tiPermExigir($mysqli, $modulo, tiPermAcaoDoArquivo());
}
