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

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');

header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-CSRF-Token');

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

// ✅ Protección (opcional)
// if (!isset($_SESSION['idusuario'])) { http_response_code(401); echo json_encode(['success'=>false,'message'=>'Sesión no iniciada'], JSON_UNESCAPED_UNICODE); exit; }

require_once __DIR__ . '/../../conex.php';
$db = $conn ?? null;
if (!$db instanceof mysqli) { http_response_code(500); echo json_encode(['success'=>false,'message'=>'Sin conexión BD'], JSON_UNESCAPED_UNICODE); exit; }
mysqli_set_charset($db, 'utf8mb4');
@mysqli_query($db, "SET time_zone = '-05:00'");

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');
  if (!$raw) return [];
  $j = json_decode($raw, true);
  return is_array($j) ? $j : [];
}
function norm_tipo_pago(string $s): string {
  $s = mb_strtoupper(trim($s), 'UTF-8');
  $s = preg_replace('/\s+/', ' ', $s);
  return $s;
}
function user_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);
}
function is_pago_saldo(?string $obs): bool {
  $obs = (string)$obs;
  return strpos($obs, 'PAGO_SALDO') === 0; // empieza con PAGO_SALDO
}

$action = $_GET['action'] ?? '';

/* ===================== CANILLITAS ACTIVOS ===================== */
if ($action === 'canillitas_activos') {
  $rows = [];
  $sql = "SELECT id, canillita FROM tbr_canillita WHERE activo=1 ORDER BY canillita ASC";
  $res = $db->query($sql);
  if ($res) {
    while ($r = $res->fetch_assoc()) $rows[] = $r;
    $res->free();
  }
  jexit(['success'=>true,'data'=>$rows]);
}

/* ===================== LIST COBROS ===================== */
if ($action === 'cobro_list') {
  $rows = [];
  $sql = "
    SELECT cs.id, cs.fecha_hora, cs.num_raspaditas, cs.subtotal, cs.descuento, cs.total_pagar, cs.tipo_pago, cs.id_canillita,
           c.canillita
    FROM tbr_coordinador_saldo cs
    INNER JOIN tbr_canillita c ON c.id = cs.id_canillita
    ORDER BY cs.id DESC
    LIMIT 500
  ";
  $res = $db->query($sql);
  if ($res) {
    while ($r = $res->fetch_assoc()) $rows[] = $r;
    $res->free();
  }
  jexit(['success'=>true,'data'=>$rows]);
}

