<?php
/**
 * SISTEMA DE PROTEÇÃO ANTI-CLONE
 * Adicione este arquivo e configure no chat.php
 */

// ==================== CONFIGURAÇÕES ====================
// Domínios autorizados (ADICIONE SEUS DOMÍNIOS AQUI)
define('DOMINIOS_AUTORIZADOS', [
    'checkout-carlinhosmaia.com',
    'www.checkout-carlinhosmaia.com',
    'carlinhosmaia.com',
    'www.carlinhosmaia.com',
    'localhost',
    '127.0.0.1'
]);

// Chave secreta para tokens (MUDE PARA UMA CHAVE ÚNICA)
define('CHAVE_SECRETA', 'chave-secreta12@' . date('Y-m'));

// IPs bloqueados (adicione IPs de bots/scrapers conhecidos)
define('IPS_BLOQUEADOS', [
    // Adicione IPs maliciosos aqui
]);

// ==================== FUNÇÕES DE PROTEÇÃO ====================

/**
 * Verifica se o domínio é autorizado
 */
function verificarDominio() {
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    $referer = $_SERVER['HTTP_REFERER'] ?? '';
    $host = $_SERVER['HTTP_HOST'] ?? '';
    
    // Extrai domínio do origin ou referer
    $dominioOrigin = parse_url($origin, PHP_URL_HOST) ?? '';
    $dominioReferer = parse_url($referer, PHP_URL_HOST) ?? '';
    
    // Verifica se algum dos domínios é autorizado
    foreach (DOMINIOS_AUTORIZADOS as $autorizado) {
        if (
            strpos($dominioOrigin, $autorizado) !== false ||
            strpos($dominioReferer, $autorizado) !== false ||
            strpos($host, $autorizado) !== false
        ) {
            return true;
        }
    }
    
    // Log de tentativa não autorizada
    logTentativa('dominio_invalido', [
        'origin' => $origin,
        'referer' => $referer,
        'host' => $host,
        'ip' => getClientIP()
    ]);
    
    return false;
}

/**
 * Verifica se o IP está bloqueado
 */
function verificarIP() {
    $ip = getClientIP();
    
    if (in_array($ip, IPS_BLOQUEADOS)) {
        logTentativa('ip_bloqueado', ['ip' => $ip]);
        return false;
    }
    
    return true;
}

/**
 * Gera um token de sessão seguro
 */
function gerarToken($dados = []) {
    $payload = [
        'timestamp' => time(),
        'ip' => getClientIP(),
        'ua' => $_SERVER['HTTP_USER_AGENT'] ?? '',
        'dados' => $dados,
        'random' => bin2hex(random_bytes(16))
    ];
    
    $payloadJson = json_encode($payload);
    $payloadBase64 = base64_encode($payloadJson);
    $assinatura = hash_hmac('sha256', $payloadBase64, CHAVE_SECRETA);
    
    return $payloadBase64 . '.' . $assinatura;
}

/**
 * Valida um token
 */
function validarToken($token, $maxIdade = 3600) {
    if (empty($token)) return false;
    
    $partes = explode('.', $token);
    if (count($partes) !== 2) return false;
    
    list($payloadBase64, $assinatura) = $partes;
    
    // Verifica assinatura
    $assinaturaEsperada = hash_hmac('sha256', $payloadBase64, CHAVE_SECRETA);
    if (!hash_equals($assinaturaEsperada, $assinatura)) {
        logTentativa('token_invalido', ['token' => substr($token, 0, 50)]);
        return false;
    }
    
    // Decodifica payload
    $payloadJson = base64_decode($payloadBase64);
    $payload = json_decode($payloadJson, true);
    
    if (!$payload) return false;
    
    // Verifica idade do token
    if (time() - ($payload['timestamp'] ?? 0) > $maxIdade) {
        return false;
    }
    
    // Verifica IP (opcional - pode causar problemas com IPs dinâmicos)
    // if (($payload['ip'] ?? '') !== getClientIP()) return false;
    
    return $payload;
}

/**
 * Obtém IP real do cliente
 */
