<?php
/**
 * calcu-v2.php — Calculadora Tributaria (rediseño)
 *  - Motor de cálculo método SIN (ver motor_siat.php), validado vs Vistas de Cargo.
 *  - Modos: "Una deuda" y "Varias deudas" (consolidado estilo Vista de Cargo).
 *  - Transparencia total: cada monto muestra su "memoria de cálculo" (DESIGN §8),
 *    inline en modo una-deuda y en popover (burbuja) en modo varias-deudas.
 *  - UI 100% sobre design-tokens.css (sin colores/medidas inventadas).
 *
 *  UFV: API central ufv_api (https://nitro.com.de/ufv/api.php), fallback BCB.
 *  Endpoints JSON de este mismo archivo:
 *    ?action=get_ufv&fecha=YYYY-MM-DD     -> {"ufv": <float|null>}
 *    ?action=calc  (POST JSON con datos)  -> desglose completo del motor
 */

require_once __DIR__ . '/motor_siat.php';
require_once __DIR__ . '/vencimientos.php';

// ---- API: sugerir fecha de vencimiento (dataset por año) ------------------
if (isset($_GET['action']) && $_GET['action'] === 'vencimiento') {
    header('Content-Type: application/json');
    header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
    $nit = (isset($_GET['nit']) && $_GET['nit'] !== '') ? (int)$_GET['nit'] : null;
    echo json_encode(['fecha' => Vencimientos::sugerir($_GET['periodo'] ?? '', $_GET['impuesto'] ?? '', $nit)]);
    exit;
}

// ---- API: UFV de una fecha ------------------------------------------------
if (isset($_GET['action']) && $_GET['action'] === 'get_ufv' && isset($_GET['fecha'])) {
    header('Content-Type: application/json');
    header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
    $m = new MotorDeudaSIN();
    echo json_encode(['ufv' => $m->getUFV($_GET['fecha'])]);
    exit;
}

