<?php
// guardar_ticket3.php — Inserta ticket (3 cifras) — CUPO GLOBAL (permite hasta 5, bloquea si suma>=5)
declare(strict_types=1);
session_start();
date_default_timezone_set('America/Guayaquil');

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

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
  http_response_code(204);
  exit;
}

try {
  // ==== Validar sesión ====
  if (!isset($_SESSION['idusuario'])) {
    echo json_encode(['success'=>false,'message'=>'Sesión no iniciada'], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $id_usuario = (int)$_SESSION['idusuario'];

  // ==== Conexión BD ====
  require __DIR__ . '/conex.php';
  $cn = $conn ?? ($conex ?? null);
  if (!$cn instanceof mysqli) {
    echo json_encode(['success'=>false,'message'=>'Sin conexión BD'], JSON_UNESCAPED_UNICODE);
    exit;
  }

  mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  mysqli_set_charset($cn, 'utf8mb4');
  @mysqli_query($cn, "SET time_zone = '-05:00'");

  $post = fn(string $k): string => isset($_POST[$k]) ? trim((string)$_POST[$k]) : '';

  // ==== Datos entrada ====
  $date2     = $post('date2');
  $idloteria = (int)($_POST['loterias'] ?? 0);

  // Acepta "5.00" o "5,00"
  $valorRaw = $post('valor');
  if ($valorRaw === '') $valorRaw = (string)($_POST['valor'] ?? '0');
  $valor = (float) str_replace(',', '.', $valorRaw);

  // Normalizar número a 3 cifras
  $rawNum = preg_replace('/\D/', '', $post('number'));
  $number = str_pad(substr($rawNum, -3), 3, '0', STR_PAD_LEFT);

  $id_cifras = 2; // 3 cifras
  $hoy = date('Y-m-d');

  // ==== Validaciones básicas ====
  if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date2)) throw new Exception('Fecha inválida (YYYY-MM-DD).');
  if ($date2 < $hoy) throw new Exception('La fecha no puede ser menor a hoy.');
  if ($idloteria <= 0) throw new Exception('Seleccione una lotería.');
  if (!preg_match('/^\d{3}$/', $number)) throw new Exception('Número inválido (000-999).');
  if ($valor < 0.50) throw new Exception('El valor debe ser = 0.50.');

  // ==== Hora cierre lotería ====
  $horaHi = (int)date('Hi');

  $HCAST = "CAST(
              LPAD(
                CONCAT(
                  LPAD(SUBSTRING_INDEX(hora_fin, ':', 1), 2, '0'),
                  LPAD(SUBSTRING_INDEX(hora_fin, ':', -1), 2, '0')
                ),
              4,'0')
            AS UNSIGNED)";

  $st = $cn->prepare("SELECT $HCAST AS finHHMM, activar, condicion FROM tbr_loteria WHERE idloteria = ?");
  $st->bind_param('i', $idloteria);
  $st->execute();
  $lot = $st->get_result()->fetch_assoc();
  $st->close();

  if (!$lot || (int)$lot['activar'] !== 1 || (int)$lot['condicion'] !== 1) {
    throw new Exception('Lotería inactiva o inexistente.');
  }
  if ($date2 === $hoy && (int)$lot['finHHMM'] < $horaHi) {
    throw new Exception('Fuera de la hora de juego permitida.');
  }

  // ==== CUPOS ====
  // Cupo base global por cifra (ej: 5)
  $cupo_base = 0.0;
  $st = $cn->prepare("SELECT cupo_cifras FROM tbr_cifras WHERE idcifras = ? AND condicion = 1");
  $st->bind_param('i', $id_cifras);
  $st->execute();
  $cupo_base = (float)($st->get_result()->fetch_assoc()['cupo_cifras'] ?? 0);
  $st->close();

  // Extra cupo para 3 cifras (si no quieres extra, déjalo en 0)
  $extra = 0.0;
  $st = $cn->prepare("
    SELECT CASE WHEN cupo_activo3 = 1 THEN COALESCE(extra_cupo3, 0) ELSE 0 END AS extra
    FROM tbr_usuario
    WHERE idusuario = ?
  ");
  $st->bind_param('i', $id_usuario);
  $st->execute();
  $extra = (float)($st->get_result()->fetch_assoc()['extra'] ?? 0);
  $st->close();

  $cupo_total = $cupo_base + $extra;

  // Si el valor por sí solo ya excede cupo
  if ($valor > $cupo_total) {
    echo json_encode([
      'success'=>false,
      'error'=>'Cupo_no_disponible',
      'mensaje'=>"El valor ($valor) supera el cupo máximo ($cupo_total)."
    ], JSON_UNESCAPED_UNICODE);
    exit;
  }

  // ? SUMA que cuenta para cupo: SOLO estado 1 o 2
  $sqlSuma = "
    SELECT IFNULL(SUM(t.valor), 0) AS suma
    FROM tbr_ticket t
    WHERE t.fecha      = ?
      AND t.condicion  = 1
      AND t.id_cifras  = ?
      AND t.numero     = ?
      AND t.id_loteria = ?
      AND t.estado IN (1,2)
  ";
  $st = $cn->prepare($sqlSuma);
  $st->bind_param('sisi', $date2, $id_cifras, $number, $idloteria);
  $st->execute();
  $suma = (float)($st->get_result()->fetch_assoc()['suma'] ?? 0);
  $st->close();

  // ? REGLA EXACTA:
  // - si suma >= cupo_total => NO vender
  if ($suma >= $cupo_total) {
    echo json_encode([
      'success'=>false,
      'error'=>'Cupo_no_disponible',
      'mensaje'=>"Cupo agotado. Ya se vendió $suma y el cupo máximo es $cupo_total."
    ], JSON_UNESCAPED_UNICODE);
    exit;
  }

  // - si suma < cupo_total => permitir SOLO si (suma + valor) <= cupo_total
  $restante_total = $cupo_total - $suma;

  if (($suma + $valor) > $cupo_total) {
    echo json_encode([
      'success'=>false,
      'error'=>'Cupo_no_disponible',
      'mensaje'=>"Solo te queda $restante_total de cupo para este número.",
      'cupo_restante'=>number_format(max($restante_total, 0), 2, '.', '')
    ], JSON_UNESCAPED_UNICODE);
    exit;
  }

  // Distribución base vs extra
  $restante_base = max($cupo_base - $suma, 0);
  $tope1 = min($valor, $restante_base);
  $tope2 = max($valor - $tope1, 0);

  if ($tope2 > $extra) {
    throw new Exception("No puedes superar el cupo adicional de $extra.");
  }

  // ==== Insertar ====
  $fecha_imp = date('Y-m-d');
  $hora_imp  = date('H:i:s');
  $estado    = 1; // cuenta para cupo porque está en (1,2)
  $cond      = 1;

  // Código único
  $codigo = '';
  for ($i=0; $i<10; $i++) {
    $codigo = (string)random_int(10000000, 99999999);
    $chk = $cn->prepare("SELECT 1 FROM tbr_ticket WHERE codigo = ? LIMIT 1");
    $chk->bind_param('s', $codigo);
    $chk->execute();
    $exists = $chk->get_result()->fetch_row();
    $chk->close();
    if (!$exists) break;
  }
  if ($codigo === '') throw new Exception('No se pudo generar código único.');

  $sqlIns = "INSERT INTO tbr_ticket
    (fecha_impreso, hora_impreso, fecha, id_loteria, numero, valor,
     id_usuario, codigo, estado, tope1, tope2, id_cifras, condicion)
    VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";

  $st = $cn->prepare($sqlIns);
  $st->bind_param(
    'sssisdisiddii',
    $fecha_imp,
    $hora_imp,
    $date2,
    $idloteria,
    $number,
    $valor,
    $id_usuario,
    $codigo,
    $estado,
    $tope1,
    $tope2,
    $id_cifras,
    $cond
  );
  $st->execute();
  $id = (int)$cn->insert_id;
  $st->close();

  echo json_encode([
    'success'=>true,
    'id'=>$id,
    'codigo'=>$codigo,
    'numero'=>$number,
    'valor'=>number_format($valor, 2, '.', ''),
    'cupo_restante'=>number_format(max($restante_total - $valor, 0), 2, '.', '')
  ], JSON_UNESCAPED_UNICODE);

} catch (Throwable $e) {
  http_response_code(200);
  echo json_encode([
    'success'=>false,
    'message'=>'No se pudo guardar',
    'error'=>$e->getMessage()
  ], JSON_UNESCAPED_UNICODE);
}
