<?php
// Configurações do banco 
$host     = "localhost";
$port     = 3306;
$user     = "tvitec62_adm";
$password = "Gabrielito@1";
$database = "tvitec62_son";

// Criar conexão PRINCIPAL (para compatibilidade com sistema existente)
$conn = new mysqli($host, $user, $password, $database);

// Definir charset correto
$conn->set_charset("utf8mb4");

// Verificar conexão
if ($conn->connect_error) {
    die("Falha na conexão: " . $conn->connect_error);
}

// ============================================================================
// ✅ NOVA FUNÇÃO: criarConexaoBanco() - PARA PROCESSAMENTO EM BACKGROUND
// ============================================================================

/**
 * Cria uma nova conexão com o banco de dados para processamento em background
 * Esta função é necessária para o processador de emails agendados
 * @return mysqli Nova conexão com o banco de dados
 */
if (!function_exists('criarConexaoBanco')) {
    function criarConexaoBanco() {
        // Configurações do banco (mesmas do início do arquivo)
        $host = "localhost";
        $user = "tvitec62_adm";
        $password = "Gabrielito@1";
        $database = "tvitec62_son";
        
        // Criar nova conexão
        $novaConn = new mysqli($host, $user, $password, $database);
        
        // Verificar conexão
        if ($novaConn->connect_error) {
            error_log("❌ FALHA NA CRIAÇÃO DE CONEXÃO: " . $novaConn->connect_error);
            return false;
        }
        
        // Definir charset
        $novaConn->set_charset("utf8mb4");
        
        // Definir timeout maior para processamento em background
        $novaConn->query("SET SESSION wait_timeout = 600"); // 10 minutos
        $novaConn->query("SET SESSION interactive_timeout = 600");
        
        return $novaConn;
    }
}

/**
 * Função de compatibilidade - mantém conexão principal disponível
 * @deprecated Use criarConexaoBanco() para processamento em background
 */
if (!function_exists('conectarBancoDados')) {
    function conectarBancoDados() {
        global $host, $user, $password, $database;
        
        $conn = new mysqli($host, $user, $password, $database);
        if ($conn->connect_error) {
            error_log("Erro de conexão: " . $conn->connect_error);
            return false;
        }
        
        $conn->set_charset("utf8mb4");
        return $conn;
    }
}

// ============================================================================
// FUNÇÕES DE AUTENTICAÇÃO E VERIFICAÇÃO (mantidas do seu arquivo original)
// ============================================================================

/**
 * Verifica se um tenant de teste está expirado
 * @param int $tenant_id ID do tenant
 * @return bool True se expirado, False se ativo
 */