// ---- API: cálculo de una deuda -------------------------------------------
if (isset($_GET['action']) && $_GET['action'] === 'calc') {
    header('Content-Type: application/json');
    header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
    $in = json_decode(file_get_contents('php://input'), true);
    if (!is_array($in)) $in = $_POST;
    $m = new MotorDeudaSIN();
    echo json_encode($m->calcular($in));
    exit;
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculadora tributaria · boliviaimpuestos</title>
<link rel="icon" href="assets/marca/isotipo-bib.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="design-tokens.css">
<style>
  * { margin:0; padding:0; box-sizing:border-box; }
  body {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    color: var(--text-primary);
    background: var(--bg-canvas);
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;
  }
  .num { font-variant-numeric: tabular-nums; font-feature-settings: var(--num-tabular); }
  .mono { font-family: var(--font-mono); }

  /* Header */
  .app-header {
    display:flex; align-items:center; gap: var(--space-3);
    height:56px; padding:0 var(--space-6);
    background: var(--bg-surface); border-bottom:1px solid var(--border-default);
  }
  .app-header img { height:28px; width:auto; }
  .app-header__section { font-size: var(--text-lg); font-weight:500; color: var(--text-primary); }

  .wrap { max-width: var(--container-max); margin:0 auto; padding: var(--space-6); }

  /* Toggle de modo */
  .mode-toggle { display:inline-flex; background: var(--bg-subtle); border:1px solid var(--border-default);
    border-radius: var(--radius-md); padding:3px; gap:3px; }
  .mode-toggle button {
    border:0; background:transparent; cursor:pointer; font-family:inherit;
    font-size: var(--text-base); font-weight:500; color: var(--text-secondary);
    padding: 7px var(--space-4); border-radius: var(--radius-sm); transition: all .12s;
  }
  .mode-toggle button.active { background: var(--bg-surface); color: var(--color-azure-600); box-shadow: var(--shadow-xs); }

  /* Barra común */
  .common-bar { display:grid; grid-template-columns: repeat(12,1fr); gap: var(--space-4) var(--space-5);
    margin: var(--space-5) 0; padding: var(--space-5); background: var(--bg-surface);
    border:1px solid var(--border-default); border-radius: var(--radius-lg); }

  /* Campos */
  .field { display:flex; flex-direction:column; }
  .field label { font-size: var(--text-base); font-weight:500; color: var(--text-secondary); margin-bottom: var(--space-2); }
  .field .hint { font-size: var(--text-xs); color: var(--text-tertiary); margin-top: var(--space-1); }
  .input, .select {
    height: var(--control-height); border:1px solid var(--border-default); border-radius: var(--radius-md);
    padding:0 var(--space-3); font-family:inherit; font-size: var(--text-base); color: var(--text-primary);
    background: var(--bg-surface); width:100%; transition: border-color .12s, box-shadow .12s;
  }
  .input:hover, .select:hover { border-color: var(--border-strong); }
  .input:focus, .select:focus { outline:0; border-color: var(--color-brand-400); box-shadow: var(--focus-ring); }
  .input.right { text-align:right; }
  .input-addon { position:relative; }
  .input-addon > span { position:absolute; left:var(--space-3); top:50%; transform:translateY(-50%);
    color: var(--text-tertiary); font-size: var(--text-base); pointer-events:none; }
  .input-addon .input { padding-left: 32px; }

  /* Botones */
  .btn { height: var(--control-height); padding:0 var(--space-4); border-radius: var(--radius-md);
    font-family:inherit; font-size: var(--text-base); font-weight:500; cursor:pointer; border:0;
    display:inline-flex; align-items:center; gap: var(--space-2); transition: all .12s; }
  .btn-primary { background: var(--color-brand-500); color:#fff; }
  .btn-primary:hover { background: var(--color-brand-600); }
  .btn-primary:active { background: var(--color-brand-700); transform: scale(.98); }
  .btn-secondary { background: var(--bg-surface); color: var(--text-primary); border:1px solid var(--border-strong); }
  .btn-secondary:hover { background: var(--bg-subtle); }
  .btn-ghost { background:transparent; color: var(--color-brand-600); }
  .btn-ghost:hover { background: var(--bg-subtle); }
  .btn-danger { background: var(--bg-surface); color: var(--color-danger-fg); border:1px solid var(--color-danger-border); }

  /* Tarjetas */
  .card { background: var(--bg-surface); border:1px solid var(--border-default); border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6); }
  .card__head { display:flex; align-items:center; justify-content:space-between; margin-bottom: var(--space-4); }
  .card__title { font-size: var(--text-lg); font-weight:500; }

  /* Grid una-deuda */
  .single-grid { display:grid; grid-template-columns: 380px 1fr; gap: var(--space-5); align-items:start; }
  @media (max-width: 860px){ .single-grid { grid-template-columns:1fr; } .common-bar > .field { grid-column: span 12 !important; } }

  /* Hoja de resultado (concepto … valor) */
  .sheet { width:100%; border-collapse:collapse; }
  .sheet td { padding: var(--space-3) 0; font-size: var(--text-base); }
  .sheet td:last-child { text-align:right; }
  .sheet .label { color: var(--text-secondary); }
  .sheet .op { color: var(--text-tertiary); width:18px; }
  .sheet tr.step td { color: var(--text-secondary); }
  .sheet tr.total td { border-top:1px solid var(--border-strong); font-weight:600; color: var(--text-primary);
    font-size: var(--text-lg); padding-top: var(--space-4); }
  .info-btn { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px;
    margin-left: var(--space-2); border-radius: var(--radius-full); border:1px solid var(--border-strong);
    color: var(--text-tertiary); font-size:11px; cursor:pointer; background: var(--bg-surface); }
  .info-btn:hover { color: var(--color-azure-600); border-color: var(--color-azure-300); }
  .info-btn svg { width:11px; height:11px; }

  /* Íconos genéricos */
  .ic { width:16px; height:16px; flex-shrink:0; vertical-align:middle; }
  .btn .ic { margin-right:-2px; }
  .callout { display:flex; align-items:center; gap: var(--space-2); }
  .callout .ic { color: var(--color-info-fg); }
  .memoria__title .ic, .card__title .ic { color: var(--color-azure-600); }

  /* Footer / fuente de datos */
  .foot { display:flex; flex-wrap:wrap; gap: var(--space-2) var(--space-6); margin-top: var(--space-8);
    padding-top: var(--space-4); border-top:1px solid var(--border-default);
    font-size: var(--text-xs); color: var(--text-tertiary); }
  .foot__item { display:inline-flex; align-items:center; gap: var(--space-2); }
  .foot__item .ic { width:14px; height:14px; color: var(--color-azure-600); }

  /* Memoria de cálculo */
  .memoria { background: var(--bg-surface); border:1px solid var(--border-default); border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6); margin-top: var(--space-5); }
  .memoria__title { font-size: var(--text-lg); font-weight:500; margin-bottom: var(--space-4); display:flex; align-items:center; gap:var(--space-2); }
  .memoria .sheet td { padding: var(--space-2) 0; }
  .memoria .formula { font-family: var(--font-mono); font-size:13px; color: var(--text-tertiary); }
  .tramo-tabla { width:100%; border-collapse:collapse; margin: var(--space-3) 0; }
  .tramo-tabla th { background: var(--bg-subtle); font-size: var(--text-xs); font-weight:500; color: var(--text-secondary);
    text-align:left; padding: var(--space-2) var(--space-3); }
  .tramo-tabla th.r, .tramo-tabla td.r { text-align:right; }
  .tramo-tabla td { padding: var(--space-2) var(--space-3); border-bottom:1px solid var(--border-default); font-size: var(--text-base); }
  .pill { display:inline-block; padding:2px 8px; border-radius: var(--radius-full); font-size: var(--text-xs); font-weight:500; }
  .pill-4 { background: var(--color-info-bg); color: var(--color-info-fg); }
  .pill-6 { background: var(--color-warning-bg); color: var(--color-warning-fg); }
  .pill-10{ background: var(--color-danger-bg); color: var(--color-danger-fg); }

  /* Tabla multi-deuda */
  .table-wrap { overflow-x:auto; border:1px solid var(--border-default); border-radius: var(--radius-lg); background:var(--bg-surface); }
  table.multi { width:100%; border-collapse:collapse; min-width:880px; }
  table.multi thead th { background: var(--bg-subtle); font-size: var(--text-xs); font-weight:500; color: var(--text-secondary);
    text-align:left; padding: var(--space-3); white-space:nowrap; }
  table.multi thead th.r { text-align:right; }
  table.multi tbody td { padding: var(--space-2) var(--space-3); border-bottom:1px solid var(--border-default); font-size: var(--text-base); }
  table.multi tbody td.r { text-align:right; }
  table.multi tbody tr:hover { background: var(--bg-subtle); }
  table.multi tbody td .input, table.multi tbody td .select { height:32px; }
  table.multi tfoot td { padding: var(--space-3); border-top:2px solid var(--border-strong);
    background: var(--bg-subtle); font-weight:600; }
  table.multi tfoot td.r { text-align:right; }
  .row-warn { background: var(--color-warning-bg) !important; }
  .col-san { display:none; }
  table.multi.has-sancion .col-san { display:table-cell; }
  .val-cell { display:inline-flex; align-items:center; gap:6px; justify-content:flex-end; }

  /* Popover (burbuja) */
  .popover { position:absolute; z-index:50; width: 340px; background: var(--bg-surface);
    border:1px solid var(--border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
    padding: var(--space-4) var(--space-5); display:none; }
  .popover.show { display:block; }
  .popover__head { display:flex; align-items:center; justify-content:space-between; margin-bottom: var(--space-2); }
  .popover__title { font-size: var(--text-base); font-weight:600; }
  .popover__pin { cursor:pointer; color: var(--text-tertiary); font-size: var(--text-xs); border:0; background:transparent;
    display:inline-flex; align-items:center; gap:4px; }
  .popover__pin svg { width:12px; height:12px; }

  .callout { border-left:3px solid var(--color-info-border); background: var(--color-info-bg); color: var(--color-info-fg);
    padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); font-size: var(--text-base); margin: var(--space-4) 0; }
  .toolbar { display:flex; gap: var(--space-3); margin: var(--space-4) 0; flex-wrap:wrap; }
  .err { color: var(--color-danger-fg); font-size: var(--text-base); }
  .hide { display:none !important; }
  .metric-row { display:grid; grid-template-columns: repeat(4,1fr); gap: var(--space-4); margin-top: var(--space-4); }
  .metric { background: var(--bg-subtle); border-radius: var(--radius-md); padding: var(--space-4); }
  .metric .k { font-size: var(--text-xs); color: var(--text-secondary); }
  .metric .v { font-size: var(--text-2xl); font-weight:600; margin-top: var(--space-1); }
  @media (max-width:860px){ .metric-row { grid-template-columns: repeat(2,1fr); } }
