<?php
// views/pages/raspadita/api/coordinador_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');

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

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'=>'Método no permitido'], JSON_UNESCAPED_UNICODE);
  exit;
}

/* ✅ NO romper JSON con fatals */
mysqli_report(MYSQLI_REPORT_OFF);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
error_reporting(E_ALL);

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');
  $j = json_decode($raw ?: '[]', true);
  return is_array($j) ? $j : [];
}
function upper(string $s): string {
  $s = trim($s);
  return $s === '' ? '' : mb_strtoupper($s, 'UTF-8');
}
function 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);
}

/* ✅ Sesión */
if (!isset($_SESSION['idusuario'])) {
  jexit(['success'=>false,'message'=>'Sesión no iniciada'], 401);
}

/* ✅ CSRF */
$csrfHeader = (string)($_SERVER['HTTP_X_CSRF_TOKEN'] ?? '');
$csrfSess   = (string)($_SESSION['csrf'] ?? '');
if ($csrfSess === '' || !hash_equals($csrfSess, $csrfHeader)) {
  jexit(['success'=>false,'message'=>'CSRF inválido'], 419);
}

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

$in = read_json();
$action = (string)($in['action'] ?? '');
$id_admin = (int)($_SESSION['idusuario'] ?? 0);

const ROL_COORDINADOR = 7;

/* ===================== LIST ===================== */
if ($action === 'list') {
  $rows = [];
  $sql = "SELECT id, indentificacion, nombre, activo, saldo, usuario, id_rol
          FROM tbr_coordinador
          ORDER BY id DESC";
  $res = $db->query($sql);
  if ($res) {
    while ($r = $res->fetch_assoc()) $rows[] = $r;
    $res->free();
  }
  jexit(['success'=>true,'data'=>$rows]);
}

