<?php
/**
 * calcu-v3.php — Calculadora Tributaria (tema IBM Carbon)
 *  - Idéntica a calcu-v2 en lógica/motor; cambia solo el sistema de diseño.
 *  - Diseño 100% IBM Carbon (carbondesignsystem.com): IBM Plex Sans/Mono con la
 *    métrica de Carbon (tamaños + letter-spacing), gris #f4f4f4 con borde inferior
 *    en campos, azul #0f62fe, esquinas rectas, header UI Shell negro, foco 2px.
 *  - Tokens en carbon-tokens.css (:root) + refinamientos en el <style>.
 *  - 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).
 *
 *  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" data-theme="carbon">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculadora Tributaria BCB - Consulta Directa</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=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- Tokens IBM Carbon (carbondesignsystem.com). -->
<link rel="stylesheet" href="carbon-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); }
  .field .hint a { color: var(--color-azure-600); text-decoration: none; }
  .field .hint a:hover { text-decoration: underline; }
  .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); } }

  /* ====================================================================== */
  /*  IBM Carbon — refinamientos de tipografía y componentes                */
  /*  (tokens base en carbon-tokens.css; aquí los detalles del sistema)     */
  /* ====================================================================== */

  /* Tipografía IBM Plex con la métrica de Carbon (tamaño + letter-spacing) */
  body { letter-spacing: 0.16px; }                                   /* body-compact-01 */
  .field label { font-size: var(--text-xs); font-weight: 400; color: var(--text-secondary);
                 letter-spacing: 0.32px; margin-bottom: var(--space-2); }   /* label-01 */
  .field .hint { letter-spacing: 0.32px; color: var(--color-neutral-500); } /* helper-text-01 #6f6f6f */
  .card__title, .memoria__title { font-size: var(--text-lg); font-weight: 600; letter-spacing: 0; } /* heading-compact */
  .sheet tr.total td { font-weight: 600; }
  .num, .mono { letter-spacing: 0; }                                  /* cifras sin tracking */

  /* UI Shell header (negro #161616, alto 48, texto 14/600) */
  .app-header { background: #161616; border-bottom: none; height: 48px; }
  .app-header img { filter: brightness(0) invert(1); height: 24px; }
  .app-header__section { color: #f4f4f4; font-size: var(--text-base); font-weight: 600; letter-spacing: 0; }

  /* Text input: relleno gris #f4f4f4 + borde inferior #8d8d8d, foco 2px */
  .input, .select { background: #f4f4f4; border: none; border-bottom: 1px solid #8d8d8d; border-radius: 0; }
  .input:hover, .select:hover { background: #e8e8e8; border-bottom-color: #8d8d8d; }
  .input:focus, .select:focus { outline: 2px solid #0f62fe; outline-offset: -2px; box-shadow: none; border-bottom-color: transparent; }
  .input::placeholder { color: #a8a8a8; }

  /* Botones: rectos, peso 400, foco Carbon (anillo 2px + interior blanco) */
  .btn { font-weight: 400; letter-spacing: 0.16px; }
  .btn-primary:active { transform: none; }
  .btn:focus { outline: 2px solid #0f62fe; outline-offset: -2px; box-shadow: inset 0 0 0 1px #fff; }

  /* Content switcher (toggles Una/Varias y Monto/Base) */
  .mode-toggle { background: transparent; border: 1px solid #8d8d8d; border-radius: 0; padding: 0; gap: 0; }
  .mode-toggle button { border-radius: 0; border-right: 1px solid #8d8d8d; font-weight: 400; }
  .mode-toggle button:last-child { border-right: none; }
  .mode-toggle button.active { background: #393939; color: #fff; box-shadow: none; }

  /* DataTable */
  table.multi thead th { background: #e0e0e0; color: #161616; letter-spacing: 0.32px; }
  table.multi tbody tr:hover { background: #e8e8e8; }

  /* Carbon Tag = píldora redondeada (se mantiene radius-full, peso 400) */
  .pill { font-weight: 400; }
</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 2;">
      <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 3;">
      <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 4;">
      <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="impuestoU">Impuesto</label>
          <select id="impuestoU" class="select">
            <option value="IVA">IVA</option>
            <option value="IT">IT</option>
            <option value="RC-IVA">RC-IVA</option>
            <option value="IUE">IUE</option>
            <option value="Otro">Otro</option>
          </select>
        </div>

        <!-- Mensual (IVA/IT/RC-IVA): último dígito del NIT -->
        <div class="field" id="campoNitU" style="margin-bottom: var(--space-4);">
          <label for="nitDigitoU">Último dígito del NIT</label>
          <select id="nitDigitoU" class="select">
            <option value="">—</option>
            <option>0</option><option>1</option><option>2</option><option>3</option><option>4</option>
            <option>5</option><option>6</option><option>7</option><option>8</option><option>9</option>
          </select>
          <span class="hint">Define el día de vencimiento del calendario mensual.</span>
        </div>

        <!-- Mensual / Otro: periodo fiscal por mes -->
        <div class="field" id="campoMesU" style="margin-bottom: var(--space-4);">
          <label for="periodoU">Periodo fiscal</label>
          <input type="month" id="periodoU" class="input">
        </div>

        <!-- IUE: tipo de cierre de gestión + gestión (año) -->
        <div id="campoIueU" class="hide">
          <div class="field" style="margin-bottom: var(--space-4);">
            <label for="cierreU">Tipo de cierre de gestión</label>
            <select id="cierreU" class="select">
              <option value="comercial">Comercial, servicios y otras (cierre 31 dic)</option>
              <option value="industrial">Industrial y petrolera (cierre 31 mar)</option>
              <option value="agropecuaria">Agropecuaria y agroindustrial (cierre 30 jun)</option>
              <option value="minera">Minera (cierre 30 sep)</option>
            </select>
          </div>
          <div class="field" style="margin-bottom: var(--space-4);">
            <label for="gestionU">Gestión (año)</label>
            <input type="number" id="gestionU" class="input" min="2001" max="2100" placeholder="2024">
          </div>
        </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="vencNotaU">Sugerida según el <a href="https://www.impuestos.gob.bo/index.php/calendario-tributario/" target="_blank" rel="noopener">calendario tributario del SIN</a>; verifíquela y ajústela (sujeta a revisión del contribuyente).</span>
          <span class="hint" id="ufvVencHint">UFV: —</span>
        </div>
        <div class="field" style="margin-bottom: var(--space-2);">
          <label>Tributo omitido</label>
          <div class="mode-toggle" style="margin-top: var(--space-1);">
            <button type="button" id="tribTabDir" class="active" onclick="setTribMode('directo')">Monto directo</button>
            <button type="button" id="tribTabBase" onclick="setTribMode('base')">Desde base imponible</button>
          </div>
        </div>
        <div class="field" id="campoTribDir" style="margin-bottom: var(--space-5);">
          <div class="input-addon"><span>Bs</span><input type="number" id="tributoU" class="input right" placeholder="0,00"></div>
        </div>
        <div id="campoBaseU" class="hide">
          <div class="field" style="margin-bottom: var(--space-4);">
            <label for="baseU">Base imponible</label>
            <div class="input-addon"><span>Bs</span><input type="number" id="baseU" class="input right" placeholder="0,00" oninput="recomputeBaseU()"></div>
          </div>
          <div class="field" style="margin-bottom: var(--space-5);">
            <label for="alicuotaU">Alícuota (%)</label>
            <input type="number" id="alicuotaU" class="input right" step="0.01" placeholder="13" oninput="recomputeBaseU()">
            <span class="hint" id="tribCalcHint">Tributo omitido: —</span>
          </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">
      <label style="display:flex; align-items:center; gap:var(--space-2); font-size:var(--text-base); font-weight:500; color:var(--text-secondary); margin-right:auto;">
        Último dígito del NIT
        <select id="nitDigitoV" class="select" style="width:auto; height:var(--control-height);">
          <option value="">—</option>
          <option>0</option><option>1</option><option>2</option><option>3</option><option>4</option>
          <option>5</option><option>6</option><option>7</option><option>8</option><option>9</option>
        </select>
        <span class="hint" style="font-weight:400;">aplica a impuestos mensuales</span>
      </label>
      <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>Impuesto</th><th>Periodo</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;

// Categorías de impuesto y mapeo de cierre IUE -> mes de cierre (vencimientos.php
// infiere el tipo de cierre a partir del mes: 12=comercial, 03=industrial, etc.).
const MENSUALES = ['IVA','IT','RC-IVA'];
const CIERRE_MES = { comercial:'12', industrial:'03', agropecuaria:'06', minera:'09' };
function categoria(imp){ return imp==='IUE' ? 'iue' : (MENSUALES.includes(imp) ? 'mensual' : 'otro'); }

// ---------------- tokens IBM Carbon para el reporte impreso ----------------
const PRINT_TOKENS_CARBON = "--font-sans:'IBM Plex Sans',system-ui,sans-serif;--font-mono:'IBM Plex Mono',monospace;--text-primary:#161616;--text-secondary:#525252;--text-tertiary:#6f6f6f;--color-brand-500:#0f62fe;--bg-subtle:#f4f4f4;--border-strong:#8d8d8d;--border-default:#e0e0e0;--color-info-bg:#edf5ff;--color-info-fg:#0043ce;--color-warning-bg:#fcf4d6;--color-warning-fg:#684e00;--color-danger-bg:#fff1f1;--color-danger-fg:#da1e28;";

// Alícuotas por defecto (%) para el modo "desde base imponible".
const ALICUOTAS = { 'IVA':13, 'RC-IVA':13, 'IT':3, 'IUE':25 };
let tribMode = 'directo'; // 'directo' | 'base'
// Alterna entre escribir el tributo omitido directo o derivarlo de base×alícuota.
function setTribMode(m){
  tribMode = m;
  document.getElementById('tribTabDir').classList.toggle('active', m==='directo');
  document.getElementById('tribTabBase').classList.toggle('active', m==='base');
  document.getElementById('campoTribDir').classList.toggle('hide', m!=='directo');
  document.getElementById('campoBaseU').classList.toggle('hide', m!=='base');
  if(m==='base'){
    const al = document.getElementById('alicuotaU');
    if(!al.value){ const a = ALICUOTAS[document.getElementById('impuestoU').value]; if(a) al.value = a; }
    recomputeBaseU();
  }
}
// Calcula el tributo omitido = base × alícuota con PRECISIÓN COMPLETA (sin
// redondear a centavos) y lo deja en #tributoU, que es lo que lee el motor.
function recomputeBaseU(){
  const base = parseFloat(document.getElementById('baseU').value || 0);
  const alic = parseFloat(document.getElementById('alicuotaU').value || 0);
  const to = base * alic / 100;
  document.getElementById('tributoU').value = to ? to : '';
  document.getElementById('tribCalcHint').textContent = to ? ('Tributo omitido: '+fmtBs(to)) : 'Tributo omitido: —';
}
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 ----------------
// Contexto de "una deuda": resuelve período (para sugerir vencimiento y para
// mostrar) y NIT según el tipo de impuesto elegido.
function unaCtx(){
  const imp = document.getElementById('impuestoU').value;
  const cat = categoria(imp);
  let periodoVenc='', periodoLabel='', nit=null;
  if(cat==='mensual'){
    const p = document.getElementById('periodoU').value;
    periodoVenc=p; periodoLabel=p; nit=document.getElementById('nitDigitoU').value;
  } else if(cat==='iue'){
    const g = document.getElementById('gestionU').value, c = document.getElementById('cierreU').value;
    if(g && c){ periodoVenc = g+'-'+CIERRE_MES[c]; periodoLabel = 'Gestión '+g+' ('+c+')'; }
  } else { // 'otro': período opcional, sin sugerencia
    const p = document.getElementById('periodoU').value; periodoVenc=p; periodoLabel=p;
  }
  return { imp, cat, periodoVenc, periodoLabel, nit };
}
// Muestra/oculta los campos según el impuesto y re-sugiere el vencimiento.
function aplicarImpuestoU(){
  const imp = document.getElementById('impuestoU').value;
  const cat = categoria(imp);
  document.getElementById('campoNitU').classList.toggle('hide', cat!=='mensual');
  document.getElementById('campoMesU').classList.toggle('hide', cat==='iue');
  document.getElementById('campoIueU').classList.toggle('hide', cat!=='iue');
  if(tribMode==='base' && ALICUOTAS[imp] !== undefined){ document.getElementById('alicuotaU').value = ALICUOTAS[imp]; recomputeBaseU(); }
  sugUna();
}
// Sugiere y autocompleta el vencimiento (una deuda) sin pisar lo escrito a mano.
async function sugUna(){
  const ctx = unaCtx();
  if(!ctx.periodoVenc) return;
  const ok = await sugerirVencDOM(document.getElementById('fechaVencU'), ctx.periodoVenc, ctx.imp, ctx.nit);
  if(ok) refrescarUFVHint('fechaVencU','ufvVencHint');
}

async function calcularUna(){
  const body = document.getElementById('resultUnaBody');
  const com = opcionesComunes();
  const ctx = unaCtx();
  const payload = Object.assign({}, com, {
    fechaVenc: document.getElementById('fechaVencU').value,
    tributoOmitido: parseFloat(document.getElementById('tributoU').value || 0),
    periodo: ctx.periodoLabel,
    impuesto: ctx.imp,
  });
  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><select class="select" data-f="impuesto">
      <option value="IVA">IVA</option><option value="IT">IT</option><option value="RC-IVA">RC-IVA</option>
      <option value="IUE">IUE</option><option value="Otro">Otro</option></select></td>
    <td class="cell-periodo"></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);
  renderPeriodo(tr, pre);
  bindPeriodo(tr, id);
  // Listeners de campos que NO se re-renderizan:
  tr.querySelector('[data-f="impuesto"]').addEventListener('change', async ()=>{
    renderPeriodo(tr); bindPeriodo(tr, id); await sugerirFila(tr); calcularFila(id);
  });
  tr.querySelector('[data-f="fechaVenc"]').addEventListener('change', ()=>calcularFila(id));
  tr.querySelector('[data-f="tributoOmitido"]').addEventListener('change', ()=>calcularFila(id));
}
// Construye la celda de período según el impuesto: mes (mensual/otro) o
// cierre+gestión (IUE).
function renderPeriodo(tr, pre){
  const cat = categoria(tr.querySelector('[data-f="impuesto"]').value);
  const cell = tr.querySelector('.cell-periodo');
  if(cat==='iue'){
    cell.innerHTML = `<div style="display:flex; gap:6px;">
      <select class="select" data-f="cierre" style="height:32px;">
        <option value="comercial">Comercial (31 dic)</option>
        <option value="industrial">Industrial (31 mar)</option>
        <option value="agropecuaria">Agro (30 jun)</option>
        <option value="minera">Minera (30 sep)</option></select>
      <input type="number" class="input" data-f="gestion" placeholder="año" min="2001" max="2100" style="width:78px;" value="${pre?.gestion||''}"></div>`;
  } else {
    cell.innerHTML = `<input type="month" class="input" data-f="periodo" value="${pre?.periodo||''}">`;
  }
}
// (Re)asigna listeners a los campos de la celda de período.
function bindPeriodo(tr, id){
  tr.querySelectorAll('.cell-periodo [data-f]').forEach(el=>{
    el.addEventListener('change', async ()=>{ await sugerirFila(tr); calcularFila(id); });
  });
}
// Contexto de la fila: período para vencimiento/etiqueta y NIT global.
function filaCtx(tr){
  const imp = tr.querySelector('[data-f="impuesto"]').value;
  const cat = categoria(imp);
  let periodoVenc='', periodoLabel='', nit=null;
  if(cat==='mensual'){
    const p = tr.querySelector('[data-f="periodo"]')?.value || '';
    periodoVenc=p; periodoLabel=p; nit=document.getElementById('nitDigitoV').value;
  } else if(cat==='iue'){
    const g = tr.querySelector('[data-f="gestion"]')?.value || '', c = tr.querySelector('[data-f="cierre"]')?.value || '';
    if(g && c){ periodoVenc = g+'-'+CIERRE_MES[c]; periodoLabel = 'Gestión '+g+' ('+c+')'; }
  } else {
    const p = tr.querySelector('[data-f="periodo"]')?.value || ''; periodoVenc=p; periodoLabel=p;
  }
  return { imp, cat, periodoVenc, periodoLabel, nit };
}
async function sugerirFila(tr){
  const ctx = filaCtx(tr);
  if(!ctx.periodoVenc) return;
  await sugerirVencDOM(tr.querySelector('[data-f="fechaVenc"]'), ctx.periodoVenc, ctx.imp, ctx.nit);
}
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 com = opcionesComunes();
  const ctx = filaCtx(tr);
  const payload = Object.assign({}, com, {
    fechaVenc: tr.querySelector('[data-f="fechaVenc"]').value,
    tributoOmitido: parseFloat(tr.querySelector('[data-f="tributoOmitido"]').value||0),
    periodo: ctx.periodoLabel, impuesto: ctx.imp,
  });
  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 href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono&display=swap" rel="stylesheet">
    <style>:root{${PRINT_TOKENS_CARBON}}</style>
    <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'));

  // Una deuda: el impuesto cambia los campos visibles; período/NIT/cierre/gestión re-sugieren el vencimiento.
  document.getElementById('impuestoU').addEventListener('change', aplicarImpuestoU);
  document.getElementById('periodoU').addEventListener('change', sugUna);
  document.getElementById('nitDigitoU').addEventListener('change', sugUna);
  document.getElementById('cierreU').addEventListener('change', sugUna);
  document.getElementById('gestionU').addEventListener('change', sugUna);

  // NIT global (varias deudas): re-sugiere y recalcula todas las filas.
  document.getElementById('nitDigitoV').addEventListener('change', async ()=>{
    for(const tr of document.querySelectorAll('#multiBody tr')){
      await sugerirFila(tr);
      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();
  aplicarImpuestoU();
});
</script>

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-70NLCS69RM"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-70NLCS69RM');
</script>
</body>
</html>