function getClientIP() {
    $headers = [
        'HTTP_CF_CONNECTING_IP', // Cloudflare
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR'
    ];
    
    foreach ($headers as $header) {
        if (!empty($_SERVER[$header])) {
            $ip = $_SERVER[$header];
            // Pega primeiro IP se houver múltiplos
            if (strpos($ip, ',') !== false) {
                $ip = trim(explode(',', $ip)[0]);
            }
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }
    
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

/**
 * Rate limiting - limita requisições por IP
 */
function verificarRateLimit($limite = 60, $janela = 60) {
    $ip = getClientIP();
    $arquivo = sys_get_temp_dir() . '/rate_limit_' . md5($ip) . '.json';
    
    $dados = [];
    if (file_exists($arquivo)) {
        $dados = json_decode(file_get_contents($arquivo), true) ?? [];
    }
    
    $agora = time();
    
    // Remove requisições antigas
    $dados = array_filter($dados, function($timestamp) use ($agora, $janela) {
        return ($agora - $timestamp) < $janela;
    });
    
    // Verifica limite
    if (count($dados) >= $limite) {
        logTentativa('rate_limit', ['ip' => $ip, 'count' => count($dados)]);
        return false;
    }
    
    // Adiciona nova requisição
    $dados[] = $agora;
    file_put_contents($arquivo, json_encode($dados));
    
    return true;
}

/**
 * Detecta bots/scrapers
 */
function detectarBot() {
    $ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
    
    $bots = [
        'bot', 'crawler', 'spider', 'scraper', 'curl', 'wget',
        'python', 'java', 'perl', 'ruby', 'go-http', 'httpclient',
        'postman', 'insomnia', 'axios', 'fetch', 'node-fetch',
        'phantomjs', 'headless', 'selenium', 'puppeteer', 'playwright'
    ];
    
    foreach ($bots as $bot) {
        if (strpos($ua, $bot) !== false) {
            // Permite alguns bots legítimos (Google, etc)
            if (strpos($ua, 'googlebot') !== false) continue;
            if (strpos($ua, 'bingbot') !== false) continue;
            
            logTentativa('bot_detectado', ['ua' => $ua, 'ip' => getClientIP()]);
            return true;
        }
    }
    
    // Verifica se tem User-Agent
    if (empty($ua)) {
        logTentativa('sem_user_agent', ['ip' => getClientIP()]);
        return true;
    }
    
    return false;
}

/**
 * Ofusca resposta JSON (dificulta scraping)
 */
function ofuscarResposta($dados) {
    // Adiciona campos falsos para confundir scrapers
    $dados['_t'] = time();
    $dados['_h'] = substr(md5(json_encode($dados) . CHAVE_SECRETA), 0, 8);
    
    return $dados;
}

/**
 * Log de tentativas suspeitas
 */
function logTentativa($tipo, $dados = []) {
    $logDir = __DIR__ . '/logs';
    if (!is_dir($logDir)) {
        mkdir($logDir, 0755, true);
    }
    
    $logFile = $logDir . '/security_' . date('Y-m-d') . '.log';
    
    $entry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'tipo' => $tipo,
        'ip' => getClientIP(),
        'dados' => $dados
    ];
    
    file_put_contents($logFile, json_encode($entry) . "\n", FILE_APPEND | LOCK_EX);
}

/**
 * Headers de segurança
 */
function setSecurityHeaders() {
    // Previne embedding em iframes de outros sites
    header('X-Frame-Options: SAMEORIGIN');
    
    // Previne sniffing de MIME type
    header('X-Content-Type-Options: nosniff');
    
    // XSS Protection
    header('X-XSS-Protection: 1; mode=block');
    
    // Referrer Policy
    header('Referrer-Policy: strict-origin-when-cross-origin');
    
    // Content Security Policy (ajuste conforme necessário)
    // header("Content-Security-Policy: default-src 'self'");
}

/**
 * Middleware principal de proteção
 * Chame esta função no início da sua API
 */
function protegerAPI($opcoes = []) {
    $opcoes = array_merge([
        'verificar_dominio' => true,
        'verificar_ip' => true,
        'verificar_rate_limit' => true,
        'detectar_bot' => true,
        'limite_requisicoes' => 100,
        'janela_segundos' => 60
    ], $opcoes);
    
    setSecurityHeaders();
    
    // Verifica IP bloqueado
    if ($opcoes['verificar_ip'] && !verificarIP()) {
        http_response_code(403);
        die(json_encode(['error' => 'Acesso negado']));
    }
    
    // Verifica domínio
    if ($opcoes['verificar_dominio'] && !verificarDominio()) {
        http_response_code(403);
        die(json_encode(['error' => 'Origem não autorizada']));
    }
    
    // Rate limiting
    if ($opcoes['verificar_rate_limit'] && !verificarRateLimit($opcoes['limite_requisicoes'], $opcoes['janela_segundos'])) {
        http_response_code(429);
        die(json_encode(['error' => 'Muitas requisições. Tente novamente mais tarde.']));
    }
    
    // Detecta bots
    if ($opcoes['detectar_bot'] && detectarBot()) {
        http_response_code(403);
        die(json_encode(['error' => 'Acesso negado']));
    }
    
    return true;
}

// ==================== PROTEÇÃO DO CÓDIGO JS ====================

/**
 * Gera código JS protegido/ofuscado
 */
function gerarJSProtegido($apiUrl) {
    $token = gerarToken(['tipo' => 'widget']);
    $timestamp = time();
    $hash = substr(md5($timestamp . CHAVE_SECRETA), 0, 16);
    
    // Código minificado e com verificações
    $js = <<<JS
(function(){
    var _0x={
        t:'$token',
        ts:$timestamp,
        h:'$hash',
        api:'$apiUrl'
    };
    
    // Verifica se está no domínio correto
    var _d=window.location.hostname;
    var _a=['checkout-carlinhosmaia.com','carlinhosmaia.com','localhost'];
    var _v=false;
    for(var i=0;i<_a.length;i++){if(_d.indexOf(_a[i])!==-1){_v=true;break;}}
    if(!_v){console.error('Domínio não autorizado');return;}
    
    // Anti-DevTools (básico)
    var _c=0;
    setInterval(function(){
        var s=new Date();
        debugger;
        if(new Date()-s>100){_c++;if(_c>3){document.body.innerHTML='';}}
    },1000);
    
    // Desabilita clique direito no widget
    document.addEventListener('contextmenu',function(e){
        if(e.target.closest('.cm-chat-trigger,.cm-chat-window')){e.preventDefault();}
    });
    
    // Adiciona token em todas as requisições
    window._chatToken=_0x.t;
})();
JS;
    
    return $js;
}