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

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

if (!isset($_SESSION['idusuario'], $_SESSION['usuario'])) {
  header("Location: ../raspadita/login.php"); exit;
}

require_once __DIR__ . '/../conex.php';
$db = $conn ?? null;
if (!$db instanceof mysqli) { http_response_code(500); die("Sin conexión BD"); }
mysqli_set_charset($db, 'utf8mb4');
@mysqli_query($db, "SET time_zone='-05:00'");

$idusuario = (int)$_SESSION['idusuario'];
$usuario   = htmlspecialchars((string)$_SESSION['usuario'], ENT_QUOTES, 'UTF-8');

// Permiso raspadita (igual que coordinador.php)
$raspPerm = 0;
$stmt = mysqli_prepare($db, "SELECT COALESCE(raspadita,0) raspadita FROM tbr_usuario WHERE idusuario=? LIMIT 1");
mysqli_stmt_bind_param($stmt, "i", $idusuario);
mysqli_stmt_execute($stmt);
$res = mysqli_stmt_get_result($stmt);
if ($row = mysqli_fetch_assoc($res)) $raspPerm = (int)$row['raspadita'];
mysqli_stmt_close($stmt);
if ($raspPerm !== 1) { http_response_code(403); die("Acceso denegado"); }

// CSRF
if (!isset($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(16));
$csrf = (string)$_SESSION['csrf'];
?>
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width,initial-scale=1"/>
  <title>Canillitas · Raspaditas</title>

  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
  <link href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css" rel="stylesheet">

  <style>
    body{background:#f4f6f9;}
    .sidebar{width:150px;background:#343a40;padding:20px;height:100vh;position:fixed;left:0;top:0;display:flex;flex-direction:column;align-items:center;}
    .sidebar a{color:#fff;text-decoration:none;padding:10px 15px;display:block;width:100%;text-align:center;}
    .sidebar a:hover{background:#495057;border-radius:8px;}
    .sidebar .active{font-weight:bold;color:#17a2b8;}
    .main-content{margin-left:0;transition:margin-left .3s;}
    @media(min-width:769px){.main-content{margin-left:150px;}}
    .badge-soft{background:rgba(23,162,184,.15);color:#0b7285;border:1px solid rgba(23,162,184,.35);}
    .card{border-radius:14px;}
    .table-sm th,.table-sm td{padding:.45rem .5rem;}
    .switch-wrap{display:flex;justify-content:center;}
    .modal .form-label{margin-bottom:.25rem;}
  </style>
</head>
<body>

<nav class="sidebar" id="sidebar">
  <?php $active='canillita'; include __DIR__ . '/menu_raspadita.php'; ?>
</nav>

<div class="main-content p-2 p-md-3">
  <nav class="navbar navbar-light bg-light rounded-3 mb-3">
    <div class="container-fluid">
      <span class="navbar-brand"><i class="fa-solid fa-user-tag"></i> Canillitas</span>
      <div class="ms-auto d-flex gap-2 align-items-center">
        <span class="badge badge-soft px-3 py-2"><i class="fa fa-user"></i> <?= $usuario ?></span>
        <span class="badge badge-soft px-3 py-2"><i class="fa fa-clock"></i> <span id="hora"></span></span>
      </div>
    </div>
  </nav>

  <div class="card">
    <div class="card-body">

      <div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-2">
        <h6 class="mb-0"><i class="fa-solid fa-list"></i> Listado</h6>
        <div class="d-flex gap-2">
          <button id="btnOpenHistorial" class="btn btn-outline-dark" type="button" onclick="openHistorial()">
            <i class="fa-solid fa-clock-rotate-left"></i> Historial
          </button>
          <button class="btn btn-primary" type="button" onclick="openCreate()">
            <i class="fa-solid fa-plus"></i> Nuevo
          </button>
        </div>
      </div>

      <div class="table-responsive">
        <table id="tbCan" class="table table-sm table-striped w-100">
          <thead>
            <tr>
              <th>#</th>
              <th>Canillita</th>
              <th class="text-center">Activo</th>
              <th class="text-end">Saldo</th>
              <th class="text-end">Acciones</th>
            </tr>
          </thead>
          <tbody></tbody>
        </table>
      </div>

    </div>
  </div>

</div>

<!-- Modal Canillita -->
<div class="modal fade" id="modalCan" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-md modal-dialog-centered">
    <div class="modal-content" style="border-radius:16px;">
      <div class="modal-header">
        <h5 class="modal-title" id="modalTitle"><i class="fa-solid fa-user-tag"></i> Canillita</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cerrar"></button>
      </div>

      <div class="modal-body">
        <input type="hidden" id="id">

        <div class="mb-2">
          <label class="form-label fw-semibold">Nombre</label>
          <input type="text" id="canillita" class="form-control" maxlength="80" placeholder="NOMBRE COMPLETO">
          <small class="text-muted">Se guardará en MAYÚSCULAS.</small>
        </div>

        <div class="mb-2">
          <label class="form-label fw-semibold">Saldo</label>
          <input type="text" id="saldo" class="form-control" value="0" readonly>
          <small class="text-muted">Saldo inicia en 0.</small>
        </div>

        <div class="form-check form-switch mt-2">
          <input class="form-check-input" type="checkbox" id="activo" checked>
          <label class="form-check-label" for="activo">Activo</label>
        </div>
      </div>

      <div class="modal-footer">
        <button class="btn btn-outline-secondary" data-bs-dismiss="modal">Cerrar</button>
        <button class="btn btn-primary" type="button" onclick="saveCan()">
          <i class="fa-solid fa-floppy-disk"></i> Guardar
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Modal Cobro -->
<div class="modal fade" id="modalCobro" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-md modal-dialog-centered">
    <div class="modal-content" style="border-radius:16px;">
      <div class="modal-header">
        <h5 class="modal-title" id="cobroTitle"><i class="fa-solid fa-cash-register"></i> Cobro</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cerrar"></button>
      </div>

      <div class="modal-body">
        <input type="hidden" id="cobro_id_canillita">

        <div class="mb-2">
          <label class="form-label fw-semibold">Canillita</label>
          <input type="text" id="cobro_nombre" class="form-control" readonly>
        </div>

        <div class="row g-2">
          <div class="col-12 col-md-6">
            <label class="form-label fw-semibold">Saldo actual</label>
            <input type="text" id="cobro_saldo_actual" class="form-control" readonly>
          </div>
          <div class="col-12 col-md-6">
            <label class="form-label fw-semibold">Abono</label>
            <input type="number" id="cobro_abono" class="form-control" min="0" step="0.01" placeholder="0.00">
          </div>
        </div>

        <div class="mt-2">
          <label class="form-label fw-semibold">Saldo resultante</label>
          <input type="text" id="cobro_saldo_nuevo" class="form-control fw-bold" readonly>
          <small class="text-muted">Se calcula automáticamente: saldo_actual - abono</small>
        </div>

        <div class="mt-2">
          <label class="form-label fw-semibold">Observación (opcional)</label>
          <input type="text" id="cobro_obs" class="form-control" maxlength="255" placeholder="Ej: pago parcial...">
        </div>
      </div>

      <div class="modal-footer">
        <button class="btn btn-outline-secondary" data-bs-dismiss="modal">Cerrar</button>
        <button class="btn btn-success" type="button" onclick="guardarCobro()">
          <i class="fa-solid fa-check"></i> Guardar cobro
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Modal Historial -->
<div class="modal fade" id="modalHistorial" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl modal-dialog-centered">
    <div class="modal-content" style="border-radius:16px;">
      <div class="modal-header">
        <h5 class="modal-title"><i class="fa-solid fa-clock-rotate-left"></i> Historial de Cobros</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cerrar"></button>
      </div>

      <div class="modal-body">
        <div class="row g-2 align-items-end mb-2">
          <div class="col-12 col-md-4">
            <label class="form-label fw-semibold">Canillita (ID opcional)</label>
            <input type="number" id="his_id_canillita" class="form-control" placeholder="Ej: 3">
          </div>
          <div class="col-6 col-md-3">
            <label class="form-label fw-semibold">Desde</label>
            <input type="date" id="his_desde" class="form-control">
          </div>
          <div class="col-6 col-md-3">
            <label class="form-label fw-semibold">Hasta</label>
            <input type="date" id="his_hasta" class="form-control">
          </div>
          <div class="col-12 col-md-2 d-grid">
            <button class="btn btn-primary" type="button" onclick="loadHistorial()">
              <i class="fa-solid fa-magnifying-glass"></i> Buscar
            </button>
          </div>
        </div>

        <div class="table-responsive">
          <table id="tbHist" class="table table-sm table-striped w-100">
            <thead>
              <tr>
                <th>#</th>
                <th>Fecha</th>
                <th>Canillita</th>
                <th class="text-end">Saldo ant.</th>
                <th class="text-end">Abono</th>
                <th class="text-end">Saldo nuevo</th>
                <th>Obs.</th>
                <th class="text-end">Acción</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>

        <small class="text-muted d-block mt-2">
          * Para anular: se revierte el saldo y queda auditoría (si tienes tabla de anulaciones).
        </small>
      </div>

      <div class="modal-footer">
        <button class="btn btn-outline-secondary" data-bs-dismiss="modal">Cerrar</button>
      </div>
    </div>
  </div>
</div>

<script>
  window.CSRF = <?= json_encode($csrf, JSON_UNESCAPED_UNICODE) ?>;
</script>

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script>

<script>
  // Hora EC
  (function(){
    function pad2(n){return String(n).padStart(2,'0');}
    function tick(){
      const now = new Date();
      const ec  = new Date(now.toLocaleString("en-US",{timeZone:"America/Guayaquil"}));
      const el = document.getElementById('hora');
      if (el) el.textContent = pad2(ec.getHours())+":"+pad2(ec.getMinutes());
    }
    tick(); setInterval(tick, 30000);
  })();

  async function api(action, payload){
    const r = await fetch('api/canillita_admin_actions.php', {
      method:'POST',
      headers:{
        'Content-Type':'application/json',
        'X-CSRF-Token': (window.CSRF || '')
      },
      body: JSON.stringify({ action, ...(payload||{}) })
    });
    const txt = await r.text();
    let j=null; try{ j=JSON.parse(txt); }catch(e){}
    if(!r.ok) throw new Error((j && (j.message||j.detail)) ? (j.message||j.detail) : (txt.slice(0,200) || `HTTP ${r.status}`));
    if(!j || j.success !== true) throw new Error((j && (j.message||j.detail)) ? (j.message||j.detail) : 'Error');
    return j;
  }

  function esc(s){ return String(s ?? '').replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[m])); }
  function money(v){ const n = parseFloat(v||0); return '$' + n.toFixed(2); }
  function toNumber(x){
    const s = String(x ?? '0').replace('$','').replace(',', '.');
    const n = parseFloat(s);
    return isNaN(n) ? 0 : n;
  }

  let dt = null;
  let dtHist = null;

  const modal = new bootstrap.Modal(document.getElementById('modalCan'));
  const modalCobro = new bootstrap.Modal(document.getElementById('modalCobro'));
  const modalHistorial = new bootstrap.Modal(document.getElementById('modalHistorial'));

  function openCreate(){
    document.getElementById('modalTitle').innerHTML = '<i class="fa-solid fa-plus"></i> Nuevo Canillita';
    document.getElementById('id').value = '';
    document.getElementById('canillita').value = '';
    document.getElementById('saldo').value = '0';
    document.getElementById('activo').checked = true;
    modal.show();
    setTimeout(()=>document.getElementById('canillita')?.focus(), 150);
  }

  function openEdit(row){
    document.getElementById('modalTitle').innerHTML = '<i class="fa-solid fa-pen"></i> Editar Canillita';
    document.getElementById('id').value = row.id;
    document.getElementById('canillita').value = row.canillita || '';
    document.getElementById('saldo').value = row.saldo || '0';
    document.getElementById('activo').checked = parseInt(row.activo||0,10) === 1;
    modal.show();
  }

  function openCobro(row){
    const id = parseInt(row.id, 10) || 0;
    const saldo = toNumber(row.saldo);

    document.getElementById('cobro_id_canillita').value = String(id);
    document.getElementById('cobro_nombre').value = (row.canillita || '');
    document.getElementById('cobro_saldo_actual').value = money(saldo);
    document.getElementById('cobro_abono').value = '';
    document.getElementById('cobro_obs').value = '';
    document.getElementById('cobro_saldo_nuevo').value = money(saldo);

    modalCobro.show();
    setTimeout(()=>document.getElementById('cobro_abono')?.focus(), 150);
  }

  function recalcularCobro(){
    const saldoActual = toNumber(document.getElementById('cobro_saldo_actual').value || '0');
    const abono = toNumber(document.getElementById('cobro_abono').value || '0');
    document.getElementById('cobro_saldo_nuevo').value = money(saldoActual - abono);
  }

  document.addEventListener('input', (ev)=>{
    if (ev.target && ev.target.id === 'cobro_abono') recalcularCobro();
    if (ev.target && ev.target.id === 'canillita') {
      ev.target.value = String(ev.target.value || '').toUpperCase();
    }
  });

  async function guardarCobro(){
    const id_canillita = parseInt(document.getElementById('cobro_id_canillita').value || '0', 10) || 0;
    const saldoActual = toNumber(document.getElementById('cobro_saldo_actual').value || '0');
    const abono = toNumber(document.getElementById('cobro_abono').value || '0');
    const observacion = (document.getElementById('cobro_obs').value || '').trim();

    if(id_canillita <= 0) return Swal.fire('Error','ID inválido.','error');
    if(abono <= 0) return Swal.fire('Atención','Ingrese un abono mayor a 0.','warning');
    if(abono > saldoActual) return Swal.fire('Atención','El abono no puede ser mayor al saldo actual.','warning');

    try{
      const j = await api('cobro', { id_canillita, abono, observacion });
      Swal.fire('OK', j.message || 'Cobro registrado', 'success');
      modalCobro.hide();
      await loadTable();
    }catch(e){
      Swal.fire('Error', e.message || 'Error', 'error');
    }
  }

  async function loadTable(){
    const j = await api('list', {});
    dt.clear();

    (j.data || []).forEach((r, idx)=>{
      const sw = `
        <div class="switch-wrap">
          <div class="form-check form-switch m-0">
            <input class="form-check-input sw-activo" type="checkbox"
              data-id="${esc(r.id)}" ${parseInt(r.activo,10)===1 ? 'checked' : ''}>
          </div>
        </div>
      `;

      const btns = `
        <div class="d-flex justify-content-end gap-1">
          <button class="btn btn-outline-success btn-sm" type="button" title="Cobro"
            onclick='openCobro(${JSON.stringify(r)})'>
            <i class="fa-solid fa-cash-register"></i>
          </button>
          <button class="btn btn-outline-primary btn-sm" type="button" title="Editar"
            onclick='openEdit(${JSON.stringify(r)})'>
            <i class="fa-solid fa-pen"></i>
          </button>
          <button class="btn btn-outline-danger btn-sm" type="button" title="Eliminar"
            onclick='delCan(${parseInt(r.id,10)})'>
            <i class="fa-solid fa-trash"></i>
          </button>
        </div>
      `;

      dt.row.add([
        idx + 1,
        `<b>${esc(r.canillita || '')}</b>`,
        sw,
        `<span class="fw-bold">${money(r.saldo)}</span>`,
        btns
      ]);
    });

    dt.draw(false);
  }

  async function saveCan(){
    const id = parseInt(document.getElementById('id').value || '0', 10) || 0;
    const canillita = (document.getElementById('canillita').value || '').trim().toUpperCase();
    const activo = document.getElementById('activo').checked ? 1 : 0;

    if(!canillita) return Swal.fire('Atención','Ingrese el nombre.','warning');

    try{
      const payload = { id, canillita, activo };
      const j = await api(id>0 ? 'update' : 'create', payload);
      Swal.fire('OK', j.message || 'Guardado', 'success');
      modal.hide();
      await loadTable();
    }catch(e){
      Swal.fire('Error', e.message || 'Error', 'error');
    }
  }

  async function delCan(id){
    const r = await Swal.fire({
      title:'Eliminar',
      text:'¿Deseas eliminar este canillita?',
      icon:'warning',
      showCancelButton:true,
      confirmButtonText:'Sí, eliminar',
      cancelButtonText:'Cancelar'
    });
    if(!r.isConfirmed) return;

    try{
      const j = await api('delete', { id });
      Swal.fire('OK', j.message || 'Eliminado', 'success');
      await loadTable();
    }catch(e){
      Swal.fire('Error', e.message || 'Error', 'error');
    }
  }

  function openHistorial(){
    if (!dtHist) {
      dtHist = $('#tbHist').DataTable({
        searching:true,
        lengthChange:false,
        pageLength:25,
        responsive:true,
        ordering:false,
        language:{url:"https://cdn.datatables.net/plug-ins/1.13.8/i18n/es-ES.json"},
        columnDefs:[
          {targets:0, className:'text-center', width:'40px'},
          {targets:[3,4,5,7], className:'text-end'}
        ]
      });
    }
    modalHistorial.show();
    setTimeout(()=>{
      document.getElementById('his_id_canillita')?.focus();
      loadHistorial();
    }, 200);
  }

  async function loadHistorial(){
    const id_canillita = parseInt(document.getElementById('his_id_canillita').value || '0', 10) || 0;
    const desde = (document.getElementById('his_desde').value || '').trim();
    const hasta = (document.getElementById('his_hasta').value || '').trim();

    const payload = {};
    if (id_canillita > 0) payload.id_canillita = id_canillita;
    if (desde) payload.desde = desde;
    if (hasta) payload.hasta = hasta;

    try{
      const j = await api('list_historial', payload);
      dtHist.clear();

      (j.data || []).forEach((r, idx)=>{
        const btnAnular = `
          <button class="btn btn-outline-danger btn-sm" type="button" title="Anular"
            onclick="anularCobro(${parseInt(r.id,10)})">
            <i class="fa-solid fa-ban"></i>
          </button>
        `;
        dtHist.row.add([
          idx + 1,
          esc(r.fecha_hora || ''),
          esc(r.canillita || ('ID '+r.id_canillita)),
          `<span class="fw-bold">${money(r.saldo_anterior)}</span>`,
          `<span class="fw-bold">${money(r.abono)}</span>`,
          `<span class="fw-bold">${money(r.saldo_nuevo)}</span>`,
          esc(r.observacion || ''),
          btnAnular
        ]);
      });

      dtHist.draw(false);
    }catch(e){
      Swal.fire('Error', e.message || 'Error', 'error');
    }
  }

  // ✅ FIX DEFINITIVO: cerrar modal antes de SweetAlert
  async function anularCobro(id_cobro){
    try { modalHistorial.hide(); } catch(e){}

    await new Promise(res=>{
      const el = document.getElementById('modalHistorial');
      if(!el) return res();
      const done = ()=>{ el.removeEventListener('hidden.bs.modal', done); res(); };
      el.addEventListener('hidden.bs.modal', done);
      setTimeout(res, 250);
    });

    const r = await Swal.fire({
      title:'Anular cobro',
      input:'text',
      inputLabel:'Motivo (obligatorio)',
      inputPlaceholder:'Ej: Cobro duplicado',
      showCancelButton:true,
      confirmButtonText:'Sí, anular',
      cancelButtonText:'Cancelar',
      allowOutsideClick:false,
      didOpen: () => {
        const inp = Swal.getInput();
        if (inp) inp.focus();
      },
      inputValidator: (v)=> !v ? 'Ingrese el motivo' : undefined
    });

    if(!r.isConfirmed){
      try { modalHistorial.show(); } catch(e){}
      return;
    }

    try{
      const j = await api('anular_cobro', { id_cobro, motivo: r.value });
      await Swal.fire('OK', j.message || 'Anulado', 'success');
      await loadTable();

      try { modalHistorial.show(); } catch(e){}
      setTimeout(()=>loadHistorial(), 250);

    }catch(e){
      await Swal.fire('Error', e.message || 'Error', 'error');
      try { modalHistorial.show(); } catch(err){}
    }
  }

  // Switch activo
  document.addEventListener('change', async (ev)=>{
    const t = ev.target;
    if(!t || !t.classList || !t.classList.contains('sw-activo')) return;

    const id = parseInt(t.getAttribute('data-id') || '0', 10) || 0;
    const activo = t.checked ? 1 : 0;

    try{
      await api('toggle', { id, activo });
    }catch(e){
      t.checked = !t.checked;
      Swal.fire('Error', e.message || 'No se pudo cambiar estado', 'error');
    }
  });

  // FIX ARIA-HIDDEN
  (function(){
    const modalIds = ['modalCan','modalCobro','modalHistorial'];
    modalIds.forEach(id=>{
      const m = document.getElementById(id);
      if(!m) return;
      m.addEventListener('hide.bs.modal', () => {
        const ae = document.activeElement;
        if (ae && m.contains(ae)) ae.blur();
      });
    });

    const mh = document.getElementById('modalHistorial');
    if (mh) {
      mh.addEventListener('hidden.bs.modal', () => {
        document.getElementById('btnOpenHistorial')?.focus();
      });
    }
  })();

  document.addEventListener('DOMContentLoaded', async ()=>{
    dt = $('#tbCan').DataTable({
      searching:true,
      lengthChange:false,
      pageLength:25,
      responsive:true,
      ordering:false,
      language:{url:"https://cdn.datatables.net/plug-ins/1.13.8/i18n/es-ES.json"},
      columnDefs:[
        {targets:0, className:'text-center', width:'40px'},
        {targets:2, orderable:false, searchable:false, className:'text-center', width:'90px'},
        {targets:[3,4], className:'text-end'}
      ]
    });

    await loadTable();
  });
</script>

</body>
</html>
