<?php
/**
 * Endpoint público para tracking de eventos
 * Não requer autenticação - usado pelo frontend
 * Timezone: America/Sao_Paulo
 */

date_default_timezone_set('America/Sao_Paulo');

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

// Handle preflight request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit(0);
}

// Apenas POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
    exit;
}

/**
 * Função para obter geolocalização do IP
 * Usa a API gratuita ip-api.com
 */
function getGeoLocation($ip) {
    // IPs locais não têm geolocalização
    if ($ip === '127.0.0.1' || $ip === '::1' || strpos($ip, '192.168.') === 0 || strpos($ip, '10.') === 0) {
        return [
            'city' => 'Local',
            'region' => 'Local',
            'country' => 'BR',
            'isp' => 'Local Network'
        ];
    }
    
    try {
        $url = "http://ip-api.com/json/{$ip}?fields=status,message,country,countryCode,region,regionName,city,isp&lang=pt-BR";
        
        $context = stream_context_create([
            'http' => [
                'timeout' => 2, // 2 segundos de timeout
                'ignore_errors' => true
            ]
        ]);
        
        $response = @file_get_contents($url, false, $context);
        
        if ($response) {
            $data = json_decode($response, true);
            if ($data && isset($data['status']) && $data['status'] === 'success') {
                return [
                    'city' => $data['city'] ?? '',
                    'region' => $data['regionName'] ?? '',
                    'country' => $data['countryCode'] ?? 'BR',
                    'isp' => $data['isp'] ?? ''
                ];
            }
        }
    } catch (Exception $e) {
        // Silenciar erros de geolocalização
    }
    
    return [
        'city' => '',
        'region' => '',
        'country' => '',
        'isp' => ''
    ];
}

