<?php
// views/pages/raspadita/api/raspadita_insert.php
// ENTREGA CANILLITA: estado=3 forzado
// Si el codigo ya existe (anulado=0):
//   - SI (algun devuelto esta en 0 o 1) => ANULA el anterior e INSERTA un nuevo registro
//   - SI (todos los devueltos > 1)      => BLOQUEA
// NO actualiza saldo en tbr_canillita

declare(strict_types=1);
session_start();
date_default_timezone_set('America/Guayaquil');

/* ===== HEADERS ===== */
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');

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

function jexit(array $payload, int $code=200): void {
  http_response_code($code);
  echo json_encode($payload, JSON_UNESCAPED_UNICODE);
  exit;
}
function read_json(): array {
  $raw = file_get_contents('php://input');
  $data = json_decode($raw ?: '', true);
  return is_array($data) ? $data : [];
}
function norm(string $s): string {
  $s = trim($s);
  $s = preg_replace('/\s+/', '', $s);
  return (string)$s;
}
function co0($v): int {
  if ($v === null) return 0;
  $n = (int)$v;
  return $n;
}

if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
  jexit(['success'=>false,'message'=>'Metodo no permitido. Use POST'], 405);
}

/* ===== DB ===== */
require_once __DIR__ . '/../../conex.php';
$db = $conn ?? ($conex ?? null);
if (!$db instanceof mysqli) jexit(['success'=>false,'message'=>'Sin conexion BD'], 500);

mysqli_set_charset($db, 'utf8mb4');
@mysqli_query($db, "SET time_zone = '-05:00'");

/* ===== ENTRADA ===== */
$in = read_json();

$codigo       = norm((string)($in['codigo'] ?? ''));
$estado       = 3; // FORZADO SIEMPRE
$anulado      = isset($in['anulado']) ? (int)$in['anulado'] : 0;
$id_canillita = (int)($in['id_canillita'] ?? 0);

$premio = (float)($in['premio'] ?? 0);
$premio = round($premio, 2);

$id_admin_ses = (int)($_SESSION['idusuario'] ?? 0);
$id_admin     = $id_admin_ses > 0 ? $id_admin_ses : (int)($in['id_admin'] ?? 0);

if ($id_admin <= 0)  jexit(['success'=>false,'message'=>'Debe enviar "id_admin" o iniciar sesion'], 401);
if ($codigo === '')  jexit(['success'=>false,'message'=>'Debe enviar "codigo"'], 422);
if (!in_array($anulado, [0,1], true)) jexit(['success'=>false,'message'=>'"anulado" debe ser 0 o 1'], 422);
if ($id_canillita <= 0) jexit(['success'=>false,'message'=>'Debe enviar "id_canillita" (>0)'], 422);
if ($premio < 0) jexit(['success'=>false,'message'=>'"premio" no puede ser negativo'], 422);

$ip  = (string)($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0');
$now = date('Y-m-d H:i:s');

try {
  mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  $db->begin_transaction();

  // validar canillita activo
  $stmt = $db->prepare("SELECT id FROM tbr_canillita WHERE id=? AND activo=1 LIMIT 1");
  $stmt->bind_param("i", $id_canillita);
  $stmt->execute();
  $rc = $stmt->get_result();
  $can = $rc ? $rc->fetch_assoc() : null;
  $stmt->close();

  if (!$can) {
    $db->rollback();
    jexit(['success'=>false,'message'=>'Canillita no existe o esta inactivo'], 409);
  }

  // Buscar si ya existe activo (anulado=0) y traer devueltos
  $stmt = $db->prepare("
    SELECT id,
           COALESCE(devuelto_punto,0)       AS dev_p,
           COALESCE(devuelto_canillita,0)   AS dev_c,
           COALESCE(devuelto_coordinador,0) AS dev_co
    FROM tbr_raspadita
    WHERE codigo=? AND anulado=0
    ORDER BY id DESC
    LIMIT 1
    FOR UPDATE
  ");
  $stmt->bind_param("s", $codigo);
  $stmt->execute();
  $res = $stmt->get_result();
  $ex  = $res ? $res->fetch_assoc() : null;
  $stmt->close();

  // Regla: permitir ˇ§insertar otroˇ¨ si ALGUNO esta en 0 o 1
  $permite_reinsertar = true; // por defecto si no existe
  $oldId = 0;

  if ($ex) {
    $oldId = (int)$ex['id'];
    $dev_p  = co0($ex['dev_p']);
    $dev_c  = co0($ex['dev_c']);
    $dev_co = co0($ex['dev_co']);

    $permite_reinsertar = (
      in_array($dev_p,  [0,1], true)
      || in_array($dev_c,  [0,1], true)
      || in_array($dev_co, [0,1], true)
    );

    if (!$permite_reinsertar) {
      $db->rollback();
      jexit([
        'success'=>false,
        'message'=>'No se puede insertar nuevamente: devoluciones mayores a 1 en todos.',
        'codigo'=>$codigo,
        'devuelto_punto'=>$dev_p,
        'devuelto_canillita'=>$dev_c,
        'devuelto_coordinador'=>$dev_co
      ], 409);
    }

    // ? Anular el anterior para dejar un solo ˇ§activoˇ¨
    $stmtAn = $db->prepare("UPDATE tbr_raspadita SET anulado=1 WHERE id=? LIMIT 1");
    $stmtAn->bind_param("i", $oldId);
    $stmtAn->execute();
    $stmtAn->close();
  }

  // ? Insertar NUEVO registro
  $stmtIns = $db->prepare("
    INSERT INTO tbr_raspadita
      (codigo, estado, anulado, fecha_hora, ip, id_admin, id_canillita, premio)
    VALUES
      (?, ?, 0, ?, ?, ?, ?, ?)
  ");
  $stmtIns->bind_param("sissiid", $codigo, $estado, $now, $ip, $id_admin, $id_canillita, $premio);
  $stmtIns->execute();
  $newId = (int)$db->insert_id;
  $stmtIns->close();

  $db->commit();

  jexit([
    'success' => true,
    'message' => $oldId > 0 ? 'Insertado nuevamente (anterior anulado)' : 'Insertado correctamente',
    'mode'    => $oldId > 0 ? 'insert_again' : 'insert',
    'old_id'  => $oldId ?: null,
    'id'      => $newId,
    'codigo'  => $codigo,
    'estado'  => $estado,
    'premio'  => $premio
  ], 201);

} catch (Throwable $e) {
  try { $db->rollback(); } catch(Throwable $x) {}
  jexit([
    'success' => false,
    'message' => 'Error en transaccion',
    'detail'  => $e->getMessage()
  ], 500);
}