</style>
</head>
<body>

<header class="app-header">
  <img src="assets/marca/isotipo-bib.png" alt="boliviaimpuestos">
  <span class="app-header__section">Calculadora tributaria</span>
</header>

<div class="wrap">

  <!-- Modo + barra común -->
  <div class="mode-toggle" role="tablist">
    <button id="tabUna" class="active" onclick="setMode('una')">Una deuda</button>
    <button id="tabVarias" onclick="setMode('varias')">Varias deudas</button>
  </div>

  <div class="common-bar">
    <div class="field" style="grid-column: span 3;">
      <label for="fechaPago">Fecha de pago / cálculo</label>
      <input type="date" id="fechaPago" class="input">
      <span class="hint" id="ufvPagoHint">UFV: —</span>
    </div>
    <div class="field" style="grid-column: span 2;">
      <label for="nitDigito">Último dígito NIT</label>
      <input type="number" id="nitDigito" class="input" min="0" max="9" step="1" placeholder="—">
      <span class="hint">Opcional. Sugiere el vencimiento.</span>
    </div>
    <div class="field" style="grid-column: span 4;">
      <label for="tipoCalc">Tipo de cálculo</label>
      <select id="tipoCalc" class="select">
        <option value="voluntario">Pago voluntario (tributo + mant. + interés)</option>
        <option value="sancion">Con sanción por omisión (60%)</option>
      </select>
    </div>
    <div class="field" style="grid-column: span 3;">
      <label for="multaDF">Multa deberes formales (UFV)</label>
      <select id="multaDF" class="select">
        <option value="0">Sin multa</option>
        <option value="50">50 UFV (persona natural)</option>
        <option value="100">100 UFV (persona jurídica)</option>
      </select>
    </div>
    <div class="field" style="grid-column: span 5;">
      <label for="precisionFactor">Redondeo del interés</label>
      <select id="precisionFactor" class="select">
        <option value="completa">Precisión completa (RND 102500000013)</option>
        <option value="5dec">Factor a 5 decimales (algunas liquidaciones SIN)</option>
      </select>
      <span class="hint">Precisión completa es lo normado; use «5 dec.» solo para reconciliar una liquidación puntual.</span>
    </div>
  </div>

  <!-- ====================== MODO UNA DEUDA ====================== -->
  <div id="modeUna">
    <div class="single-grid">
      <div class="card">
        <div class="card__head"><span class="card__title">Datos de la deuda</span></div>
        <div class="field" style="margin-bottom: var(--space-4);">
          <label for="periodoU">Periodo fiscal</label>
          <input type="month" id="periodoU" class="input">
        </div>
        <div class="field" style="margin-bottom: var(--space-4);">
          <label for="impuestoU">Impuesto</label>
          <select id="impuestoU" class="select">
            <option>IVA</option><option>IT</option><option>IUE</option><option>RC-IVA</option><option>Otro</option>
          </select>
        </div>
        <div class="field" style="margin-bottom: var(--space-4);">
          <label for="fechaVencU">Fecha de vencimiento</label>
          <input type="date" id="fechaVencU" class="input">
          <span class="hint" id="ufvVencHint">UFV: —</span>
        </div>
        <div class="field" style="margin-bottom: var(--space-5);">
          <label for="tributoU">Tributo omitido</label>
          <div class="input-addon"><span>Bs</span><input type="number" id="tributoU" class="input right" placeholder="0,00"></div>
        </div>
        <button class="btn btn-primary" style="width:100%; justify-content:center;" onclick="calcularUna()">Calcular</button>
      </div>

      <div>
        <div class="card" id="resultUna">
          <div class="card__head"><span class="card__title">Resultado</span>
            <span style="display:flex;align-items:center;gap:var(--space-3)">
              <span class="hint" id="resultFecha"></span>
              <button class="btn btn-ghost" id="btnPrintUna" onclick="generarReporte()" style="display:none"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/></svg>Imprimir / PDF</button>
            </span>
          </div>
          <div id="resultUnaBody"><p class="hint">Complete los datos y presione «Calcular».</p></div>
        </div>
        <div id="memoriaUna"></div>
      </div>
    </div>
  </div>

  <!-- ====================== MODO VARIAS DEUDAS ====================== -->
  <div id="modeVarias" class="hide">
    <div class="toolbar">
      <button class="btn btn-secondary" onclick="agregarFila()"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>Agregar fila</button>
      <button class="btn btn-ghost" onclick="calcularTodas()"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>Recalcular todo</button>
      <button class="btn btn-ghost" onclick="generarReporte()" style="margin-left:auto"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/></svg>Imprimir / PDF</button>
    </div>
    <div class="table-wrap">
      <table class="multi">
        <thead>
          <tr>
            <th>Periodo</th><th>Impuesto</th><th>F. vencimiento</th>
            <th class="r">Tributo omitido (Bs)</th>
            <th class="r">TO actualiz. (UFV)</th>
            <th class="r">Interés (UFV)</th>
            <th class="r">Deuda (UFV)</th>
            <th class="r col-san">Sanción 60% (UFV)</th>
            <th class="r">Total (Bs)</th>
            <th></th>
          </tr>
        </thead>
        <tbody id="multiBody"></tbody>
        <tfoot>
          <tr>
            <td colspan="4">Total general</td>
            <td class="r num" id="totUFVc">—</td>
            <td class="r num" id="totUFVi">—</td>
            <td class="r num" id="totUFVd">—</td>
            <td class="r num col-san" id="totUFVs">—</td>
            <td class="r num" id="totBs">Bs 0,00</td>
            <td></td>
          </tr>
        </tfoot>
      </table>
    </div>
    <div class="callout"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>Pase el cursor (o toque) sobre el ícono de cada monto calculado para ver su memoria de cálculo. Haga clic para fijarla.</div>
  </div>

  <footer class="foot">
    <span class="foot__item">
      <svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="22" x2="21" y2="22"/><line x1="6" y1="18" x2="6" y2="11"/><line x1="10" y1="18" x2="10" y2="11"/><line x1="14" y1="18" x2="14" y2="11"/><line x1="18" y1="18" x2="18" y2="11"/><polygon points="12 2 20 7 4 7"/></svg>
      UFV oficiales obtenidas en línea del Banco Central de Bolivia (BCB).
    </span>
    <span class="foot__item">Cálculo conforme al Art. 47 de la Ley 2492 y la R.N.D. 102500000013.</span>
  </footer>