/* ===================== CREATE ===================== */
if ($action === 'create') {
  $indentificacion = trim((string)($in['indentificacion'] ?? ''));
  $nombre = upper((string)($in['nombre'] ?? ''));
  $activo = (int)($in['activo'] ?? 1);

  $usuario = upper((string)($in['usuario_login'] ?? ''));
  $clave   = trim((string)($in['clave_login'] ?? ''));

  if ($indentificacion === '') jexit(['success'=>false,'message'=>'Identificación requerida'], 422);
  if ($nombre === '') jexit(['success'=>false,'message'=>'Nombre requerido'], 422);
  if ($usuario === '') jexit(['success'=>false,'message'=>'Usuario requerido'], 422);
  if ($clave === '') jexit(['success'=>false,'message'=>'Clave requerida'], 422);
  if (!in_array($activo, [0,1], true)) $activo = 1;

  // usuario único
  $st = $db->prepare("SELECT id FROM tbr_coordinador WHERE usuario=? LIMIT 1");
  if(!$st) jexit(['success'=>false,'message'=>'Error preparando validación usuario'], 500);
  $st->bind_param("s", $usuario);
  $st->execute();
  $dup = $st->get_result()->fetch_assoc();
  $st->close();
  if ($dup) jexit(['success'=>false,'message'=>'Ese usuario ya existe.'], 409);

  $saldo = 0.00;
  $rol = ROL_COORDINADOR;

  // ✅ CLAVE EN TEXTO PLANO
  $plain = $clave;

  $ins = $db->prepare("
    INSERT INTO tbr_coordinador (indentificacion, nombre, activo, saldo, usuario, clave, id_rol)
    VALUES (?,?,?,?,?,?,?)
  ");
  if (!$ins) jexit(['success'=>false,'message'=>'No se pudo preparar INSERT'], 500);

  $ins->bind_param("ssidssi", $indentificacion, $nombre, $activo, $saldo, $usuario, $plain, $rol);

  if (!$ins->execute()) {
    $err = $ins->error ?: 'Error al insertar';
    $ins->close();
    jexit(['success'=>false,'message'=>'No se pudo guardar','detail'=>$err], 500);
  }

  $newId = (int)$ins->insert_id;
  $ins->close();
  jexit(['success'=>true,'message'=>'Coordinador creado','id'=>$newId]);
}

/* ===================== UPDATE ===================== */
if ($action === 'update') {
  $id = (int)($in['id'] ?? 0);
  $indentificacion = trim((string)($in['indentificacion'] ?? ''));
  $nombre = upper((string)($in['nombre'] ?? ''));
  $activo = (int)($in['activo'] ?? 1);

  $usuario = upper((string)($in['usuario_login'] ?? ''));
  $clave   = trim((string)($in['clave_login'] ?? ''));

  if ($id <= 0) jexit(['success'=>false,'message'=>'ID inválido'], 422);
  if ($indentificacion === '') jexit(['success'=>false,'message'=>'Identificación requerida'], 422);
  if ($nombre === '') jexit(['success'=>false,'message'=>'Nombre requerido'], 422);
  if ($usuario === '') jexit(['success'=>false,'message'=>'Usuario requerido'], 422);
  if (!in_array($activo, [0,1], true)) $activo = 1;

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

  // usuario único
  $st = $db->prepare("SELECT id FROM tbr_coordinador WHERE usuario=? AND id<>? LIMIT 1");
  if(!$st) jexit(['success'=>false,'message'=>'Error preparando validación usuario'], 500);
  $st->bind_param("si", $usuario, $id);
  $st->execute();
  $dup = $st->get_result()->fetch_assoc();
  $st->close();
  if ($dup) jexit(['success'=>false,'message'=>'Ese usuario ya existe.'], 409);

  $rol = ROL_COORDINADOR;

  if ($clave !== '') {
    // ✅ actualiza clave en texto plano
    $up = $db->prepare("
      UPDATE tbr_coordinador
      SET indentificacion=?, nombre=?, activo=?, usuario=?, clave=?, id_rol=?
      WHERE id=? LIMIT 1
    ");
    if(!$up) jexit(['success'=>false,'message'=>'No se pudo preparar UPDATE'], 500);
    $up->bind_param("ssissii", $indentificacion, $nombre, $activo, $usuario, $clave, $rol, $id);
  } else {
    $up = $db->prepare("
      UPDATE tbr_coordinador
      SET indentificacion=?, nombre=?, activo=?, usuario=?, id_rol=?
      WHERE id=? LIMIT 1
    ");
    if(!$up) jexit(['success'=>false,'message'=>'No se pudo preparar UPDATE'], 500);
    $up->bind_param("ssissi", $indentificacion, $nombre, $activo, $usuario, $rol, $id);
  }

  if(!$up->execute()){
    $err = $up->error ?: 'Error al actualizar';
    $up->close();
    jexit(['success'=>false,'message'=>'No se pudo actualizar','detail'=>$err], 500);
  }
  $up->close();
  jexit(['success'=>true,'message'=>'Actualizado']);
}

/* ===================== TOGGLE ACTIVO ===================== */
if ($action === 'toggle') {
  $id = (int)($in['id'] ?? 0);
  $activo = (int)($in['activo'] ?? -1);

  if ($id <= 0) jexit(['success'=>false,'message'=>'ID inválido'], 422);
  if (!in_array($activo, [0,1], true)) jexit(['success'=>false,'message'=>'Activo inválido'], 422);

  $up = $db->prepare("UPDATE tbr_coordinador SET activo=? WHERE id=? LIMIT 1");
  if(!$up) jexit(['success'=>false,'message'=>'No se pudo preparar UPDATE'], 500);
  $up->bind_param("ii", $activo, $id);

  if(!$up->execute()){
    $err = $up->error ?: 'Error al actualizar';
    $up->close();
    jexit(['success'=>false,'message'=>'No se pudo actualizar','detail'=>$err], 500);
  }
  $up->close();
  jexit(['success'=>true,'message'=>'Estado actualizado']);
}

/* ===================== DELETE ===================== */
if ($action === 'delete') {
  $id = (int)($in['id'] ?? 0);
  if ($id <= 0) jexit(['success'=>false,'message'=>'ID inválido'], 422);

  $del = $db->prepare("DELETE FROM tbr_coordinador WHERE id=? LIMIT 1");
  if(!$del) jexit(['success'=>false,'message'=>'No se pudo preparar DELETE'], 500);
  $del->bind_param("i", $id);

  if(!$del->execute()){
    $err = $del->error ?: 'Error al eliminar';
    $del->close();
    jexit(['success'=>false,'message'=>'No se pudo eliminar','detail'=>$err], 500);
  }
  $del->close();
  jexit(['success'=>true,'message'=>'Eliminado']);
}

/* ===================== COBRO ===================== */
if ($action === 'cobro') {
  $id_coordinador = (int)($in['id_coordinador'] ?? 0);
  $abono = (float)($in['abono'] ?? 0);
  $observacion = trim((string)($in['observacion'] ?? ''));
  $id_punto_venta = (int)($in['id_punto_venta'] ?? 0);
  $id_canillita   = (int)($in['id_canillita'] ?? 0);

  if ($id_coordinador <= 0) jexit(['success'=>false,'message'=>'Coordinador inválido'], 422);
  if ($abono <= 0) jexit(['success'=>false,'message'=>'Abono inválido'], 422);

  $st = $db->prepare("SELECT saldo FROM tbr_coordinador WHERE id=? LIMIT 1");
  if(!$st) jexit(['success'=>false,'message'=>'Error consultando saldo'], 500);
  $st->bind_param("i", $id_coordinador);
  $st->execute();
  $row = $st->get_result()->fetch_assoc();
  $st->close();

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

  $saldoActual = (float)($row['saldo'] ?? 0);
  if ($abono > $saldoActual + 0.00001) jexit(['success'=>false,'message'=>'El abono no puede ser mayor al saldo actual'], 422);
  $saldoNuevo = $saldoActual - $abono;

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

  $db->begin_transaction();
  try {
    // historial (usa tu estructura de tbr_coordinador_saldo)
    $num_raspaditas = 0;
    $subtotal = $saldoActual;   // saldo anterior
    $descuento = $abono;        // abono
    $total_pagar = $saldoNuevo; // saldo nuevo

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

    $ins->bind_param(
      "siiddsdissi",
      $fecha_hora,
      $id_coordinador,
      $num_raspaditas,
      $subtotal,
      $descuento,
      $total_pagar,
      $observacion,
      $id_admin,
      $ipx,
      $tipo_pago,
      $id_canillita
    );
    if(!$ins->execute()){
      $err = $ins->error ?: 'Error insertando historial';
      $ins->close();
      throw new Exception($err);
    }
    $ins->close();

    $up = $db->prepare("UPDATE tbr_coordinador SET saldo=? WHERE id=? LIMIT 1");
    if(!$up) throw new Exception("No prepara update saldo");
    $up->bind_param("di", $saldoNuevo, $id_coordinador);
    if(!$up->execute()){
      $err = $up->error ?: 'Error actualizando saldo';
      $up->close();
      throw new Exception($err);
    }
    $up->close();

    $db->commit();
    jexit(['success'=>true,'message'=>'Cobro registrado']);
  } catch(Throwable $e){
    $db->rollback();
    jexit(['success'=>false,'message'=>'Error en cobro','detail'=>$e->getMessage()], 500);
  }
}

/* ===================== HISTORIAL ===================== */
if ($action === 'list_historial') {
  $id_coordinador = (int)($in['id_coordinador'] ?? 0);
  $desde = trim((string)($in['desde'] ?? ''));
  $hasta = trim((string)($in['hasta'] ?? ''));

  $w = [];
  $p = [];
  $t = '';

  if ($id_coordinador > 0) { $w[] = "cs.id_coordinador=?"; $t .= "i"; $p[] = $id_coordinador; }
  if ($desde !== '') { $w[] = "DATE(cs.fecha_hora) >= ?"; $t .= "s"; $p[] = $desde; }
  if ($hasta !== '') { $w[] = "DATE(cs.fecha_hora) <= ?"; $t .= "s"; $p[] = $hasta; }

  $where = $w ? ("WHERE " . implode(" AND ", $w)) : "";

  $sql = "
    SELECT cs.id, cs.fecha_hora, cs.id_coordinador,
           c.nombre AS coordinador,
           cs.subtotal AS saldo_anterior,
           cs.descuento AS abono,
           cs.total_pagar AS saldo_nuevo,
           cs.observacion
    FROM tbr_coordinador_saldo cs
    LEFT JOIN tbr_coordinador c ON c.id = cs.id_coordinador
    {$where}
    ORDER BY cs.id DESC
    LIMIT 1000
  ";

  $rows = [];
  if ($w) {
    $st = $db->prepare($sql);
    if(!$st) jexit(['success'=>false,'message'=>'Error preparando historial'], 500);
    $st->bind_param($t, ...$p);
    $st->execute();
    $res = $st->get_result();
    while ($r = $res->fetch_assoc()) $rows[] = $r;
    $st->close();
  } else {
    $res = $db->query($sql);
    if ($res) {
      while ($r = $res->fetch_assoc()) $rows[] = $r;
      $res->free();
    }
  }

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

/* ===================== ANULAR COBRO ===================== */
if ($action === 'anular_cobro') {
  $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);

  $st = $db->prepare("SELECT id, id_coordinador, subtotal FROM tbr_coordinador_saldo WHERE id=? LIMIT 1");
  if(!$st) jexit(['success'=>false,'message'=>'Error consultando cobro'], 500);
  $st->bind_param("i", $id_cobro);
  $st->execute();
  $row = $st->get_result()->fetch_assoc();
  $st->close();

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

  $id_coordinador = (int)$row['id_coordinador'];
  $saldo_anterior = (float)($row['subtotal'] ?? 0);

  $db->begin_transaction();
  try {
    $up = $db->prepare("UPDATE tbr_coordinador SET saldo=? WHERE id=? LIMIT 1");
    if(!$up) throw new Exception("No prepara reverse saldo");
    $up->bind_param("di", $saldo_anterior, $id_coordinador);
    if(!$up->execute()){
      $err = $up->error ?: 'Error revirtiendo saldo';
      $up->close();
      throw new Exception($err);
    }
    $up->close();

    // si quieres guardar el motivo antes de borrar
    $obsAnul = "ANULADO: {$motivo}";
    $uobs = $db->prepare("UPDATE tbr_coordinador_saldo SET observacion = CONCAT(?, ' | ', COALESCE(observacion,'')) WHERE id=? LIMIT 1");
    if ($uobs) {
      $uobs->bind_param("si", $obsAnul, $id_cobro);
      $uobs->execute();
      $uobs->close();
    }

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

    $db->commit();
    jexit(['success'=>true,'message'=>'Cobro anulado y saldo revertido']);
  } 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);