<?php
// views/pages/raspadita/api/coordinador_cobrar_saldo.php
// Cobrar saldo a PV o CAN y registrar en tbr_raspadita_cobro.
//
// POST JSON:
// { "tipo":"PV|CAN", "id_destino":123, "abono":10.50, "observacion":"..." }
//
// Reglas:
// - rol=7 y sesión con id_coordinador
// - PV: descuenta de tbr_usuario.saldo (DEBE existir la columna saldo)
// - CAN: descuenta de tbr_canillita.saldo
// - abono se limita al saldo actual (no deja saldo negativo)
// - Inserta historial en tbr_raspadita_cobro

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;
}

function jexit(array $p, int $c=200): void { http_response_code($c); echo json_encode($p, 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 now_str(): string { return date('Y-m-d H:i:s'); }

if (!isset($_SESSION['ingreso']) || $_SESSION['ingreso'] !== 'YES' || (int)($_SESSION['id_rol'] ?? 0) !== 7) {
  jexit(['success'=>false,'message'=>'No autorizado'], 401);
}
$id_coordinador = (int)($_SESSION['id_coordinador'] ?? 0);
if ($id_coordinador <= 0) jexit(['success'=>false,'message'=>'Sesión sin coordinador'], 401);

$in = read_json();
$tipo = strtoupper(trim((string)($in['tipo'] ?? '')));
$id_destino = (int)($in['id_destino'] ?? 0);
$abono_in = (float)($in['abono'] ?? 0);
$observacion = trim((string)($in['observacion'] ?? ''));

if (!in_array($tipo, ['PV','CAN'], true)) jexit(['success'=>false,'message'=>'tipo inválido (PV|CAN)'], 422);
if ($id_destino <= 0) jexit(['success'=>false,'message'=>'id_destino requerido'], 422);
if (!is_finite($abono_in) || $abono_in <= 0) jexit(['success'=>false,'message'=>'abono inválido'], 422);
if (strlen($observacion) > 255) $observacion = substr($observacion, 0, 255);

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

$fecha_hora = now_str();
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';

mysqli_begin_transaction($db);

try {

  // ==== Verificar columna saldo en PV (evitar 500)
  $pv_has_saldo = true;
  if ($tipo === 'PV') {
    $pv_has_saldo = false;
    $chk = mysqli_prepare($db, "
      SELECT 1
      FROM information_schema.COLUMNS
      WHERE TABLE_SCHEMA = DATABASE()
        AND TABLE_NAME = 'tbr_usuario'
        AND COLUMN_NAME = 'saldo'
      LIMIT 1
    ");
    if ($chk) {
      mysqli_stmt_execute($chk);
      mysqli_stmt_store_result($chk);
      $pv_has_saldo = (mysqli_stmt_num_rows($chk) > 0);
      mysqli_stmt_close($chk);
    }
    if (!$pv_has_saldo) {
      mysqli_rollback($db);
      jexit([
        'success'=>false,
        'message'=>"PV sin columna saldo. Ejecuta: ALTER TABLE tbr_usuario ADD saldo DECIMAL(10,2) DEFAULT 0;"
      ], 422);
    }
  }

  // ==== Validar destino + leer saldo actual
  $saldo_anterior = 0.0;
  $destino_txt = '';

  if ($tipo === 'CAN') {
    $st = mysqli_prepare($db, "SELECT canillita, COALESCE(saldo,0) saldo FROM tbr_canillita WHERE id=? AND activo=1 LIMIT 1");
    if (!$st) throw new Exception('SQL CAN select error');
    mysqli_stmt_bind_param($st, "i", $id_destino);
    mysqli_stmt_execute($st);
    mysqli_stmt_store_result($st);
    if (mysqli_stmt_num_rows($st) < 1) { mysqli_stmt_close($st); mysqli_rollback($db); jexit(['success'=>false,'message'=>'Canillita inválido o inactivo'], 422); }
    mysqli_stmt_bind_result($st, $canillita, $saldo);
    mysqli_stmt_fetch($st);
    mysqli_stmt_close($st);
    $destino_txt = (string)$canillita;
    $saldo_anterior = (float)$saldo;

  } else { // PV
    $st = mysqli_prepare($db, "SELECT usuario, COALESCE(saldo,0) saldo FROM tbr_usuario WHERE idusuario=? AND activo=1 AND condicion=1 LIMIT 1");
    if (!$st) throw new Exception('SQL PV select error');
    mysqli_stmt_bind_param($st, "i", $id_destino);
    mysqli_stmt_execute($st);
    mysqli_stmt_store_result($st);
    if (mysqli_stmt_num_rows($st) < 1) { mysqli_stmt_close($st); mysqli_rollback($db); jexit(['success'=>false,'message'=>'Punto de venta inválido o inactivo'], 422); }
    mysqli_stmt_bind_result($st, $usuario_pv, $saldo);
    mysqli_stmt_fetch($st);
    mysqli_stmt_close($st);
    $destino_txt = (string)$usuario_pv;
    $saldo_anterior = (float)$saldo;
  }

  if ($saldo_anterior <= 0) {
    mysqli_rollback($db);
    jexit(['success'=>false,'message'=>'Este destino no tiene saldo pendiente'], 409);
  }

  // ==== Abono real: no dejar saldo negativo
  $abono = round(min($abono_in, $saldo_anterior), 2);
  if ($abono <= 0) {
    mysqli_rollback($db);
    jexit(['success'=>false,'message'=>'Abono inválido frente al saldo actual'], 422);
  }

  $saldo_nuevo = round(max(0, $saldo_anterior - $abono), 2);

  // ==== Actualizar saldo
  if ($tipo === 'CAN') {
    $up = mysqli_prepare($db, "UPDATE tbr_canillita SET saldo=? WHERE id=? LIMIT 1");
    if (!$up) throw new Exception('SQL CAN update error');
    mysqli_stmt_bind_param($up, "di", $saldo_nuevo, $id_destino);
    mysqli_stmt_execute($up);
    if (mysqli_stmt_affected_rows($up) < 1) { mysqli_stmt_close($up); throw new Exception('No se pudo actualizar saldo canillita'); }
    mysqli_stmt_close($up);
  } else {
    $up = mysqli_prepare($db, "UPDATE tbr_usuario SET saldo=? WHERE idusuario=? LIMIT 1");
    if (!$up) throw new Exception('SQL PV update error');
    mysqli_stmt_bind_param($up, "di", $saldo_nuevo, $id_destino);
    mysqli_stmt_execute($up);
    if (mysqli_stmt_affected_rows($up) < 1) { mysqli_stmt_close($up); throw new Exception('No se pudo actualizar saldo PV'); }
    mysqli_stmt_close($up);
  }

  // ==== Insert historial cobro
  $id_pv  = ($tipo === 'PV') ? $id_destino : 0;
  $id_can = ($tipo === 'CAN') ? $id_destino : 0;

  $ins = mysqli_prepare($db, "
    INSERT INTO tbr_raspadita_cobro
      (fecha_hora, id_coordinador, id_punto_venta, id_canillita, saldo_anterior, abono, saldo_nuevo, observacion, ip)
    VALUES
      (?, ?, ?, ?, ?, ?, ?, ?, ?)
  ");
  if (!$ins) throw new Exception('SQL insert cobro error');
  mysqli_stmt_bind_param($ins, "siiiiddss",
    $fecha_hora,
    $id_coordinador,
    $id_pv,
    $id_can,
    $saldo_anterior,
    $abono,
    $saldo_nuevo,
    $observacion,
    $ip
  );
  mysqli_stmt_execute($ins);
  $newId = mysqli_insert_id($db);
  mysqli_stmt_close($ins);

  mysqli_commit($db);

  jexit([
    'success'=>true,
    'message'=>'Cobro registrado',
    'id'=>$newId,
    'fecha_hora'=>$fecha_hora,
    'tipo'=>$tipo,
    'id_destino'=>$id_destino,
    'destino'=>$destino_txt,
    'saldo_anterior'=>$saldo_anterior,
    'abono'=>$abono,
    'saldo_nuevo'=>$saldo_nuevo
  ]);

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