</div>

<!-- Popover global para memorias en modo tabla -->
<div class="popover" id="pop"></div>

<script>
// ---------------- utilidades de formato ----------------
function fmtBs(n){ if(n===null||n===undefined||isNaN(n)) return '—';
  return 'Bs ' + Number(n).toLocaleString('es-BO',{minimumFractionDigits:2,maximumFractionDigits:2}); }
function fmtUFV(n){ if(n===null||n===undefined||isNaN(n)) return '—';
  return Number(n).toLocaleString('es-BO',{minimumFractionDigits:5,maximumFractionDigits:5}); }
function fmtFecha(s){ if(!s) return ''; const [y,m,d]=s.split('-'); return `${d}/${m}/${y}`; }
function esFechaValida(s){ const m=/^(\d{4})-(\d{2})-(\d{2})$/.exec(s||''); return m && +m[1]>=2001 && +m[1]<=2100; }

// Íconos (línea fina, estilo Mercury). Heredan currentColor.
const SVG = {
  info:  '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>',
  calc:  '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="2" width="16" height="20" rx="2"/><line x1="8" y1="6" x2="16" y2="6"/><line x1="8" y1="18" x2="16" y2="18"/><circle cx="8" cy="11" r=".4" fill="currentColor"/><circle cx="12" cy="11" r=".4" fill="currentColor"/><circle cx="16" cy="11" r=".4" fill="currentColor"/><circle cx="8" cy="14.5" r=".4" fill="currentColor"/><circle cx="12" cy="14.5" r=".4" fill="currentColor"/></svg>',
  trash: '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',
  x:     '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',
};

// ---------------- estado ----------------
let reqSeq = {};
let ultimoResultadoUna = null;
async function getUFV(fecha){
  if(!esFechaValida(fecha)) return null;
  const r = await fetch(`?action=get_ufv&fecha=${fecha}&_=${Date.now()}`, {cache:'no-store'});
  const d = await r.json(); return d.ufv;
}
async function calcular(payload){
  const r = await fetch('?action=calc', {method:'POST', cache:'no-store',
    headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload)});
  return await r.json();
}
function opcionesComunes(){
  return {
    fechaPago: document.getElementById('fechaPago').value,
    sancionOmision: document.getElementById('tipoCalc').value === 'sancion',
    multaDF: parseFloat(document.getElementById('multaDF').value || 0),
    precisionFactor: document.getElementById('precisionFactor').value === '5dec' ? '5dec' : 'completa',
  };
}

// Sugiere y autocompleta la fecha de vencimiento (no pisa lo que el usuario escribió a mano).
async function sugerirVencDOM(elFecha, periodo, impuesto, nit){
  if(!elFecha || !periodo || !impuesto) return false;
  if(elFecha.value && elFecha.value !== (elFecha.dataset.auto||'')) return false;
  try{
    const r = await fetch(`?action=vencimiento&periodo=${periodo}&impuesto=${encodeURIComponent(impuesto)}&nit=${(nit===undefined||nit===null)?'':nit}`, {cache:'no-store'});
    const d = await r.json();
    if(d && d.fecha){ elFecha.value = d.fecha; elFecha.dataset.auto = d.fecha; return true; }
  }catch(e){}
  return false;
}

