<?php
declare(strict_types=1);

error_reporting(E_ALL);
ini_set('display_errors','1');
ini_set('log_errors','1');
ini_set('error_log', __DIR__ . '/../logs/php_errors.log');

header('Content-Type: application/json; charset=utf-8');

/* === Anti-cache forte (browser, proxy e CDN) === */
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');
header('Surrogate-Control: no-store');
header('X-Accel-Expires: 0'); // Nginx (se houver)

// ✅ ATIVE LOGS DETALHADOS
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('log_errors', '1');
ini_set('error_log', __DIR__ . '/../logs/php_errors.log');

// ✅ Crie o diretório de logs se não existir
if (!is_dir(__DIR__ . '/../logs')) {
    mkdir(__DIR__ . '/../logs', 0755, true);
}

header('Content-Type: application/json; charset=utf-8');

// ✅ LOG INICIAL DETALHADO
error_log("🎰 SPIN.PHP INICIADO - Time: " . date('Y-m-d H:i:s'));
error_log("🎰 _POST: " . print_r($_POST, true));
error_log("🎰 _GET: " . print_r($_GET, true));

require_once __DIR__.'/../inc/spin_lib.php';

// ✅ LOG DE VERIFICAÇÃO DO PDO
error_log("🎰 PDO Status: " . ($pdo instanceof PDO ? 'Conectado' : 'Não conectado'));

