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

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

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

// CSRF simple (opcional, no obligatorio para tu PV actual)
if (!isset($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(16));
$csrf = (string)$_SESSION['csrf'];
?>
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Puntos de Venta</title>

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

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

<body>

<?php
$active = 'punto';
include __DIR__ . '/menu_raspadita.php';
?>

<div class="main-content p-2 p-md-3">
  <div class="container-fluid">

    <div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
      <div>
        <h4 class="mb-0 fw-bold"><i class="fa-solid fa-store me-2"></i>Puntos de Venta</h4>
      </div>
      <div class="d-flex gap-2">
        <button id="btnOpenHistPV" class="btn btn-outline-dark" onclick="openHistorialPV()">
          <i class="fa-solid fa-clock-rotate-left me-1"></i>Historial
        </button>
        <button id="btnOpenModalPV" class="btn btn-success" onclick="openModal()">
          <i class="fa-solid fa-plus me-1"></i>Nuevo Punto
        </button>
      </div>
    </div>

    <div class="card p-3">
      <div class="table-responsive">
        <table id="tabla" class="table table-striped table-hover align-middle mb-0" style="width:100%">
          <thead>
            <tr>
              <th>Usuario</th>
              <th>Sucursal</th>
              <th>Activo</th>
              <th class="text-end">Saldo</th>
              <th class="text-center">Raspadita</th>
              <th class="text-end">Acciones</th>
            </tr>
          </thead>
          <tbody></tbody>
        </table>
      </div>
      <div id="msg" class="mt-2 small"></div>
    </div>

  </div>
</div>

<!-- MODAL CREAR/EDITAR PV -->
<div class="modal fade" id="mdl" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-centered">
    <div class="modal-content" style="border-radius:18px;">
      <div class="modal-header">
        <h5 class="modal-title fw-bold"><i class="fa-solid fa-store me-2"></i><span id="ttl">Nuevo Punto</span></h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cerrar"></button>
      </div>

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

        <div class="row g-3">
          <div class="col-12 col-md-6">
            <label class="form-label">Usuario</label>
            <input class="form-control" id="usuario" placeholder="Ej: punto01" autocomplete="off">
          </div>

          <div class="col-12 col-md-6">
            <label class="form-label">Clave</label>
            <div class="input-group">
              <input type="password" class="form-control" id="clave" placeholder="********">
              <button class="btn btn-outline-secondary" type="button" id="toggleClave" title="Ver / ocultar">
                <i class="fa-solid fa-eye"></i>
              </button>
            </div>
          </div>

          <div class="col-6">
            <label class="form-label">Sucursal</label>
            <select class="form-select" id="id_sucursal">
              <option value="">Cargando sucursales...</option>
            </select>
          </div>

          <div class="col-3">
            <label class="form-label">Activo</label>
            <select class="form-select" id="activo">
              <option value="1">(Sí)</option>
              <option value="0">(No)</option>
            </select>
          </div>

          <div class="col-3">
            <label class="form-label">Raspadita</label>
            <select class="form-select" id="raspadita">
              <option value="1">(Sí)</option>
              <option value="0">(No)</option>
            </select>
          </div>
        </div>
      </div>

      <div class="modal-footer">
        <button class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancelar</button>
        <button class="btn btn-success" onclick="savePV()">
          <i class="fa-solid fa-floppy-disk me-1"></i>Guardar
        </button>
      </div>
    </div>
  </div>
</div>

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

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

        <div class="mb-2">
          <label class="form-label fw-semibold">Punto de venta</label>
          <input type="text" id="pv_usuario" class="form-control" readonly>
        </div>

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

        <div class="mt-2">
          <label class="form-label fw-semibold">Saldo resultante</label>
          <input type="text" id="pv_saldo_nuevo" class="form-control fw-bold" readonly>
        </div>

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

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

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

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

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

        <small class="text-muted d-block mt-2">
          * Anular revierte saldo y guarda auditoría.
        </small>
      </div>

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

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

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

<script>
let dt, modal, modalCobroPV, modalHistPV, dtHistPV;
let SUC_CACHE = [];

const DT_ES = {
  decimal: ",",
  thousands: ".",
  processing: "Procesando...",
  search: "Buscar:",
  lengthMenu: "Mostrar _MENU_ registros",
  info: "Mostrando _START_ a _END_ de _TOTAL_ registros",
  infoEmpty: "Mostrando 0 a 0 de 0 registros",
  infoFiltered: "(filtrado de _MAX_ registros totales)",
  loadingRecords: "Cargando...",
  zeroRecords: "No se encontraron resultados",
  emptyTable: "No hay datos disponibles",
  paginate: { first:"Primero", previous:"Anterior", next:"Siguiente", last:"Último" }
};

function showMsg(text, ok=true){
  const el = document.getElementById('msg');
  el.className = ok ? 'mt-2 small text-success' : 'mt-2 small text-danger';
  el.textContent = text;
}

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

function reloadTable(){ if(dt) dt.ajax.reload(null, false); }

async function loadSucursales(){
  const sel = document.getElementById('id_sucursal');
  sel.innerHTML = `<option value="">Cargando...</option>`;
  try{
    const res = await fetch('api/sucursal_list.php', {
      method:'POST',
      headers:{ 'Content-Type':'application/json', 'Accept':'application/json' },
      body:'{}'
    });
    const text = await res.text();
    let j; try{ j = JSON.parse(text); } catch(e){ sel.innerHTML = `<option value="">Error</option>`; return; }
    if(!j.success){ sel.innerHTML = `<option value="">No se pudo cargar</option>`; return; }
    SUC_CACHE = j.data || [];
    let html = `<option value="">Seleccione...</option>`;
    for(const it of SUC_CACHE) html += `<option value="${it.idsucursal}">${it.sucursal}</option>`;
    sel.innerHTML = html;
  }catch(err){
    sel.innerHTML = `<option value="">Error</option>`;
  }
}

function openModal(row=null){
  if(!modal) modal = new bootstrap.Modal(document.getElementById('mdl'));

  document.getElementById('idusuario').value = row?.idusuario ?? 0;
  document.getElementById('usuario').value   = row?.usuario ?? '';
  document.getElementById('clave').value     = '';
  document.getElementById('activo').value    = row?.activo ?? 1;
  document.getElementById('raspadita').value = row?.raspadita ?? 1;

  const setSuc = () => {
    document.getElementById('id_sucursal').value = row?.id_sucursal ?? '';
  };
  if(!SUC_CACHE.length){
    loadSucursales().then(setSuc);
  } else {
    setSuc();
  }

  document.getElementById('ttl').textContent = row ? 'Editar Punto' : 'Nuevo Punto';
  modal.show();
}

async function savePV(){
  const payload = {
    idusuario: parseInt(document.getElementById('idusuario').value || '0', 10),
    usuario: (document.getElementById('usuario').value || '').trim(),
    clave: (document.getElementById('clave').value || '').trim(),
    id_sucursal: parseInt(document.getElementById('id_sucursal').value || '0', 10),
    activo: parseInt(document.getElementById('activo').value || '1', 10),
    raspadita: parseInt(document.getElementById('raspadita').value || '1', 10)
  };

  if(!payload.usuario){ showMsg('Usuario es obligatorio.', false); return; }
  if(payload.id_sucursal <= 0){ showMsg('Seleccione una sucursal válida.', false); return; }
  if(payload.idusuario === 0 && !payload.clave){ showMsg('Clave obligatoria al crear.', false); return; }

  const res = await fetch('api/pv_save_simple.php', {
    method:'POST',
    headers:{'Content-Type':'application/json', 'Accept':'application/json'},
    body: JSON.stringify(payload)
  });

  const text = await res.text();
  let j; try{ j = JSON.parse(text); }catch(e){ showMsg('Respuesta inválida (ver consola).', false); console.log(text); return; }
  if(!j || !j.success){ showMsg(j?.message || 'Error al guardar.', false); return; }

  showMsg(j.message || 'Guardado ✅', true);
  modal.hide();
  reloadTable();
}

// ======= COBRO PV =======
function openCobroPV(row){
  if(!modalCobroPV) modalCobroPV = new bootstrap.Modal(document.getElementById('modalCobroPV'));

  const saldo = toNumber(row.saldo);
  document.getElementById('pv_id').value = row.idusuario;
  document.getElementById('pv_usuario').value = row.usuario || '';
  document.getElementById('pv_saldo_actual').value = money(saldo);
  document.getElementById('pv_abono').value = '';
  document.getElementById('pv_obs').value = '';
  document.getElementById('pv_saldo_nuevo').value = money(saldo);

  modalCobroPV.show();
  setTimeout(()=>document.getElementById('pv_abono')?.focus(), 200);
}
function recalcularPV(){
  const saldo = toNumber(document.getElementById('pv_saldo_actual').value);
  const abono = toNumber(document.getElementById('pv_abono').value);
  document.getElementById('pv_saldo_nuevo').value = money(saldo - abono);
}
document.addEventListener('input', (e)=>{
  if(e.target && e.target.id === 'pv_abono') recalcularPV();
});

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

async function guardarCobroPV(){
  const id_punto_venta = parseInt(document.getElementById('pv_id').value || '0', 10) || 0;
  const saldo = toNumber(document.getElementById('pv_saldo_actual').value);
  const abono = toNumber(document.getElementById('pv_abono').value);
  const observacion = (document.getElementById('pv_obs').value || '').trim();

  if(id_punto_venta <= 0) return Swal.fire('Error','ID PV inválido','error');
  if(abono <= 0) return Swal.fire('Atención','Ingrese un abono mayor a 0','warning');
  if(abono > saldo) return Swal.fire('Atención','Abono mayor al saldo','warning');

  try{
    const j = await apiPVcobro('cobro_pv', { id_punto_venta, abono, observacion });
    await Swal.fire('OK', j.message || 'Cobro guardado', 'success');
    modalCobroPV.hide();
    reloadTable();
  }catch(err){
    Swal.fire('Error', err.message || 'Error', 'error');
  }
}

// ======= HISTORIAL PV =======
function openHistorialPV(){
  if(!modalHistPV) modalHistPV = new bootstrap.Modal(document.getElementById('modalHistPV'));
  if(!dtHistPV){
    dtHistPV = $('#tbHistPV').DataTable({
      searching:true,
      lengthChange:false,
      pageLength:25,
      responsive:true,
      ordering:false,
      language: DT_ES,
      columnDefs:[
        {targets:0, className:'text-center', width:'40px'},
        {targets:[3,4,5,7], className:'text-end'}
      ]
    });
  }
  modalHistPV.show();
  setTimeout(()=>{ document.getElementById('his_pv_id')?.focus(); loadHistorialPV(); }, 220);
}

async function loadHistorialPV(){
  const id_punto_venta = parseInt(document.getElementById('his_pv_id').value || '0', 10) || 0;
  const desde = (document.getElementById('his_pv_desde').value || '').trim();
  const hasta = (document.getElementById('his_pv_hasta').value || '').trim();

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

  try{
    const j = await apiPVcobro('historial_pv', payload);
    dtHistPV.clear();

    (j.data || []).forEach((r, idx)=>{
      const disabled = parseInt(r.anulado||0,10) === 1 ? 'disabled' : '';
      const btn = parseInt(r.anulado||0,10) === 1
        ? `<span class="badge bg-secondary">ANULADO</span>`
        : `<button class="btn btn-outline-danger btn-sm" ${disabled} onclick="anularPV(${parseInt(r.id,10)})"><i class="fa-solid fa-ban"></i></button>`;

      dtHistPV.row.add([
        idx+1,
        esc(r.fecha_hora),
        esc(r.punto_venta),
        `<b>${money(r.saldo_anterior)}</b>`,
        `<b>${money(r.abono)}</b>`,
        `<b>${money(r.saldo_nuevo)}</b>`,
        esc(r.observacion || ''),
        btn
      ]);
    });

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

// ✅ ANULAR PV (sin bloquear input: ocultamos modal antes de Swal)
async function anularPV(id_cobro){
  try { modalHistPV.hide(); } catch(e){}

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

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

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

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

    try { modalHistPV.show(); } catch(e){}
    setTimeout(()=>loadHistorialPV(), 250);
  }catch(err){
    await Swal.fire('Error', err.message || 'Error', 'error');
    try { modalHistPV.show(); } catch(e){}
  }
}

// ===== Datatable PV =====
$(function(){
  loadSucursales();

  dt = $('#tabla').DataTable({
    pageLength: 10,
    language: DT_ES,
    ajax: {
      url: 'api/pv_list_simple.php',
      type: 'POST',
      contentType: 'application/json',
      data: () => JSON.stringify({}),
      dataSrc: (json) => (json && json.success) ? (json.data || []) : [],
      error: function(xhr){ console.log('❌ pv_list_simple.php:', xhr.responseText); }
    },
    columns: [
      { data:'usuario' },
      { data:'sucursal' },
      { data:'activo', render:(d)=> d==1 ? '<span class="badge bg-success">Sí</span>' : '<span class="badge bg-secondary">No</span>' },
      { data:'saldo', className:'text-end', render:(d)=> `<b>${money(d)}</b>` },
      {
        data:'raspadita',
        orderable:false,
        className:'text-center',
        render:(d,t,row)=>{
          const checked = (parseInt(d,10) === 1) ? 'checked' : '';
          return `
            <div class="form-check form-switch m-0 d-flex justify-content-center">
              <input class="form-check-input pv-rsp"
                     type="checkbox"
                     role="switch"
                     data-id="${row.idusuario}"
                     ${checked}>
            </div>
          `;
        }
      },
      {
        data:null,
        orderable:false,
        className:'text-end',
        render:(d,t,row)=>{
          return `
            <div class="d-flex justify-content-end gap-1">
              <button class="btn btn-outline-success btn-sm" title="Cobro" onclick='openCobroPV(${JSON.stringify(row)})'>
                <i class="fa-solid fa-cash-register"></i>
              </button>
              <button class="btn btn-outline-primary btn-sm" title="Editar" onclick='openModal(${JSON.stringify(row)})'>
                <i class="fa-solid fa-pen"></i>
              </button>
            </div>
          `;
        }
      }
    ],
    order: [[0,'asc']]
  });
});

/* ✅ EVENTO SWITCH raspadita */
$(document).on('change', '.pv-rsp', async function(){
  const sw = this;
  const id = parseInt(sw.getAttribute('data-id') || '0', 10);
  const val = sw.checked ? 1 : 0;

  sw.disabled = true;

  try{
    const res = await fetch('api/pv_toggle_raspadita.php', {
      method:'POST',
      headers:{'Content-Type':'application/json','Accept':'application/json'},
      body: JSON.stringify({ idusuario:id, raspadita:val })
    });

    const text = await res.text();
    let j = null; try { j = JSON.parse(text); } catch(e){}

    if(!res.ok || !j || !j.success){
      sw.checked = !sw.checked;
      showMsg(j?.message || 'No se pudo actualizar raspadita.', false);
      console.log('❌ pv_toggle_raspadita:', text);
    }else{
      showMsg(j.message || 'Actualizado ✅', true);
    }

  }catch(err){
    sw.checked = !sw.checked;
    showMsg('Error de red al actualizar.', false);
    console.log(err);
  }finally{
    sw.disabled = false;
  }
});

// 👁️ Mostrar / ocultar clave
document.addEventListener('click', function(e){
  if(e.target.closest('#toggleClave')){
    const input = document.getElementById('clave');
    const icon  = e.target.closest('#toggleClave').querySelector('i');
    if(input.type === 'password'){
      input.type = 'text';
      icon.classList.remove('fa-eye');
      icon.classList.add('fa-eye-slash');
    } else {
      input.type = 'password';
      icon.classList.remove('fa-eye-slash');
      icon.classList.add('fa-eye');
    }
  }
});

// ✅ FIX ARIA-HIDDEN / FOCUS (SIN focusin global, SIN loops)
(function(){
  const modalIds = ['mdl','modalCobroPV','modalHistPV'];

  function focusFirst(modalEl){
    const el = modalEl.querySelector('input, textarea, select, button, [tabindex]:not([tabindex="-1"])');
    if(el) setTimeout(()=>el.focus(), 180);
  }

  modalIds.forEach(id=>{
    const m = document.getElementById(id);
    if(!m) return;

    m.addEventListener('shown.bs.modal', ()=> focusFirst(m));

    m.addEventListener('hide.bs.modal', ()=>{
      const ae = document.activeElement;
      if (ae && m.contains(ae)) ae.blur();
    });

    m.addEventListener('hidden.bs.modal', ()=>{
      const fallback = document.getElementById('btnOpenHistPV') || document.getElementById('btnOpenModalPV');
      if (fallback) setTimeout(()=>fallback.focus(), 50);
    });
  });
})();
</script>

</body>
</html>