// ---------------- modo ----------------
function setMode(m){
  document.getElementById('tabUna').classList.toggle('active', m==='una');
  document.getElementById('tabVarias').classList.toggle('active', m==='varias');
  document.getElementById('modeUna').classList.toggle('hide', m!=='una');
  document.getElementById('modeVarias').classList.toggle('hide', m!=='varias');
}

// ---------------- UFV hints ----------------
async function refrescarUFVHint(idFecha, idHint){
  const f = document.getElementById(idFecha).value;
  const el = document.getElementById(idHint);
  if(!esFechaValida(f)){ el.textContent='UFV: —'; return; }
  el.textContent='UFV: consultando…';
  const seq = (reqSeq[idHint]=(reqSeq[idHint]||0)+1);
  const u = await getUFV(f);
  if(seq!==reqSeq[idHint]) return;
  el.textContent = u ? ('UFV: '+fmtUFV(u)) : 'UFV: no disponible';
}

// ---------------- memoria de cálculo (HTML compartido) ----------------
function memoriaHTML(r, compact){
  const tramos = r.tramos.map(t=>`
    <tr>
      <td><span class="pill pill-${t.pct}">${t.pct}%</span></td>
      <td class="num">${t.dias}</td>
      <td class="num">${fmtFecha(t.desde)}–${fmtFecha(t.hasta)}</td>
      <td class="r num">${fmtUFV(t.interesUFV)}</td>
    </tr>`).join('');
  return `
    <table class="sheet">
      <tr class="step"><td class="label">Tributo omitido</td><td class="num">${fmtBs(r.tributoOmitido)}</td></tr>
      <tr class="step"><td class="label">÷ UFV vencimiento (${fmtFecha(r.fechaVenc)})</td><td class="num">${fmtUFV(r.ufvVenc)}</td></tr>
      <tr><td class="label">= TO actualizado (UFV) <span class="mono">c</span></td><td class="num">${fmtUFV(r.cUFV)}</td></tr>
    </table>
    <div class="formula" style="margin:8px 0;">interés = c × Σ (1 + tasa/360)^días − 1   ·   ${r.diasMora} días de mora</div>
    <table class="tramo-tabla">
      <thead><tr><th>Tramo</th><th class="r">Días</th><th>Periodo</th><th class="r">Interés (UFV)</th></tr></thead>
      <tbody>${tramos}</tbody>
    </table>
    <table class="sheet">
      <tr><td class="label">Interés total (UFV)</td><td class="num">${fmtUFV(r.interesUFV)}</td></tr>
      <tr><td class="label">Deuda tributaria (UFV) = c + interés</td><td class="num">${fmtUFV(r.deudaUFV)}</td></tr>
      ${r.sancionUFV>0?`<tr class="step"><td class="label">+ Sanción omisión 60% (UFV)</td><td class="num">${fmtUFV(r.sancionUFV)}</td></tr>`:''}
      ${r.multaDF_UFV>0?`<tr class="step"><td class="label">+ Multa deberes formales (UFV)</td><td class="num">${fmtUFV(r.multaDF_UFV)}</td></tr>`:''}
      <tr class="step"><td class="label">× UFV pago (${fmtFecha(r.fechaPago)})</td><td class="num">${fmtUFV(r.ufvPago)}</td></tr>
      <tr class="total"><td>Total deuda</td><td class="num">${fmtBs(r.totalBs)}</td></tr>
    </table>
    ${compact?'':'<div class="formula" style="margin-top:8px;">Precisión 5 decimales en UFV · R.N.D. 102500000013 · Art. 47 Ley 2492</div>'}
  `;
}

// ---------------- una deuda ----------------
async function calcularUna(){
  const body = document.getElementById('resultUnaBody');
  const com = opcionesComunes();
  const payload = Object.assign({}, com, {
    fechaVenc: document.getElementById('fechaVencU').value,
    tributoOmitido: parseFloat(document.getElementById('tributoU').value || 0),
    periodo: document.getElementById('periodoU').value,
    impuesto: document.getElementById('impuestoU').value,
  });
  body.innerHTML = '<p class="hint">Calculando…</p>';
  document.getElementById('memoriaUna').innerHTML='';
  const r = await calcular(payload);
  if(r.error){ body.innerHTML = `<p class="err">${r.error}</p>`; return; }
  document.getElementById('resultFecha').textContent = 'al '+fmtFecha(r.fechaPago);
  body.innerHTML = `
    <table class="sheet">
      <tr class="step"><td class="label">Tributo omitido</td><td class="num">${fmtBs(r.tributoOmitido)}</td></tr>
      <tr class="step"><td class="label">Mantenimiento de valor</td><td class="num">${fmtBs(r.mvBs)}</td></tr>
      <tr><td class="label">Tributo actualizado</td><td class="num">${fmtBs(r.toActualizadoBs)}</td></tr>
      <tr class="step"><td class="label">Interés</td><td class="num">${fmtBs(r.interesBs)}</td></tr>
      <tr><td class="label">Deuda tributaria</td><td class="num">${fmtBs(r.deudaBs)}</td></tr>
      ${r.sancionBs>0?`<tr class="step"><td class="label">Sanción por omisión (60%)</td><td class="num">${fmtBs(r.sancionBs)}</td></tr>`:''}
      ${r.multaDF_Bs>0?`<tr class="step"><td class="label">Multa deberes formales</td><td class="num">${fmtBs(r.multaDF_Bs)}</td></tr>`:''}
      <tr class="total"><td>Total deuda</td><td class="num">${fmtBs(r.totalBs)}</td></tr>
    </table>`;
  document.getElementById('memoriaUna').innerHTML =
    `<div class="memoria"><div class="memoria__title">${SVG.calc} Memoria de cálculo</div>${memoriaHTML(r,false)}</div>`;
  ultimoResultadoUna = r;
  document.getElementById('btnPrintUna').style.display = 'inline-flex';
}