try {
  $debugMode = isset($_GET['debug']) || isset($_POST['debug']);

  $idOrSlug = $_GET['roleta'] ?? $_POST['roleta'] ?? $_GET['roulette_id'] ?? $_POST['roulette_id'] ?? null;
  if (!$idOrSlug) {
    error_log("❌ Parâmetro 'roleta' não encontrado");
    http_response_code(400);
    echo json_encode(['ok'=>false,'message'=>"Informe 'roleta' (id ou slug)."]);
    exit;
  }

  // ✅ LOG DA ROLETA
  error_log("🎰 SPIN - Buscando roleta: " . $idOrSlug);

  try {
    $r = getRoulette($pdo, (string)$idOrSlug);
  } catch (Exception $e) {
    error_log("❌ ERRO getRoulette: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok'=>false,'message'=>'Erro ao buscar roleta','detail'=>$e->getMessage()]);
    exit;
  }

  if (!$r) {
    error_log("❌ Roleta não encontrada: " . $idOrSlug);
    http_response_code(404);
    echo json_encode(['ok'=>false,'message'=>'Roleta não encontrada ou inativa.']);
    exit;
  }

  $rouletteId = (int)$r['id'];
  $ipHash = ip_hash(client_ip());

  // ✅ VERIFICAÇÕES DE SEGURANÇA EM CASCATA
  error_log("🔒 VERIFICAÇÃO DE SEGURANÇA - IP: " . client_ip() . " | Hash: " . $ipHash . " | Roleta: " . $rouletteId);

  // 1. Verifica se IP está bloqueado
  if (isIpBlocked($pdo, $ipHash, $rouletteId)) {
    error_log("🚫 IP bloqueado tentou acessar roleta: " . $ipHash);
    http_response_code(403);
    echo json_encode([
      'ok' => false,
      'code' => 'ip_blocked',
      'message' => 'Acesso bloqueado temporariamente.'
    ]);
    exit;
  }

  // 2. Detecção de padrões suspeitos
  $suspiciousCheck = detectSuspiciousPattern($pdo, $ipHash, $rouletteId);
  if ($suspiciousCheck['suspicious']) {
    error_log("🚫 Padrão suspeito detectado: " . implode(', ', $suspiciousCheck['reasons']));
    
    // Bloqueia temporariamente (15 minutos)
    $blockUntil = date('Y-m-d H:i:s', time() + 900); // 15 minutos
    $st = $pdo->prepare("INSERT INTO blocked_ips (ip_hash, roulette_id, reason, blocked_until) 
                        VALUES (?, ?, ?, ?)");
    $st->execute([$ipHash, $rouletteId, implode(', ', $suspiciousCheck['reasons']), $blockUntil]);
    
    http_response_code(429);
    echo json_encode([
      'ok' => false,
      'code' => 'suspicious_activity',
      'message' => 'Atividade suspeita detectada.',
      'retry_after' => 900
    ]);
    exit;
  }

  // 3. Rate limit rápido
  $rl = rateLimit($pdo, $rouletteId, $ipHash);
  if (!$rl['ok']) {
    error_log("❌ Rate limit rápido excedido para roleta: " . $rouletteId);
    http_response_code(429);
    echo json_encode([
      'ok' => false,
      'message' => $rl['message'],
      'retry_after' => $rl['retry_after'],
      'code' => $rl['code']
    ]);
    exit;
  }

  // 4. Verifica limites de segurança (horário, diário, de sessão)
  $limitsCheck = checkUserLimits($pdo, $rouletteId, $ipHash);
  if (!$limitsCheck['ok']) {
    error_log("❌ Limite de segurança excedido: " . $limitsCheck['code']);
    http_response_code(429);
    echo json_encode([
      'ok' => false,
      'message' => $limitsCheck['message'],
      'retry_after' => $limitsCheck['retry_after'],
      'code' => $limitsCheck['code'],
      'limit_type' => $limitsCheck['limit_type'],
      'current_count' => $limitsCheck['current_count'],
      'max_limit' => $limitsCheck['max_limit']
    ]);
    exit;
  }

  // ✅ LOG DA ROLETA ENCONTRADA
  error_log("🎰 SPIN - Roleta encontrada: ID " . $r['id'] . " - " . $r['name']);
  
  // ✅ VERIFICAÇÃO DO PADRÃO FORÇADO
  $force_pattern = (string)($r['force_pattern'] ?? 'none');
  $pattern = strtoupper(preg_replace('/[^LW]/', '', $force_pattern));
  
  error_log("🎰 SPIN - Pattern configurado: '{$force_pattern}'");
  error_log("🎰 SPIN - Pattern limpo: '{$pattern}'");

  if ($pattern === '' || $pattern === 'NONE') {
    error_log("🎰 SPIN - Usando sorteio normal (sem padrão forçado)");
  } else {
    error_log("🎰 SPIN - Aplicando padrão forçado: {$pattern}");
  }

  // ✅ LOG DOS SEGMENTOS
  try {
    $segs = getSegments($pdo, (int)$r['id']);
  } catch (Exception $e) {
    error_log("❌ ERRO getSegments: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok'=>false,'message'=>'Erro ao buscar segmentos','detail'=>$e->getMessage()]);
    exit;
  }

  if (!$segs) {
    error_log("❌ Sem segmentos configurados para roleta: " . $r['id']);
    http_response_code(500);
    echo json_encode(['ok'=>false,'message'=>'Sem segmentos configurados.']);
    exit;
  }

  error_log("🎰 SPIN - Segmentos encontrados: " . count($segs));
  foreach ($segs as $seg) {
    error_log("   → Segmento {$seg['id']}: {$seg['type']} - Peso: {$seg['weight']}");
  }

  // ✅ CORREÇÃO CRÍTICA: Calcula TODOS os spins (não apenas ACKs) antes de pickWithPattern
  try {
    $total_spins = spinCount($pdo, (int)$r['id']);
  } catch (Exception $e) {
    error_log("❌ ERRO spinCount: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok'=>false,'message'=>'Erro ao contar spins','detail'=>$e->getMessage()]);
    exit;
  }

  $dbg = [];
  $dbg['total_spins'] = $total_spins;

  // ✅ LOG DOS SPINS TOTAIS
  error_log("🎰 SPIN - Total spins count: " . $total_spins);

  // aplica padrão + coleta debug
  try {
    $chosen = pickWithPattern($pdo, (int)$r['id'], (string)($r['force_pattern'] ?? 'none'), $segs, $dbg);
  } catch (Exception $e) {
    error_log("❌ ERRO pickWithPattern: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok'=>false,'message'=>'Erro ao escolher segmento','detail'=>$e->getMessage()]);
    exit;
  }

  // índice 0-based na ordem do template
  $index = 0;
  foreach ($segs as $k => $row) { 
    if ((int)$row['id'] === (int)$chosen['id']) { 
      $index = $k; 
      break; 
    } 
  }
  
  $forced = $chosen['__forced'] ?? '';

  // ✅ DEBUG EXTENDIDO - Log completo do force_pattern
  error_log("🎯 FORCE_PATTERN RESULTADO");
  error_log("   Roleta ID: " . $r['id']);
  error_log("   Pattern: " . ($r['force_pattern'] ?? 'none'));
  error_log("   Total Spins: " . $total_spins);
  error_log("   Step Index: " . ($dbg['step_index'] ?? 'N/A'));
  error_log("   Step Char: " . ($dbg['step'] ?? 'N/A'));
  error_log("   Pattern Length: " . ($dbg['pattern_length'] ?? 'N/A'));
  error_log("   Calculation: " . ($dbg['calculation'] ?? 'N/A'));
  error_log("   Chosen ID: " . $chosen['id']);
  error_log("   Chosen Type: " . strtoupper($chosen['type']));
  error_log("   Forced: " . $forced);
  error_log("   Index: " . $index);

  // token p/ ACK
  $nonce = bin2hex(random_bytes(8));
  $hmac  = hmac_for((int)$r['id'], (int)$chosen['id'], $nonce);
  
  try {
    $spinId = logIssue($pdo, (int)$r['id'], (int)$chosen['id'], ip_hash(client_ip()), $_SERVER['HTTP_USER_AGENT']??'', $nonce, $hmac);
  } catch (Exception $e) {
    error_log("❌ ERRO logIssue: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok'=>false,'message'=>'Erro ao registrar spin','detail'=>$e->getMessage()]);
    exit;
  }

  error_log("🎰 SPIN - Spin ID gerado: " . $spinId);

  // DEBUG EXTENDIDO - Mostra informações detalhadas do sorteio
  $dbg['chosen_details'] = [
    'id'     => (int)$chosen['id'],
    'index'  => $index,
    'type'   => strtoupper((string)$chosen['type']),
    'weight' => (float)($chosen['weight'] ?? 0),
    'forced' => $forced,
    'effective_weight' => ((float)($chosen['weight'] ?? 0) <= 1) ? 0 : (float)$chosen['weight']
  ];

  $dbg['client_info'] = [
    'ip' => client_ip(),
    'ip_hash' => ip_hash(client_ip()),
    'user_agent' => substr($_SERVER['HTTP_USER_AGENT']??'', 0, 100)
  ];

  $dbg['selection_method'] = $forced ? 'forced_pattern' : 'weighted_random';

  $response = [
    'ok'      => true,
    'spin_id' => $spinId,
    'verify'  => ['nonce'=>$nonce, 'hmac'=>$hmac],
    'index'   => $index,
    'forced'  => $forced,
    'retry_after' => 10,
    'roulette'=> [
      'id'               => (int)$r['id'],
      'anim_spins'       => isset($r['anim_spins']) ? (int)$r['anim_spins'] : null,
      'anim_speed'       => isset($r['anim_speed']) ? (int)$r['anim_speed'] : null,
      'pointer_position' => $r['pointer_position'] ?? 'top',
      'force_pattern'    => $r['force_pattern'] ?? 'none',
    ],
    'segment' => [
      'id'            => (int)$chosen['id'],
      'order'         => (int)($chosen['segment_order'] ?? $index),
      'type'          => strtoupper((string)$chosen['type']),
      'label_primary' => $chosen['label_primary'] ?? ($chosen['primary'] ?? null),
      'label_unit'    => $chosen['label_unit'] ?? ($chosen['unit'] ?? null),
      'color'         => $chosen['color'] ?? null,
      'image'         => $chosen['image'] ?? null,
      'game_url'      => $chosen['game_url'] ?? ($chosen['url'] ?? null),
      'weight'        => isset($chosen['weight']) ? (float)$chosen['weight'] : null,
      'effective_weight' => ((float)($chosen['weight'] ?? 0) <= 1) ? 0 : (float)$chosen['weight']
    ],
    'debug' => $dbg,
  ];

  error_log("🎰 SPIN - Response preparada, enviando JSON...");
  error_log("🎰 SPIN - Response: " . json_encode($response));

  echo json_encode($response, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);

} catch (Throwable $e) {
  error_log("🎰 SPIN - ERRO: " . $e->getMessage());
  error_log("🎰 SPIN - Trace: " . $e->getTraceAsString());
  error_log("🎰 SPIN - Arquivo: " . $e->getFile() . " Linha: " . $e->getLine());
  
  http_response_code(500);
  echo json_encode([
    'ok'=>false,
    'message'=>'Erro interno',
    'code'=>'server_exception',
    'detail'=> $e->getMessage(),
    'file'=> $e->getFile(),
    'line'=> $e->getLine()
  ]);
}