/* ===================== COBRO NORMAL (igual que antes) ===================== */
if ($action === 'cobro_create') {
  if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') jexit(['success'=>false,'message'=>'Método no permitido. Use POST'], 405);

  $data = read_json();

  $id_canillita   = (int)($data['id_canillita'] ?? 0);
  $num_raspaditas = (int)($data['num_raspaditas'] ?? 0);

  $subtotal    = (float)($data['subtotal'] ?? 0);
  $descuento   = (float)($data['descuento'] ?? 0);
  $total_pagar = (float)($data['total_pagar'] ?? 0);

  $observacion = trim((string)($data['observacion'] ?? ''));
  $tipo_pago   = norm_tipo_pago((string)($data['tipo_pago'] ?? ''));

  if ($id_canillita <= 0) jexit(['success'=>false,'message'=>'Canillita requerido'], 422);
  if ($num_raspaditas < 0) jexit(['success'=>false,'message'=>'Cantidad inválida'], 422);
  if ($subtotal < 0 || $descuento < 0 || $total_pagar < 0) jexit(['success'=>false,'message'=>'Valores inválidos'], 422);
  if ($tipo_pago === '') jexit(['success'=>false,'message'=>'Tipo pago requerido'], 422);

  $id_admin = (int)($_SESSION['idusuario'] ?? 0);
  if ($id_admin < 0) $id_admin = 0;

  $chk = $db->prepare("SELECT id FROM tbr_canillita WHERE id=? LIMIT 1");
  if (!$chk) jexit(['success'=>false,'message'=>'Error preparando validación'], 500);
  $chk->bind_param("i", $id_canillita);
  $chk->execute();
  $ex = $chk->get_result()->fetch_assoc();
  $chk->close();
  if (!$ex) jexit(['success'=>false,'message'=>'Canillita no existe'], 404);

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

  $db->begin_transaction();
  try {
    $stmt = $db->prepare("
      INSERT INTO tbr_coordinador_saldo
      (fecha_hora, num_raspaditas, subtotal, descuento, total_pagar, observacion, id_admin, ip, tipo_pago, id_canillita)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    if (!$stmt) throw new Exception("Error preparando insert");

    $stmt->bind_param(
      "siddsdissi",
      $fecha_hora,
      $num_raspaditas,
      $subtotal,
      $descuento,
      $total_pagar,
      $observacion,
      $id_admin,
      $ip,
      $tipo_pago,
      $id_canillita
    );

    if (!$stmt->execute()) {
      $err = $stmt->error ?: 'No se pudo insertar';
      $stmt->close();
      throw new Exception($err);
    }
    $newId = (int)$stmt->insert_id;
    $stmt->close();

    // ✅ Si es crédito: aumentar saldo (deuda)
    if ($tipo_pago === 'CREDITO') {
      $upd = $db->prepare("UPDATE tbr_canillita SET saldo = saldo + ? WHERE id=? LIMIT 1");
      if (!$upd) throw new Exception("Error preparando update saldo");
      $upd->bind_param("di", $total_pagar, $id_canillita);
      if (!$upd->execute()) {
        $err = $upd->error ?: 'No se pudo actualizar saldo';
        $upd->close();
        throw new Exception($err);
      }
      $upd->close();
    }

    $db->commit();
    jexit(['success'=>true,'message'=>'Cobro registrado','id'=>$newId]);

  } catch (Throwable $e) {
    $db->rollback();
    jexit(['success'=>false,'message'=>'Error al registrar cobro','detail'=>$e->getMessage()], 500);
  }
}

/* ===================== ✅ NUEVO: COBRAR SALDO PENDIENTE ===================== */
if ($action === 'saldo_cobrar') {
  if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') jexit(['success'=>false,'message'=>'Método no permitido. Use POST'], 405);

  $data = read_json();
  $id_canillita = (int)($data['id_canillita'] ?? 0);
  $monto = (float)($data['monto'] ?? 0);
  $tipo_pago = norm_tipo_pago((string)($data['tipo_pago'] ?? ''));
  $obsUser = trim((string)($data['observacion'] ?? ''));

  if ($id_canillita <= 0) jexit(['success'=>false,'message'=>'Canillita requerido'], 422);
  if ($monto <= 0) jexit(['success'=>false,'message'=>'Monto inválido'], 422);
  if ($tipo_pago === '') jexit(['success'=>false,'message'=>'Tipo pago requerido'], 422);

  // Traer saldo actual
  $stmt = $db->prepare("SELECT id, saldo FROM tbr_canillita WHERE id=? LIMIT 1");
  if (!$stmt) jexit(['success'=>false,'message'=>'Error preparando consulta'], 500);
  $stmt->bind_param("i", $id_canillita);
  $stmt->execute();
  $row = $stmt->get_result()->fetch_assoc();
  $stmt->close();

  if (!$row) jexit(['success'=>false,'message'=>'Canillita no existe'], 404);

  $saldoActual = (float)($row['saldo'] ?? 0);
  if ($saldoActual <= 0) jexit(['success'=>false,'message'=>'No tiene saldo pendiente'], 422);
  if ($monto > $saldoActual + 0.00001) jexit(['success'=>false,'message'=>'No puede cobrar más que el saldo pendiente'], 422);

  $id_admin = (int)($_SESSION['idusuario'] ?? 0);
  if ($id_admin < 0) $id_admin = 0;

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

  // Marcar el movimiento para poder revertir en anulación
  $observacion = 'PAGO_SALDO';
  if ($obsUser !== '') $observacion .= ' - ' . $obsUser;

  // Guardar movimiento en historial y restar saldo
  $db->begin_transaction();
  try {
    // Insert historial como un “registro” (sin raspaditas)
    $num_raspaditas = 0;
    $subtotal = $monto;
    $descuento = 0.00;
    $total_pagar = $monto;

    $ins = $db->prepare("
      INSERT INTO tbr_coordinador_saldo
      (fecha_hora, num_raspaditas, subtotal, descuento, total_pagar, observacion, id_admin, ip, tipo_pago, id_canillita)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    if (!$ins) throw new Exception("Error preparando insert");

    $ins->bind_param(
      "siddsdissi",
      $fecha_hora,
      $num_raspaditas,
      $subtotal,
      $descuento,
      $total_pagar,
      $observacion,
      $id_admin,
      $ip,
      $tipo_pago,
      $id_canillita
    );

    if (!$ins->execute()) {
      $err = $ins->error ?: 'No se pudo insertar';
      $ins->close();
      throw new Exception($err);
    }
    $newId = (int)$ins->insert_id;
    $ins->close();

    // Restar saldo pendiente
    $upd = $db->prepare("UPDATE tbr_canillita SET saldo = saldo - ? WHERE id=? LIMIT 1");
    if (!$upd) throw new Exception("Error preparando update saldo");
    $upd->bind_param("di", $monto, $id_canillita);
    if (!$upd->execute()) {
      $err = $upd->error ?: 'No se pudo actualizar saldo';
      $upd->close();
      throw new Exception($err);
    }
    $upd->close();

    $db->commit();
    jexit(['success'=>true,'message'=>'Saldo cobrado','id'=>$newId,'monto'=>$monto]);

  } catch (Throwable $e) {
    $db->rollback();
    jexit(['success'=>false,'message'=>'Error al cobrar saldo','detail'=>$e->getMessage()], 500);
  }
}

/* ===================== ANULAR (reversa CREDITO o PAGO_SALDO) ===================== */
if ($action === 'cobro_anular') {
  if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') jexit(['success'=>false,'message'=>'Método no permitido. Use POST'], 405);

  $data = read_json();
  $id = (int)($data['id'] ?? 0);
  if ($id <= 0) jexit(['success'=>false,'message'=>'ID requerido'], 422);

  $stmt = $db->prepare("SELECT id, id_canillita, tipo_pago, total_pagar, observacion FROM tbr_coordinador_saldo WHERE id=? LIMIT 1");
  if (!$stmt) jexit(['success'=>false,'message'=>'Error preparando consulta'], 500);
  $stmt->bind_param("i", $id);
  $stmt->execute();
  $row = $stmt->get_result()->fetch_assoc();
  $stmt->close();

  if (!$row) jexit(['success'=>false,'message'=>'Registro no existe'], 404);

  $id_canillita = (int)$row['id_canillita'];
  $tipo_pago = norm_tipo_pago((string)$row['tipo_pago']);
  $total_pagar = (float)($row['total_pagar'] ?? 0);
  $obs = (string)($row['observacion'] ?? '');

  $db->begin_transaction();
  try {
    // ✅ Si fue un PAGO_SALDO: devolver saldo (sumar)
    if (is_pago_saldo($obs)) {
      $upd = $db->prepare("UPDATE tbr_canillita SET saldo = saldo + ? WHERE id=? LIMIT 1");
      if (!$upd) throw new Exception("Error preparando reverse saldo");
      $upd->bind_param("di", $total_pagar, $id_canillita);
      if (!$upd->execute()) {
        $err = $upd->error ?: 'No se pudo reversar saldo';
        $upd->close();
        throw new Exception($err);
      }
      $upd->close();
    }
    // ✅ Si era CREDITO: reversar crédito (restar)
    else if ($tipo_pago === 'CREDITO') {
      $upd = $db->prepare("UPDATE tbr_canillita SET saldo = saldo - ? WHERE id=? LIMIT 1");
      if (!$upd) throw new Exception("Error preparando reverse crédito");
      $upd->bind_param("di", $total_pagar, $id_canillita);
      if (!$upd->execute()) {
        $err = $upd->error ?: 'No se pudo reversar crédito';
        $upd->close();
        throw new Exception($err);
      }
      $upd->close();
    }

    $del = $db->prepare("DELETE FROM tbr_coordinador_saldo WHERE id=? LIMIT 1");
    if (!$del) throw new Exception("Error preparando delete");
    $del->bind_param("i", $id);
    if (!$del->execute()) {
      $err = $del->error ?: 'No se pudo eliminar';
      $del->close();
      throw new Exception($err);
    }
    $del->close();

    $db->commit();
    jexit(['success'=>true,'message'=>'Anulado']);

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

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