if (!function_exists('verificarTesteExpirado')) {
    function verificarTesteExpirado($tenant_id) {
        global $conn;
        
        if (!$tenant_id) return false;
        
        $stmt = $conn->prepare("
            SELECT t.data_fim, t.ativo, p.codigo
            FROM tenants t
            LEFT JOIN planos p ON t.plano_id = p.id
            WHERE t.id = ?
        ");
        $stmt->bind_param("i", $tenant_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $tenant = $result->fetch_assoc();
            
            // Verifica se é um plano de teste
            if ($tenant['codigo'] === 'teste') {
                // Verifica se a data de expiração já passou
                if ($tenant['data_fim'] && strtotime($tenant['data_fim']) < time()) {
                    // Bloqueia o tenant
                    $stmt_update = $conn->prepare("UPDATE tenants SET ativo = 0 WHERE id = ?");
                    $stmt_update->bind_param("i", $tenant_id);
                    $stmt_update->execute();
                    $stmt_update->close();
                    
                    // Bloqueia todos os usuários do tenant
                    $stmt_users = $conn->prepare("UPDATE usuarios SET ativo = 'nao' WHERE tenant_id = ?");
                    $stmt_users->bind_param("i", $tenant_id);
                    $stmt_users->execute();
                    $stmt_users->close();
                    
                    return true; // Teste expirado
                }
            }
        }
        
        $stmt->close();
        return false; // Teste ativo ou não é um tenant de teste
    }
}

/**
 * Verifica se um usuário tem acesso ao sistema
 * @param int $usuario_id ID do usuário
 * @return bool True se tem acesso, False se bloqueado
 */
if (!function_exists('verificarAcessoUsuario')) {
    function verificarAcessoUsuario($usuario_id) {
        global $conn;
        
        if (!$usuario_id) {
            error_log("verificarAcessoUsuario: ID vazio");
            return false;
        }
        
        $stmt = $conn->prepare("
            SELECT u.tenant_id, t.ativo, t.data_fim, p.codigo
            FROM usuarios u
            JOIN tenants t ON u.tenant_id = t.id
            LEFT JOIN planos p ON t.plano_id = p.id
            WHERE u.id = ? AND u.ativo = 'sim'
        ");
        
        if (!$stmt) {
            error_log("Erro no prepare: " . $conn->error);
            return false;
        }
        
        $stmt->bind_param("i", $usuario_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $dados = $result->fetch_assoc();
            
            // Verifica se tenant está ativo
            if ($dados['ativo'] != 1) {
                error_log("Tenant inativo para usuário: " . $usuario_id);
                $stmt->close();
                return false;
            }
            
            // Verifica se é plano de teste e se expirou
            if ($dados['codigo'] === 'teste') {
                // Verifica se está expirado
                if ($dados['data_fim'] && strtotime($dados['data_fim']) < time()) {
                    error_log("Teste expirado para usuário: " . $usuario_id);
                    $stmt->close();
                    return false;
                }
            }
            
            $stmt->close();
            error_log("Acesso permitido para usuário: " . $usuario_id);
            return true;
        }
        
        error_log("Usuário não encontrado ou inativo: " . $usuario_id);
        $stmt->close();
        return false;
    }
}

/**
 * Verifica autenticação do usuário (compatível com ambas estruturas de sessão)
 * @return array Dados do usuário ou array vazio se não autenticado
 */
if (!function_exists('obterUsuarioAutenticado')) {
    function obterUsuarioAutenticado() {
        // Verifica se a sessão já foi iniciada
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        
        // PRIMEIRO: Verifica estrutura NOVA (array usuario)
        if (isset($_SESSION['usuario']) && is_array($_SESSION['usuario']) && !empty($_SESSION['usuario']['id'])) {
            $usuario = $_SESSION['usuario'];
            
            // Verifica acesso
            if (isset($usuario['id']) && !verificarAcessoUsuario($usuario['id'])) {
                session_destroy();
                return [];
            }
            
            return $usuario;
        }
        
        // SEGUNDO: Verifica estrutura antiga (campos separados) - CORREÇÃO APLICADA AQUI
        if (isset($_SESSION['logado']) && $_SESSION['logado'] === true && isset($_SESSION['usuario_id'])) {
            $usuario = [
                'id' => $_SESSION['usuario_id'] ?? 0, // CORREÇÃO: era $_SESSION['id']
                'nome' => $_SESSION['nome_usuario'] ?? '',
                'email' => $_SESSION['email_usuario'] ?? '',
                'permissao' => $_SESSION['permissao'] ?? '',
                'tenant_id' => $_SESSION['tenant_id'] ?? 0,
                'foto_perfil' => $_SESSION['foto_perfil'] ?? '',
                'tenant_nome' => $_SESSION['tenant_nome'] ?? '',
                'tenant_ativo' => $_SESSION['tenant_ativo'] ?? 0,
                'plano_codigo' => $_SESSION['plano_codigo'] ?? ''
            ];
            
            // Verifica acesso
            if (!verificarAcessoUsuario($usuario['id'])) {
                session_destroy();
                return [];
            }
            
            return $usuario;
        }
        
        return []; // Não autenticado
    }
}

/**
 * Middleware de autenticação - deve ser chamado no início de páginas protegidas
 * @param bool $redirect Se true, redireciona para login automaticamente
 * @return array Dados do usuário autenticado
 */
if (!function_exists('requererAutenticacao')) {
    function requererAutenticacao($redirect = true) {
        $usuario = obterUsuarioAutenticado();
        
        if (empty($usuario) && $redirect) {
            // Limpa buffer de saída para evitar erros de headers
            while (ob_get_level() > 0) {
                ob_end_clean();
            }
            header("Location: login.php");
            exit();
        }
        
        return $usuario;
    }
}

/**
 * Verifica se o usuário atual é super admin
 * @return bool True se for super admin
 */
if (!function_exists('isSuperAdmin')) {
    function isSuperAdmin() {
        $usuario = obterUsuarioAutenticado();
        
        if (empty($usuario)) return false;
        
        // Verifica ambas as estruturas possíveis
        $permissao = $usuario['permissao'] ?? '';
        return ($permissao === 'super_admin');
    }
}

/**
 * Verifica se o usuário atual tem permissão de administrador
 * @return bool True se for admin ou super admin
 */
if (!function_exists('isAdmin')) {
    function isAdmin() {
        $usuario = obterUsuarioAutenticado();
        
        if (empty($usuario)) return false;
        
        $permissao = $usuario['permissao'] ?? '';
        return ($permissao === 'admin' || $permissao === 'super_admin');
    }
}

/**
 * Verifica permissão para acessar recursos do tenant
 * @param int $tenant_id ID do tenant a verificar
 * @return bool True se tem permissão
 */
if (!function_exists('verificarPermissaoTenant')) {
    function verificarPermissaoTenant($tenant_id) {
        $usuario = obterUsuarioAutenticado();
        
        if (empty($usuario)) return false;
        
        // Super admin tem acesso a todos
        if (isSuperAdmin()) return true;
        
        // Verifica se o usuário pertence ao tenant
        $user_tenant_id = $usuario['tenant_id'] ?? 0;
        return ($user_tenant_id == $tenant_id);
    }
}

/**
 * Verifica se o usuário pode visualizar todos os clientes
 * @return bool True se pode ver todos os clientes
 */
if (!function_exists('podeVerTodosClientes')) {
    function podeVerTodosClientes() {
        global $conn;
        
        $usuario = obterUsuarioAutenticado();
        
        if (empty($usuario)) return false;
        
        // Super admin sempre pode
        if (isSuperAdmin()) return true;
        
        // Verifica configuração específica do usuário
        $user_id = $usuario['id'] ?? 0;
        $stmt = $conn->prepare("SELECT ver_todos_clientes FROM usuarios WHERE id = ?");
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $dados = $result->fetch_assoc();
            return ($dados['ver_todos_clientes'] == 1);
        }
        
        return false;
    }
}

/**
 * Obtém informações do tenant atual do usuário
 * @return array Dados do tenant
 */
if (!function_exists('obterTenantAtual')) {
    function obterTenantAtual() {
        global $conn;
        
        $usuario = obterUsuarioAutenticado();
        
        if (empty($usuario) || empty($usuario['tenant_id'])) {
            return [];
        }
        
        $tenant_id = $usuario['tenant_id'];
        $stmt = $conn->prepare("
            SELECT t.*, p.nome as plano_nome, p.codigo as plano_codigo,
                   DATEDIFF(t.data_fim, CURDATE()) as dias_restantes
            FROM tenants t
            JOIN planos p ON t.plano_id = p.id
            WHERE t.id = ?
        ");
        $stmt->bind_param("i", $tenant_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            return $result->fetch_assoc();
        }
        
        return [];
    }
}

/**
 * Verifica se o tenant atual está em período de teste
 * @return bool True se for teste
 */
if (!function_exists('isTenantTeste')) {
    function isTenantTeste() {
        $tenant = obterTenantAtual();
        return (!empty($tenant) && $tenant['plano_codigo'] === 'teste');
    }
}

/**
 * Obtém dias restantes para tenant de teste
 * @return int Dias restantes ou null se não for teste
 */
if (!function_exists('obterDiasRestantesTeste')) {
    function obterDiasRestantesTeste() {
        $tenant = obterTenantAtual();
        
        if (!empty($tenant) && $tenant['plano_codigo'] === 'teste') {
            return $tenant['dias_restantes'] ?? null;
        }
        
        return null;
    }
}

/**
 * Log de ações no sistema
 * @param string $acao Descrição da ação
 * @param string $tipo Tipo da ação (cliente, produto, sistema, etc.)
 * @param int $objeto_id ID do objeto relacionado
 * @param string $detalhes Detalhes adicionais
 * @return bool Sucesso da operação
 */
if (!function_exists('registrarLog')) {
    function registrarLog($acao, $tipo = 'sistema', $objeto_id = null, $detalhes = '') {
        global $conn;
        
        $usuario = obterUsuarioAutenticado();
        $usuario_id = $usuario['id'] ?? 0;
        $tenant_id = $usuario['tenant_id'] ?? 0;
        
        $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        
        $stmt = $conn->prepare("
            INSERT INTO logs_sistema 
            (usuario_id, tenant_id, acao, tipo, objeto_id, detalhes, ip, user_agent) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $stmt->bind_param(
            "iississs",
            $usuario_id,
            $tenant_id,
            $acao,
            $tipo,
            $objeto_id,
            $detalhes,
            $ip,
            $user_agent
        );
        
        $result = $stmt->execute();
        $stmt->close();
        
        return $result;
    }
}

/**
 * Cria a tabela de logs do sistema se não existir
 */
if (!function_exists('criarTabelaLogs')) {
    function criarTabelaLogs() {
        global $conn;
        
        $sql = "
        CREATE TABLE IF NOT EXISTS logs_sistema (
            id INT(11) NOT NULL AUTO_INCREMENT,
            usuario_id INT(11) DEFAULT NULL,
            tenant_id INT(11) DEFAULT NULL,
            acao VARCHAR(255) NOT NULL,
            tipo VARCHAR(50) DEFAULT 'sistema',
            objeto_id INT(11) DEFAULT NULL,
            detalhes TEXT,
            ip VARCHAR(45) DEFAULT NULL,
            user_agent TEXT,
            data_hora TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY idx_usuario (usuario_id),
            KEY idx_tenant (tenant_id),
            KEY idx_tipo (tipo),
            KEY idx_data_hora (data_hora)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
        ";
        
        $conn->query($sql);
    }
}

/**
 * Cria o plano de teste se não existir
 */
if (!function_exists('criarPlanoTeste')) {
    function criarPlanoTeste() {
        global $conn;
        
        // Verifica se o plano de teste já existe
        $result = $conn->query("SELECT id FROM planos WHERE codigo = 'teste'");
        
        if ($result->num_rows == 0) {
            $sql = "
            INSERT INTO planos 
            (id, nome, max_usuarios, valor, permite_georreferenciada, permite_chat, 
             permite_fluxos, permite_email_marketing, permite_formularios, max_armazenamento_mb, codigo) 
            VALUES 
            (99, 'Plano Teste 10 Dias', 1, 0.00, 1, 1, 1, 1, 1, 100, 'teste')
            ";
            
            $conn->query($sql);
        }
    }
}

/**
 * Verifica quota de armazenamento do tenant
 * @param int $tenant_id ID do tenant
 * @return array Dados da quota
 */
if (!function_exists('verificarQuotaTenant')) {
    function verificarQuotaTenant($tenant_id) {
        global $conn;
        
        $stmt = $conn->prepare("
            SELECT 
                quota_total_mb,
                espaco_utilizado_total_mb,
                (quota_total_mb - espaco_utilizado_total_mb) as espaco_disponivel_mb,
                ROUND((espaco_utilizado_total_mb / quota_total_mb) * 100, 2) as percentual_uso
            FROM tenants 
            WHERE id = ?
        ");
        $stmt->bind_param("i", $tenant_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            return $result->fetch_assoc();
        }
        
        return [
            'quota_total_mb' => 0,
            'espaco_utilizado_total_mb' => 0,
            'espaco_disponivel_mb' => 0,
            'percentual_uso' => 0
        ];
    }
}

/**
 * Verifica se pode fazer upload considerando a quota
 * @param int $tenant_id ID do tenant
 * @param int $tamanho_bytes Tamanho do arquivo em bytes
 * @return array Resultado da verificação
 */
if (!function_exists('podeFazerUpload')) {
    function podeFazerUpload($tenant_id, $tamanho_bytes) {
        $quota = verificarQuotaTenant($tenant_id);
        $tamanho_mb = $tamanho_bytes / 1048576; // Converte bytes para MB
        
        $espaco_disponivel = $quota['espaco_disponivel_mb'] ?? 0;
        
        return [
            'pode' => ($tamanho_mb <= $espaco_disponivel),
            'espaco_disponivel' => $espaco_disponivel,
            'tamanho_arquivo_mb' => $tamanho_mb,
            'mensagem' => ($tamanho_mb <= $espaco_disponivel) 
                ? '' 
                : "Espaço insuficiente. Disponível: " . number_format($espaco_disponivel, 2) . "MB, Necessário: " . number_format($tamanho_mb, 2) . "MB"
        ];
    }
}

/**
 * Sanitiza dados de entrada
 * @param mixed $dados Dados a serem sanitizados
 * @param string $tipo Tipo de sanitização (string, int, email, etc.)
 * @return mixed Dados sanitizados
 */
if (!function_exists('sanitizar')) {
    function sanitizar($dados, $tipo = 'string') {
        if (is_array($dados)) {
            foreach ($dados as $key => $value) {
                $dados[$key] = sanitizar($value, $tipo);
            }
            return $dados;
        }
        
        switch ($tipo) {
            case 'int':
                return (int) filter_var($dados, FILTER_SANITIZE_NUMBER_INT);
            case 'float':
                return (float) filter_var($dados, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
            case 'email':
                return filter_var(trim($dados), FILTER_SANITIZE_EMAIL);
            case 'url':
                return filter_var(trim($dados), FILTER_SANITIZE_URL);
            case 'string':
            default:
                return htmlspecialchars(trim($dados), ENT_QUOTES, 'UTF-8');
        }
    }
}

/**
 * Valida CPF
 * @param string $cpf CPF a ser validado
 * @return bool True se válido
 */
if (!function_exists('validarCPF')) {
    function validarCPF($cpf) {
        $cpf = preg_replace('/[^0-9]/', '', $cpf);
        
        if (strlen($cpf) != 11 || preg_match('/(\d)\1{10}/', $cpf)) {
            return false;
        }
        
        // Cálculo dos dígitos verificadores
        for ($t = 9; $t < 11; $t++) {
            $d = 0;
            for ($c = 0; $c < $t; $c++) {
                $d += $cpf[$c] * (($t + 1) - $c);
            }
            $d = ((10 * $d) % 11) % 10;
            if ($cpf[$c] != $d) {
                return false;
            }
        }
        
        return true;
    }
}

/**
 * Valida CNPJ
 * @param string $cnpj CNPJ a ser validado
 * @return bool True se válido
 */
if (!function_exists('validarCNPJ')) {
    function validarCNPJ($cnpj) {
        $cnpj = preg_replace('/[^0-9]/', '', $cnpj);
        
        if (strlen($cnpj) != 14) {
            return false;
        }
        
        // Cálculo dos dígitos verificadores
        for ($t = 12; $t < 14; $t++) {
            $d = 0;
            $pos = $t - 7;
            for ($c = 0; $c < $t; $c++) {
                $d += $cnpj[$c] * $pos--;
                if ($pos < 2) {
                    $pos = 9;
                }
            }
            $d = ((10 * $d) % 11) % 10;
            if ($cnpj[$c] != $d) {
                return false;
            }
        }
        
        return true;
    }
}

/**
 * Formata CPF/CNPJ
 * @param string $documento Documento a ser formatado
 * @return string Documento formatado
 */
if (!function_exists('formatarDocumento')) {
    function formatarDocumento($documento) {
        $documento = preg_replace('/[^0-9]/', '', $documento);
        
        if (strlen($documento) == 11) {
            return preg_replace('/(\d{3})(\d{3})(\d{3})(\d{2})/', '$1.$2.$3-$4', $documento);
        } elseif (strlen($documento) == 14) {
            return preg_replace('/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/', '$1.$2.$3/$4-$5', $documento);
        }
        
        return $documento;
    }
}

/**
 * Formata telefone
 * @param string $telefone Telefone a ser formatado
 * @return string Telefone formatado
 */
if (!function_exists('formatarTelefone')) {
    function formatarTelefone($telefone) {
        $telefone = preg_replace('/[^0-9]/', '', $telefone);
        
        if (strlen($telefone) == 10) {
            return preg_replace('/(\d{2})(\d{4})(\d{4})/', '($1) $2-$3', $telefone);
        } elseif (strlen($telefone) == 11) {
            return preg_replace('/(\d{2})(\d{5})(\d{4})/', '($1) $2-$3', $telefone);
        }
        
        return $telefone;
    }
}

/**
 * Inicialização do sistema
 * Cria tabelas necessárias e configurações básicas
 */
if (!function_exists('inicializarSistema')) {
    function inicializarSistema() {
        criarTabelaLogs();
        criarPlanoTeste();
        
        // Registra log de inicialização (apenas se houver usuário logado)
        if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION['logado']) && $_SESSION['logado'] === true) {
            registrarLog('Sistema inicializado', 'sistema');
        }
    }
}

// Inicializa o sistema automaticamente (apenas em modos que não afetam sessão)
if (php_sapi_name() !== 'cli') {
    // Verifica se não estamos em uma requisição que requer sessão
    $script_name = basename($_SERVER['SCRIPT_NAME']);
    $scripts_sem_sessao = ['login.php', 'cadastro_teste.php', 'recuperar_senha.php'];
    
    if (!in_array($script_name, $scripts_sem_sessao)) {
        // Verifica se a função já foi chamada
        if (!defined('SISTEMA_INICIALIZADO')) {
            define('SISTEMA_INICIALIZADO', true);
            inicializarSistema();
        }
    }
}