// ---------------- varias deudas ----------------
let filaId = 0;
const filaData = {}; // id -> resultado calculado
function agregarFila(pre){
  const id = ++filaId;
  const tr = document.createElement('tr');
  tr.id = 'fila'+id;
  tr.innerHTML = `
    <td><input type="month" class="input" data-f="periodo" value="${pre?.periodo||''}"></td>
    <td><select class="select" data-f="impuesto">
      <option>IVA</option><option>IT</option><option>IUE</option><option>RC-IVA</option><option>Otro</option></select></td>
    <td><input type="date" class="input" data-f="fechaVenc" value="${pre?.fechaVenc||''}"></td>
    <td><div class="input-addon"><span>Bs</span><input type="number" class="input right" data-f="tributoOmitido" placeholder="0,00" value="${pre?.tributoOmitido||''}"></div></td>
    <td class="r num cell-c">—</td>
    <td class="r num cell-i">—</td>
    <td class="r num cell-d">—</td>
    <td class="r num col-san cell-s">—</td>
    <td class="r num cell-t">—</td>
    <td><button class="btn btn-ghost" title="Eliminar" onclick="eliminarFila(${id})">${SVG.trash}</button></td>`;
  document.getElementById('multiBody').appendChild(tr);
  tr.querySelectorAll('[data-f]').forEach(el=>{
    el.addEventListener('change', async ()=>{
      if(el.dataset.f === 'periodo' || el.dataset.f === 'impuesto'){
        await sugerirVencDOM(tr.querySelector('[data-f="fechaVenc"]'),
          tr.querySelector('[data-f="periodo"]').value,
          tr.querySelector('[data-f="impuesto"]').value,
          document.getElementById('nitDigito').value);
      }
      calcularFila(id);
    });
  });
}
function eliminarFila(id){ document.getElementById('fila'+id)?.remove(); delete filaData[id]; recalcTotales(); }

async function calcularFila(id){
  const tr = document.getElementById('fila'+id); if(!tr) return;
  const get = f => tr.querySelector(`[data-f="${f}"]`).value;
  const com = opcionesComunes();
  const payload = Object.assign({}, com, {
    fechaVenc: get('fechaVenc'),
    tributoOmitido: parseFloat(get('tributoOmitido')||0),
    periodo: get('periodo'), impuesto: get('impuesto'),
  });
  if(!payload.fechaVenc || !payload.tributoOmitido || !com.fechaPago){ return; }
  const r = await calcular(payload);
  tr.classList.remove('row-warn');
  if(r.error){ tr.classList.add('row-warn'); tr.querySelector('.cell-t').textContent='⚠'; delete filaData[id]; recalcTotales(); return; }
  filaData[id] = r;
  tr.querySelector('.cell-c').innerHTML = cellConInfo(fmtUFV(r.cUFV), id, 'c');
  tr.querySelector('.cell-i').innerHTML = cellConInfo(fmtUFV(r.interesUFV), id, 'i');
  tr.querySelector('.cell-d').textContent = fmtUFV(r.deudaUFV);
  tr.querySelector('.cell-s').textContent = r.sancionUFV>0 ? fmtUFV(r.sancionUFV) : '—';
  tr.querySelector('.cell-t').innerHTML = cellConInfo(fmtBs(r.totalBs), id, 't');
  recalcTotales();
}
function cellConInfo(val, id, key){
  return `<span class="val-cell">${val}<span class="info-btn"
    onmouseenter="mostrarPop(event,${id})" onmouseleave="ocultarPop()" onclick="fijarPop(event,${id})">${SVG.info}</span></span>`;
}
async function calcularTodas(){ for(const tr of document.querySelectorAll('#multiBody tr')) await calcularFila(+tr.id.replace('fila','')); }
function recalcTotales(){
  let c=0,i=0,d=0,s=0,t=0,any=false;
  Object.values(filaData).forEach(r=>{ any=true; c+=r.cUFV; i+=r.interesUFV; d+=r.deudaUFV; s+=r.sancionUFV; t+=r.totalBs; });
  document.getElementById('totUFVc').textContent = any?fmtUFV(c):'—';
  document.getElementById('totUFVi').textContent = any?fmtUFV(i):'—';
  document.getElementById('totUFVd').textContent = any?fmtUFV(d):'—';
  document.getElementById('totUFVs').textContent = any&&s>0?fmtUFV(s):'—';
  document.getElementById('totBs').textContent = fmtBs(t);
}
// Muestra/oculta la columna de sanción y recalcula según el tipo de cálculo.
function aplicarTipoCalc(){
  const san = document.getElementById('tipoCalc').value === 'sancion';
  document.querySelector('table.multi')?.classList.toggle('has-sancion', san);
  calcularTodas();
}

