<?php

if (!function_exists('garantir_estrutura_logs')) {
function garantir_estrutura_logs($conn) {
    static $estrutura_ok = false;
    if ($estrutura_ok) {
        return;
    }

    $sql = "
        CREATE TABLE IF NOT EXISTS logs_interacoes (
            id_log INT AUTO_INCREMENT PRIMARY KEY,
            data_hora DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
            usuario_id INT NULL,
            usuario_nome VARCHAR(150) NULL,
            usuario_login VARCHAR(120) NULL,
            usuario_nivel VARCHAR(40) NULL,
            tipo_operacao VARCHAR(80) NOT NULL,
            modulo VARCHAR(150) NOT NULL,
            url VARCHAR(255) NULL,
            metodo_http VARCHAR(10) NULL,
            ip VARCHAR(45) NULL,
            user_agent VARCHAR(255) NULL,
            detalhes TEXT NULL,
            INDEX idx_logs_data_hora (data_hora),
            INDEX idx_logs_usuario (usuario_id),
            INDEX idx_logs_tipo (tipo_operacao),
            INDEX idx_logs_modulo (modulo),
            INDEX idx_logs_metodo (metodo_http)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    ";

    $conn->query($sql);
    $estrutura_ok = true;
}
}

if (!function_exists('limpar_texto_log')) {
function limpar_texto_log($valor, $max = 255) {
    $texto = trim((string)$valor);
    if ($texto === '') {
        return '';
    }
    return substr($texto, 0, $max);
}
}

if (!function_exists('obter_ip_requisicao')) {
function obter_ip_requisicao() {
    $candidatos = [
        'HTTP_CF_CONNECTING_IP',
        'HTTP_X_REAL_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_CLIENT_IP',
        'REMOTE_ADDR'
    ];

    foreach ($candidatos as $chave) {
        $valor = trim((string)($_SERVER[$chave] ?? ''));
        if ($valor === '' || strtolower($valor) === 'unknown') {
            continue;
        }

        // Alguns headers podem trazer lista: "ip1, ip2, ip3"
        $itens = explode(',', $valor);
        foreach ($itens as $item) {
            $ip = trim((string)$item);
            if ($ip === '') {
                continue;
            }

            // Remove possível sufixo de porta em IPv4 (ex: 10.0.0.1:1234)
            if (strpos($ip, ':') !== false && substr_count($ip, ':') === 1 && strpos($ip, '.') !== false) {
                $ip = explode(':', $ip)[0];
            }

            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }

    return '';
}
}

if (!function_exists('registrar_log_interacao')) {
function registrar_log_interacao($conn, $tipo_operacao, $detalhes = '', $contexto = []) {
    garantir_estrutura_logs($conn);

    $usuario_id = isset($contexto['usuario_id']) ? (int)$contexto['usuario_id'] : (int)($_SESSION['usuario_id'] ?? 0);
    $usuario_nome = limpar_texto_log($contexto['usuario_nome'] ?? ($_SESSION['usuario_nome'] ?? ''), 150);
    $usuario_login = limpar_texto_log($contexto['usuario_login'] ?? ($_SESSION['usuario_login'] ?? ''), 120);
    $usuario_nivel = limpar_texto_log($contexto['usuario_nivel'] ?? ($_SESSION['usuario_nivel'] ?? ''), 40);

    $modulo = limpar_texto_log($contexto['modulo'] ?? basename($_SERVER['SCRIPT_NAME'] ?? 'sistema.php'), 150);
    $url = limpar_texto_log($contexto['url'] ?? ($_SERVER['REQUEST_URI'] ?? ''), 255);
    $metodo_http = limpar_texto_log($contexto['metodo_http'] ?? ($_SERVER['REQUEST_METHOD'] ?? ''), 10);
    $ip = limpar_texto_log($contexto['ip'] ?? obter_ip_requisicao(), 45);
    $user_agent = limpar_texto_log($contexto['user_agent'] ?? ($_SERVER['HTTP_USER_AGENT'] ?? ''), 255);

    $tipo_operacao = limpar_texto_log($tipo_operacao, 80);
    $detalhes = trim((string)$detalhes);

    $usuario_id_db = $usuario_id > 0 ? $usuario_id : null;
    if ($usuario_nome === '') {
        $usuario_nome = null;
    }
    if ($usuario_login === '') {
        $usuario_login = null;
    }
    if ($usuario_nivel === '') {
        $usuario_nivel = null;
    }
    if ($url === '') {
        $url = null;
    }
    if ($metodo_http === '') {
        $metodo_http = null;
    }
    if ($ip === '') {
        $ip = null;
    }
    if ($user_agent === '') {
        $user_agent = null;
    }
    if ($detalhes === '') {
        $detalhes = null;
    } else {
        $detalhes = substr($detalhes, 0, 2000);
    }

    $stmt = $conn->prepare("
        INSERT INTO logs_interacoes
        (usuario_id, usuario_nome, usuario_login, usuario_nivel, tipo_operacao, modulo, url, metodo_http, ip, user_agent, detalhes)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    if (!$stmt) {
        return false;
    }

    $stmt->bind_param(
        'issssssssss',
        $usuario_id_db,
        $usuario_nome,
        $usuario_login,
        $usuario_nivel,
        $tipo_operacao,
        $modulo,
        $url,
        $metodo_http,
        $ip,
        $user_agent,
        $detalhes
    );

    return $stmt->execute();
}
}

if (!function_exists('detectar_tipo_operacao_request')) {
function detectar_tipo_operacao_request() {
    $metodo = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
    $action = trim((string)($_POST['action'] ?? $_GET['action'] ?? ''));

    if ($action !== '') {
        $action_limpa = preg_replace('/[^a-z0-9_]+/i', '_', $action);
        return 'ACAO_' . strtoupper(trim((string)$action_limpa, '_'));
    }

    if ($metodo === 'GET') {
        return 'ACESSO_PAGINA';
    }
    if ($metodo === 'POST') {
        return 'OPERACAO_POST';
    }
    if ($metodo === 'PUT' || $metodo === 'PATCH') {
        return 'OPERACAO_ATUALIZACAO';
    }
    if ($metodo === 'DELETE') {
        return 'OPERACAO_EXCLUSAO';
    }
    return 'INTERACAO';
}
}

if (!function_exists('registrar_log_automatico_requisicao')) {
function registrar_log_automatico_requisicao($conn, $detalhes = '') {
    static $ja_registrado = false;
    if ($ja_registrado) {
        return;
    }

    $ja_registrado = true;
    $tipo_operacao = detectar_tipo_operacao_request();
    registrar_log_interacao($conn, $tipo_operacao, $detalhes);
}
}

