<?php
// views/pages/raspadita/api/pv_cobro_actions.php
declare(strict_types=1);

session_start();
date_default_timezone_set('America/Guayaquil');

header('Content-Type: application/json; charset=utf-8');
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; }
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
  http_response_code(405);
  echo json_encode(['success'=>false,'message'=>'Use POST'], JSON_UNESCAPED_UNICODE);
  exit;
}

// 🔎 Debug útil en local (puedes apagarlo en producción)
ini_set('display_errors', '0'); // no imprimir HTML
ini_set('log_errors', '1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

function jexit(array $p, int $code=200): void {
  http_response_code($code);
  echo json_encode($p, JSON_UNESCAPED_UNICODE);
  exit;
}
function read_json(): array {
  $raw = file_get_contents('php://input');
  $j = json_decode($raw ?: '[]', true);
  return is_array($j) ? $j : [];
}
function client_ip(): string {
  $ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
  if (strpos($ip, ',') !== false) $ip = trim(explode(',', $ip)[0]);
  return substr($ip, 0, 45);
}

try {
  if (!isset($_SESSION['idusuario'])) jexit(['success'=>false,'message'=>'Sesión no válida'], 401);
  $id_admin = (int)$_SESSION['idusuario'];

  require __DIR__ . '/../../conex.php';
  $cn = $conn ?? ($conex ?? null);
  if (!$cn instanceof mysqli) jexit(['success'=>false,'message'=>'Sin conexión BD'], 500);
  mysqli_set_charset($cn, 'utf8mb4');
  @mysqli_query($cn, "SET time_zone='-05:00'");

  $in = read_json();
  $action = (string)($in['action'] ?? '');

  // =========================
  // COBRO PV
  // =========================
  if ($action === 'cobro_pv') {
    $id_punto_venta = (int)($in['id_punto_venta'] ?? 0);
    $abono = (float)($in['abono'] ?? 0);
    $observacion = trim((string)($in['observacion'] ?? ''));

    if ($id_punto_venta <= 0) jexit(['success'=>false,'message'=>'ID punto de venta inválido'], 422);
    if ($abono <= 0) jexit(['success'=>false,'message'=>'Abono inválido'], 422);

    // Traer saldo actual del PV (tbr_usuario.saldo)
    $stmt = mysqli_prepare($cn, "
      SELECT idusuario, usuario, COALESCE(saldo,0) AS saldo
      FROM tbr_usuario
      WHERE idusuario=? AND condicion=1
      LIMIT 1
      FOR UPDATE
    ");
    mysqli_stmt_bind_param($stmt, "i", $id_punto_venta);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $pv = mysqli_fetch_assoc($res) ?: null;
    mysqli_stmt_close($stmt);

    if (!$pv) jexit(['success'=>false,'message'=>'Punto de venta no existe'], 404);

    $saldo_anterior = (float)$pv['saldo'];

    if ($abono > $saldo_anterior) {
      jexit(['success'=>false,'message'=>'El abono no puede ser mayor al saldo actual'], 422);
    }

    $saldo_nuevo = round($saldo_anterior - $abono, 2);
    $ip = client_ip();
    $fh = date('Y-m-d H:i:s');

    mysqli_begin_transaction($cn);

    // Insert cobro (tabla tbr_raspadita_cobro)
    $stmt = mysqli_prepare($cn, "
      INSERT INTO tbr_raspadita_cobro
      (fecha_hora, id_coordinador, id_punto_venta, id_canillita, saldo_anterior, abono, saldo_nuevo, observacion, id_admin, ip)
      VALUES (?,?,?,?,?,?,?,?,?,?)
    ");
    $id_coordinador = 0;
    $id_canillita = 0;

    // ✅ TIPOS CORRECTOS: s i i i d d d s i s
    mysqli_stmt_bind_param(
      $stmt,
      "siiidddsis",
      $fh,
      $id_coordinador,
      $id_punto_venta,
      $id_canillita,
      $saldo_anterior,
      $abono,
      $saldo_nuevo,
      $observacion,
      $id_admin,
      $ip
    );
    mysqli_stmt_execute($stmt);
    $id_cobro = mysqli_insert_id($cn);
    mysqli_stmt_close($stmt);

    // Update saldo PV
    $stmt = mysqli_prepare($cn, "UPDATE tbr_usuario SET saldo=? WHERE idusuario=? LIMIT 1");
    mysqli_stmt_bind_param($stmt, "di", $saldo_nuevo, $id_punto_venta);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);

    mysqli_commit($cn);

    jexit([
      'success'=>true,
      'message'=>'Cobro registrado',
      'id'=>$id_cobro,
      'saldo_anterior'=>$saldo_anterior,
      'abono'=>$abono,
      'saldo_nuevo'=>$saldo_nuevo
    ]);
  }

  // =========================
  // HISTORIAL PV
  // =========================
  if ($action === 'historial_pv') {
    $id_punto_venta = (int)($in['id_punto_venta'] ?? 0);
    $desde = trim((string)($in['desde'] ?? ''));
    $hasta = trim((string)($in['hasta'] ?? ''));

    $where = " WHERE c.id_punto_venta > 0 AND c.id_coordinador=0 AND c.id_canillita=0 ";
    $types = "";
    $params = [];

    if ($id_punto_venta > 0) { $where .= " AND c.id_punto_venta=? "; $types .= "i"; $params[] = $id_punto_venta; }
    if ($desde !== '') { $where .= " AND DATE(c.fecha_hora) >= ? "; $types .= "s"; $params[] = $desde; }
    if ($hasta !== '') { $where .= " AND DATE(c.fecha_hora) <= ? "; $types .= "s"; $params[] = $hasta; }

    $sql = "
      SELECT
        c.id, c.fecha_hora, c.id_punto_venta,
        u.usuario AS punto_venta,
        c.saldo_anterior, c.abono, c.saldo_nuevo, c.observacion,
        (SELECT 1 FROM tbr_raspadita_cobro_anulacion a WHERE a.id_cobro=c.id LIMIT 1) AS anulado
      FROM tbr_raspadita_cobro c
      INNER JOIN tbr_usuario u ON u.idusuario = c.id_punto_venta
      $where
      ORDER BY c.id DESC
      LIMIT 500
    ";

    $stmt = mysqli_prepare($cn, $sql);
    if ($types !== "") mysqli_stmt_bind_param($stmt, $types, ...$params);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);

    $data = [];
    while ($r = mysqli_fetch_assoc($res)) {
      $data[] = [
        'id' => (int)$r['id'],
        'fecha_hora' => (string)$r['fecha_hora'],
        'id_punto_venta' => (int)$r['id_punto_venta'],
        'punto_venta' => (string)$r['punto_venta'],
        'saldo_anterior' => (string)$r['saldo_anterior'],
        'abono' => (string)$r['abono'],
        'saldo_nuevo' => (string)$r['saldo_nuevo'],
        'observacion' => (string)($r['observacion'] ?? ''),
        'anulado' => (int)($r['anulado'] ?? 0),
      ];
    }
    mysqli_stmt_close($stmt);

    jexit(['success'=>true,'data'=>$data]);
  }

  // =========================
  // ANULAR PV
  // =========================
  if ($action === 'anular_pv') {
    $id_cobro = (int)($in['id_cobro'] ?? 0);
    $motivo = trim((string)($in['motivo'] ?? ''));

    if ($id_cobro <= 0) jexit(['success'=>false,'message'=>'ID cobro inválido'], 422);
    if ($motivo === '') jexit(['success'=>false,'message'=>'Motivo requerido'], 422);

    $ip = client_ip();
    $fh = date('Y-m-d H:i:s');

    mysqli_begin_transaction($cn);

    // ya anulado?
    $stmt = mysqli_prepare($cn, "SELECT id FROM tbr_raspadita_cobro_anulacion WHERE id_cobro=? LIMIT 1");
    mysqli_stmt_bind_param($stmt, "i", $id_cobro);
    mysqli_stmt_execute($stmt);
    $resA = mysqli_stmt_get_result($stmt);
    $ya = mysqli_fetch_assoc($resA);
    mysqli_stmt_close($stmt);
    if ($ya) { mysqli_rollback($cn); jexit(['success'=>false,'message'=>'Este cobro ya fue anulado'], 409); }

    // cobro
    $stmt = mysqli_prepare($cn, "
      SELECT id, id_punto_venta, abono
      FROM tbr_raspadita_cobro
      WHERE id=? AND id_punto_venta>0 AND id_coordinador=0 AND id_canillita=0
      LIMIT 1
      FOR UPDATE
    ");
    mysqli_stmt_bind_param($stmt, "i", $id_cobro);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $c = mysqli_fetch_assoc($res) ?: null;
    mysqli_stmt_close($stmt);

    if (!$c) { mysqli_rollback($cn); jexit(['success'=>false,'message'=>'Cobro no encontrado'], 404); }

    $id_punto_venta = (int)$c['id_punto_venta'];
    $abono = (float)$c['abono'];

    // saldo actual
    $stmt = mysqli_prepare($cn, "SELECT COALESCE(saldo,0) saldo FROM tbr_usuario WHERE idusuario=? LIMIT 1 FOR UPDATE");
    mysqli_stmt_bind_param($stmt, "i", $id_punto_venta);
    mysqli_stmt_execute($stmt);
    $resS = mysqli_stmt_get_result($stmt);
    $u = mysqli_fetch_assoc($resS) ?: null;
    mysqli_stmt_close($stmt);

    if (!$u) { mysqli_rollback($cn); jexit(['success'=>false,'message'=>'PV no encontrado'], 404); }

    $saldo_actual = (float)$u['saldo'];
    $saldo_revertido = round($saldo_actual + $abono, 2);

    // auditoría
    $stmt = mysqli_prepare($cn, "
      INSERT INTO tbr_raspadita_cobro_anulacion (id_cobro, motivo, id_admin, ip, fecha_hora)
      VALUES (?,?,?,?,?)
    ");
    mysqli_stmt_bind_param($stmt, "isiss", $id_cobro, $motivo, $id_admin, $ip, $fh);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);

    // revertir saldo
    $stmt = mysqli_prepare($cn, "UPDATE tbr_usuario SET saldo=? WHERE idusuario=? LIMIT 1");
    mysqli_stmt_bind_param($stmt, "di", $saldo_revertido, $id_punto_venta);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);

    mysqli_commit($cn);

    jexit(['success'=>true,'message'=>'Cobro anulado y saldo revertido', 'saldo_revertido'=>$saldo_revertido]);
  }

  jexit(['success'=>false,'message'=>'Acción no válida'], 400);

} catch (Throwable $e) {
  // Si algo truena, devuelve JSON con detalle (esto te dirá EXACTO el motivo del 500)
  try { if (isset($cn) && $cn instanceof mysqli) @mysqli_rollback($cn); } catch(Throwable $x){}
  jexit(['success'=>false,'message'=>'Error interno', 'detail'=>$e->getMessage()], 500);
}