// ---------------- reporte / PDF ----------------
function resultadoSheetHTML(r){
  return `<table class="sheet">
    <tr class="step"><td class="label">Tributo omitido</td><td class="num">${fmtBs(r.tributoOmitido)}</td></tr>
    <tr class="step"><td class="label">Mantenimiento de valor</td><td class="num">${fmtBs(r.mvBs)}</td></tr>
    <tr><td class="label">Tributo actualizado</td><td class="num">${fmtBs(r.toActualizadoBs)}</td></tr>
    <tr class="step"><td class="label">Interés</td><td class="num">${fmtBs(r.interesBs)}</td></tr>
    <tr><td class="label">Deuda tributaria</td><td class="num">${fmtBs(r.deudaBs)}</td></tr>
    ${r.sancionBs>0?`<tr class="step"><td class="label">Sanción por omisión (60%)</td><td class="num">${fmtBs(r.sancionBs)}</td></tr>`:''}
    ${r.multaDF_Bs>0?`<tr class="step"><td class="label">Multa deberes formales</td><td class="num">${fmtBs(r.multaDF_Bs)}</td></tr>`:''}
    <tr class="total"><td>Total deuda</td><td class="num">${fmtBs(r.totalBs)}</td></tr>
  </table>`;
}
function generarReporte(){
  const esMulti = !document.getElementById('modeVarias').classList.contains('hide');
  const fechaPago = document.getElementById('fechaPago').value;
  let cuerpo = '';
  if (esMulti){
    const rows = Object.values(filaData);
    if(!rows.length){ alert('No hay deudas calculadas para incluir en el reporte.'); return; }
    const haySan = rows.some(x=>x.sancionUFV>0);
    const filas = rows.map(r=>`<tr>
      <td>${r.periodo||''}</td><td>${r.impuesto||''}</td><td>${fmtFecha(r.fechaVenc)}</td>
      <td class="r num">${fmtBs(r.tributoOmitido)}</td><td class="r num">${fmtUFV(r.cUFV)}</td>
      <td class="r num">${fmtUFV(r.interesUFV)}</td><td class="r num">${fmtUFV(r.deudaUFV)}</td>
      ${haySan?`<td class="r num">${fmtUFV(r.sancionUFV)}</td>`:''}<td class="r num">${fmtBs(r.totalBs)}</td></tr>`).join('');
    const tot = rows.reduce((a,r)=>({c:a.c+r.cUFV,i:a.i+r.interesUFV,d:a.d+r.deudaUFV,s:a.s+r.sancionUFV,t:a.t+r.totalBs}),{c:0,i:0,d:0,s:0,t:0});
    cuerpo = `<h2>Liquidación consolidada de deuda tributaria</h2>
      <table class="rep"><thead><tr>
        <th>Periodo</th><th>Impuesto</th><th>F. venc.</th><th class="r">Tributo omitido</th>
        <th class="r">TO actualiz. (UFV)</th><th class="r">Interés (UFV)</th><th class="r">Deuda (UFV)</th>
        ${haySan?'<th class="r">Sanción 60% (UFV)</th>':''}<th class="r">Total (Bs)</th></tr></thead>
      <tbody>${filas}</tbody>
      <tfoot><tr><td colspan="4">Total general</td><td class="r num">${fmtUFV(tot.c)}</td>
        <td class="r num">${fmtUFV(tot.i)}</td><td class="r num">${fmtUFV(tot.d)}</td>
        ${haySan?`<td class="r num">${fmtUFV(tot.s)}</td>`:''}<td class="r num">${fmtBs(tot.t)}</td></tr></tfoot></table>
      <h3>Memorias de cálculo</h3>
      ${rows.map(r=>`<div class="mem"><div class="mem-h">${r.periodo||''} · ${r.impuesto||''}</div>${memoriaHTML(r,true)}</div>`).join('')}`;
  } else {
    const r = ultimoResultadoUna;
    if(!r){ alert('Primero calcule una deuda.'); return; }
    cuerpo = `<h2>Liquidación de deuda tributaria</h2>
      <div class="cols"><div>${resultadoSheetHTML(r)}</div>
      <div class="mem"><div class="mem-h">Memoria de cálculo</div>${memoriaHTML(r,true)}</div></div>`;
  }
  const estilos = `
    body{font-family:var(--font-sans);color:var(--text-primary);margin:0;padding:0;font-size:11pt;}
    .num{font-variant-numeric:tabular-nums;} .mono{font-family:var(--font-mono);}
    .rep-head{display:flex;align-items:center;gap:12px;border-bottom:2px solid var(--color-brand-500);padding-bottom:10px;margin-bottom:16px;}
    .rep-title{font-size:15pt;font-weight:600;} .rep-sub{font-size:10pt;color:var(--text-secondary);}
    h2{font-size:13pt;font-weight:600;margin:14px 0 8px;} h3{font-size:11pt;font-weight:600;margin:18px 0 8px;}
    .cols{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start;}
    table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;}
    .sheet td{padding:5px 0;font-size:10.5pt;} .sheet td:last-child{text-align:right;} .sheet .label{color:var(--text-secondary);}
    .sheet tr.total td{border-top:1px solid var(--border-strong);font-weight:600;font-size:11.5pt;padding-top:8px;}
    table.rep th{background:var(--bg-subtle);text-align:left;font-size:8.5pt;font-weight:600;color:var(--text-secondary);padding:6px;border-bottom:1px solid var(--border-strong);}
    table.rep td{padding:5px 6px;border-bottom:.5pt solid var(--border-default);font-size:9.5pt;}
    table.rep .r{text-align:right;} table.rep tfoot td{border-top:1.5pt solid var(--border-strong);font-weight:600;background:var(--bg-subtle);}
    thead{display:table-header-group;} tr,td,th{page-break-inside:avoid;}
    .mem{border:.5pt solid var(--border-default);border-radius:8px;padding:10px 14px;margin:10px 0;page-break-inside:avoid;}
    .mem-h{font-weight:600;font-size:10pt;margin-bottom:6px;}
    .tramo-tabla{margin:6px 0;} .tramo-tabla th{background:var(--bg-subtle);font-size:8pt;text-align:left;padding:3px 6px;color:var(--text-secondary);}
    .tramo-tabla td{padding:3px 6px;border-bottom:.5pt solid var(--border-default);font-size:9pt;} .tramo-tabla .r{text-align:right;}
    .pill{padding:1px 6px;border-radius:999px;font-size:8pt;font-weight:600;}
    .pill-4{background:var(--color-info-bg);color:var(--color-info-fg);} .pill-6{background:var(--color-warning-bg);color:var(--color-warning-fg);} .pill-10{background:var(--color-danger-bg);color:var(--color-danger-fg);}
    .formula{font-family:var(--font-mono);font-size:8.5pt;color:var(--text-tertiary);margin:6px 0;}
    .rep-foot{margin-top:18px;padding-top:8px;border-top:.5pt solid var(--border-default);font-size:8pt;color:var(--text-tertiary);}
    @page{size:A4;margin:18mm 16mm;}
  `;
  const win = window.open('', '_blank');
  win.document.write(`<!DOCTYPE html><html lang="es"><head><meta charset="UTF-8">
    <title>Liquidación de deuda tributaria</title>
    <link rel="stylesheet" href="${location.origin}/c/design-tokens.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono&display=swap" rel="stylesheet">
    <style>${estilos}</style></head><body>
    <header class="rep-head"><img src="${location.origin}/c/assets/marca/isotipo-bib.png" height="34" alt="boliviaimpuestos">
      <div><div class="rep-title">Calculadora tributaria</div><div class="rep-sub">Liquidación de deuda · al ${fmtFecha(fechaPago)}</div></div></header>
    ${cuerpo}
    <footer class="rep-foot">UFV oficiales obtenidas del Banco Central de Bolivia (BCB). Cálculo conforme al Art. 47 de la Ley 2492 (CTB) y la R.N.D. 102500000013 (tratamiento de decimales).</footer>
    </body></html>`);
  win.document.close(); win.focus();
  setTimeout(()=>{ try{ win.print(); }catch(e){} }, 700);
}