try {
    // --- Database Connection ---
    $dbPath = __DIR__ . '/admin/admin.db';
    $pdo = new PDO('sqlite:' . $dbPath);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Configurações para evitar perda de dados com tráfego médio/alto
    $pdo->exec('PRAGMA journal_mode = WAL');
    $pdo->exec('PRAGMA busy_timeout = 10000');
    $pdo->exec('PRAGMA synchronous = NORMAL');
    $pdo->exec('PRAGMA cache_size = -64000');
    $pdo->exec('PRAGMA temp_store = MEMORY');

    // --- Create Table If Not Exists (com novas colunas de geolocalização) ---
    $pdo->exec("CREATE TABLE IF NOT EXISTS events (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        event_type TEXT NOT NULL,
        ip_address TEXT,
        user_agent TEXT,
        event_timestamp DATETIME DEFAULT (datetime('now', 'localtime')),
        metadata TEXT,
        utm_source TEXT,
        utm_medium TEXT,
        utm_campaign TEXT,
        placa TEXT,
        renavam TEXT,
        valor REAL,
        geo_city TEXT,
        geo_region TEXT,
        geo_country TEXT,
        geo_isp TEXT
    )");
    
    // Adicionar colunas se não existirem (para DBs existentes)
    try { $pdo->exec("ALTER TABLE events ADD COLUMN placa TEXT"); } catch (Exception $e) {}
    try { $pdo->exec("ALTER TABLE events ADD COLUMN renavam TEXT"); } catch (Exception $e) {}
    try { $pdo->exec("ALTER TABLE events ADD COLUMN valor REAL"); } catch (Exception $e) {}
    try { $pdo->exec("ALTER TABLE events ADD COLUMN geo_city TEXT"); } catch (Exception $e) {}
    try { $pdo->exec("ALTER TABLE events ADD COLUMN geo_region TEXT"); } catch (Exception $e) {}
    try { $pdo->exec("ALTER TABLE events ADD COLUMN geo_country TEXT"); } catch (Exception $e) {}
    try { $pdo->exec("ALTER TABLE events ADD COLUMN geo_isp TEXT"); } catch (Exception $e) {}
    
    // Criar índices para melhorar performance das consultas
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type)");
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(event_timestamp)");
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_events_placa ON events(placa)");

    // --- Process Request ---
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);

    if (json_last_error() !== JSON_ERROR_NONE || !isset($data['action'])) {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => 'Invalid input']);
        exit;
    }

    // --- Prepare Data ---
    $eventType = $data['action'];
    $metadata = isset($data['metadata']) ? $data['metadata'] : [];
    $utm = isset($metadata['utm']) ? $metadata['utm'] : [];

    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
    
    // Obter geolocalização do IP
    $geo = getGeoLocation($ip);
    
    // Extrair placa e renavam dos metadados ou do objeto veiculo
    $placa = $metadata['placa'] ?? $metadata['veiculo']['placa'] ?? null;
    $renavam = $metadata['renavam'] ?? $metadata['veiculo']['renavam'] ?? null;
    
    // Extrair valor
    $valor = null;
    if (isset($metadata['valor'])) {
        $valor = floatval($metadata['valor']);
    } elseif (isset($metadata['value'])) {
        $valor = floatval($metadata['value']);
    } elseif (isset($metadata['amount'])) {
        $valor = floatval($metadata['amount']);
    }
    
    // Adicionar geolocalização aos metadados para referência
    $metadata['geo'] = $geo;
    $metadata['tracked_at_sp'] = date('Y-m-d H:i:s'); // Hora de SP

    // --- Rate Limiting básico (por IP) ---
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM events WHERE ip_address = ? AND event_timestamp > datetime('now', 'localtime', '-1 minute')");
    $stmt->execute([$ip]);
    $recentCount = $stmt->fetchColumn();
    
    if ($recentCount > 30) {
        http_response_code(429);
        echo json_encode(['status' => 'error', 'message' => 'Too many requests']);
        exit;
    }
    
    // --- Verificar se é evento de visita duplicada (mesmo IP) ---
    // Para eventos de visita (visit, page_view, page_load), só registra se o IP ainda não visitou
    $visitTypes = ['visit', 'page_view', 'page_load'];
    if (in_array($eventType, $visitTypes)) {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM events WHERE event_type IN ('visit', 'page_view', 'page_load') AND ip_address = ?");
        $stmt->execute([$ip]);
        $existingVisits = $stmt->fetchColumn();
        
        // Se já existe uma visita deste IP, não registra novamente
        if ($existingVisits > 0) {
            echo json_encode(['status' => 'success', 'message' => 'Visit already tracked for this IP', 'duplicate' => true]);
            exit;
        }
    }

    // --- Insert into Database com retry em caso de bloqueio ---
    $maxRetries = 3;
    $retryDelay = 100000;
    
    for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
        try {
            $stmt = $pdo->prepare(
                "INSERT INTO events (event_type, ip_address, user_agent, metadata, utm_source, utm_medium, utm_campaign, placa, renavam, valor, geo_city, geo_region, geo_country, geo_isp, event_timestamp) 
                 VALUES (:event_type, :ip_address, :user_agent, :metadata, :utm_source, :utm_medium, :utm_campaign, :placa, :renavam, :valor, :geo_city, :geo_region, :geo_country, :geo_isp, datetime('now', 'localtime'))"
            );

            $stmt->execute([
                ':event_type' => $eventType,
                ':ip_address' => $ip,
                ':user_agent' => $userAgent,
                ':metadata' => json_encode($metadata, JSON_UNESCAPED_UNICODE),
                ':utm_source' => $utm['utm_source'] ?? null,
                ':utm_medium' => $utm['utm_medium'] ?? null,
                ':utm_campaign' => $utm['utm_campaign'] ?? null,
                ':placa' => $placa,
                ':renavam' => $renavam,
                ':valor' => $valor,
                ':geo_city' => $geo['city'],
                ':geo_region' => $geo['region'],
                ':geo_country' => $geo['country'],
                ':geo_isp' => $geo['isp'],
            ]);
            
            break;
            
        } catch (PDOException $e) {
            if ($attempt === $maxRetries || strpos($e->getMessage(), 'locked') === false) {
                throw $e;
            }
            usleep($retryDelay * $attempt);
        }
    }

    echo json_encode(['status' => 'success', 'message' => 'Event tracked', 'timestamp_sp' => date('Y-m-d H:i:s')]);

} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Server error']);
}
?>