// ---------------- popover ----------------
let popPinned=false;
function mostrarPop(ev, id){
  if(popPinned) return;
  const r = filaData[id]; if(!r) return;
  const pop = document.getElementById('pop');
  pop.innerHTML = `<div class="popover__head"><span class="popover__title">${r.periodo||''} · ${r.impuesto||''}</span></div>${memoriaHTML(r,true)}`;
  posicionarPop(ev); pop.classList.add('show');
}
function fijarPop(ev, id){
  const r = filaData[id]; if(!r) return;
  const pop = document.getElementById('pop');
  popPinned=true;
  pop.innerHTML = `<div class="popover__head"><span class="popover__title">${r.periodo||''} · ${r.impuesto||''}</span><button class="popover__pin" onclick="cerrarPop()">${SVG.x} cerrar</button></div>${memoriaHTML(r,true)}`;
  posicionarPop(ev); pop.classList.add('show');
  ev.stopPropagation();
}
function posicionarPop(ev){
  const pop=document.getElementById('pop'); const pad=10;
  let x=ev.clientX+pad+window.scrollX, y=ev.clientY+pad+window.scrollY;
  pop.style.left=Math.min(x, window.scrollX+document.documentElement.clientWidth-360)+'px';
  pop.style.top=y+'px';
}
function ocultarPop(){ if(!popPinned) document.getElementById('pop').classList.remove('show'); }
function cerrarPop(){ popPinned=false; document.getElementById('pop').classList.remove('show'); }
document.addEventListener('click', e=>{ if(popPinned && !e.target.closest('.popover') && !e.target.closest('.info-btn')) cerrarPop(); });

// ---------------- init ----------------
document.addEventListener('DOMContentLoaded', ()=>{
  const hoy = new Date().toISOString().slice(0,10);
  document.getElementById('fechaPago').value = hoy;
  refrescarUFVHint('fechaPago','ufvPagoHint');
  document.getElementById('fechaPago').addEventListener('change', ()=>{ refrescarUFVHint('fechaPago','ufvPagoHint'); calcularTodas(); });
  document.getElementById('fechaVencU').addEventListener('change', ()=>refrescarUFVHint('fechaVencU','ufvVencHint'));

  // Sugerencia de vencimiento (una deuda)
  const sugUna = async ()=>{
    const ok = await sugerirVencDOM(document.getElementById('fechaVencU'),
      document.getElementById('periodoU').value, document.getElementById('impuestoU').value,
      document.getElementById('nitDigito').value);
    if(ok) refrescarUFVHint('fechaVencU','ufvVencHint');
  };
  document.getElementById('periodoU').addEventListener('change', sugUna);
  document.getElementById('impuestoU').addEventListener('change', sugUna);

  // Cambiar el dígito de NIT re-sugiere todos los vencimientos
  document.getElementById('nitDigito').addEventListener('change', async ()=>{
    await sugUna();
    for(const tr of document.querySelectorAll('#multiBody tr')){
      await sugerirVencDOM(tr.querySelector('[data-f="fechaVenc"]'),
        tr.querySelector('[data-f="periodo"]').value, tr.querySelector('[data-f="impuesto"]').value,
        document.getElementById('nitDigito').value);
      calcularFila(+tr.id.replace('fila',''));
    }
  });

  // Opciones de cálculo -> recalcular
  document.getElementById('tipoCalc').addEventListener('change', ()=>{ aplicarTipoCalc(); if(ultimoResultadoUna) calcularUna(); });
  document.getElementById('multaDF').addEventListener('change', ()=>{ calcularTodas(); if(ultimoResultadoUna) calcularUna(); });
  document.getElementById('precisionFactor').addEventListener('change', ()=>{ calcularTodas(); if(ultimoResultadoUna) calcularUna(); });

  agregarFila(); agregarFila();
  aplicarTipoCalc();
});
</script>
</body>
</html>
