// Archivo modular para gestionar deducciones
import { showToast, formatNumber, formatInteger, formatPercent } from './utilidades.js';

$(document).ready(function() {
  const $tabla = $('#tablaDeducciones');
  let dataTable = null;

  async function fetchDeducciones() {
    try {
      const res = await fetch('../../backend/deducciones/get_deducciones.php');
      const text = await res.text();
      try {
        const json = JSON.parse(text);
        return json.deducciones || [];
      } catch (e) {
        console.error('Respuesta no es JSON válido:', text);
        showToast('Error al cargar deducciones: respuesta no válida del servidor', 'danger');
        return [];
      }
    } catch (err) {
      console.error('Error de red al cargar deducciones:', err);
      showToast('Error de red al cargar deducciones', 'danger');
      return [];
    }
  }

  function renderTable(data) {
    if (dataTable) {
      dataTable.clear().rows.add(data).draw();
      return;
    }

    dataTable = $tabla.DataTable({
      data,
      language: {
        url: "../../assets/i18n/es-ES.json"
      },
      columns: [
        { data: 'descripcion' },
    { data: null, title: 'Monto', render: row => {
      const monto = Number(row.monto) || 0;
      const interes = Number(row.interes_fijo) || 0;
      const montoConInteres = monto + (monto * (interes / 100));
      return `$${formatNumber(montoConInteres)}`;
    } },
    { data: null, title: 'Parcialidad a cubrir', render: row => {
      // Si es la última parcialidad, mostrar SIEMPRE el saldo real pendiente aunque exista monto reducido
      const monto = Number(row.monto) || 0;
      const interes = Number(row.interes_fijo) || 0;
      const parcialidades = Number(row.parcialidades) || 0;
      const pendientes = Number(row.parcialidades_pendientes ?? row.parcialidadesPendientes ?? 0);
      const aportacionVoluntaria = Number(row.aportacionVoluntaria) || 0;
      const saldoAportacion = Number(row.saldo_aportacion) || 0;
      if (pendientes === 1) {
        // Última parcialidad: mostrar saldo real pendiente
        let saldoFinal = (monto + (monto * (interes / 100))) - (aportacionVoluntaria + saldoAportacion);
        if (!isFinite(saldoFinal) || saldoFinal < 0) saldoFinal = 0;
        return `$${formatNumber(saldoFinal)}`;
      }
      // Si no es la última parcialidad, mostrar monto reducido si existe, si no, la parcialidad normal
      const nuevoMonto = row.nuevo_monto_a_pagar !== null && row.nuevo_monto_a_pagar !== undefined && row.nuevo_monto_a_pagar !== '' ? Number(row.nuevo_monto_a_pagar) : null;
      if (nuevoMonto !== null && !isNaN(nuevoMonto)) {
        return `<span style='color:#007bff;font-weight:bold;'>$${formatNumber(nuevoMonto)}</span> <span style='background:#e0f3ff;color:#007bff;border-radius:4px;padding:2px 7px;font-size:0.85em;margin-left:4px;'>Monto reducido</span>`;
      }
      const montoConInteres = parcialidades > 0 ? (monto + (monto * (interes / 100))) / parcialidades : 0;
      return `$${formatNumber(montoConInteres)}`;
      }
    },
        { data: 'parcialidades_pendientes', title: 'Parcialidades pendientes', render: v => formatInteger(v) },
        { data: 'parcialidades', title: 'Parcialidades totales', render: v => formatInteger(v) },
        { data: 'interes_fijo', render: v => formatPercent(v) },
        { data: 'fecha_inicio_pago', title: 'Inicio de pago', render: v => {
            if (!v) return '';
            const [y, m, d] = v.split('-');
            return `${d.padStart(2, '0')}/${m.padStart(2, '0')}/${y}`;
          }
        },
        { data: 'fecha_fin', title: 'Fecha fin', render: v => {
            if (!v) return '';
            const [y, m, d] = v.split('-');
            return `${d.padStart(2, '0')}/${m.padStart(2, '0')}/${y}`;
          }
        },
        { data: 'solicitante' },
        { data: 'activo', render: v => v == 1 ? '<span class="badge bg-success">Sí</span>' : '<span class="badge bg-secondary">No</span>' },
        { data: null, orderable: false, render: (row) => {
          const disabled = row.activo == 0 ? 'disabled' : '';
          return `
            <button class="btn btn-sm btn-primary btn-edit" data-id="${row.id}" ${disabled}><i class="fas fa-edit"></i></button>
            <button class="btn btn-sm btn-warning btn-toggle" data-id="${row.id}" data-activo="${row.activo}" ${disabled}><i class="fas fa-toggle-on"></i></button>
          `;
        }}
      ]
    });
  }

  async function loadAndRender() {
    const data = await fetchDeducciones();
    renderTable(data);
  }

  // Eventos
  // Flujo: seleccionar persona primero, luego mostrar formulario de deducción
  $('#btnNuevo').on('click', async () => {
    // 1) Modal de búsqueda y selección de empleado
    const { value: seleccion } = await Swal.fire({
      title: 'Seleccionar persona',
      html: `
        <input id="busq-persona" class="swal2-input" placeholder="Nombre, CURP o ATTUID">
        <div id="resultados-persona" style="max-height:200px; overflow:auto; text-align:left;"></div>
      `,
      showCancelButton: true,
      confirmButtonText: 'Seleccionar',
      preConfirm: () => {
        // devolver el contenido del input; la selección se hará desde la lista
        return document.getElementById('busq-persona').value;
      },
      didOpen: () => {
        const input = document.getElementById('busq-persona');
        const resultados = document.getElementById('resultados-persona');
        let timeout = null;
        input.addEventListener('input', (e) => {
          clearTimeout(timeout);
          const q = e.target.value.trim();
          if (!q) { resultados.innerHTML = ''; return; }
          timeout = setTimeout(async () => {
            resultados.innerHTML = '<div class="p-2 text-muted">Buscando...</div>';
            try {
              const r = await fetch(`../../backend/plantilla/buscar_empleados_ajax.php?q=${encodeURIComponent(q)}`);
              const arr = await r.json();
              if (!Array.isArray(arr) || arr.length === 0) {
                resultados.innerHTML = '<div class="p-2 text-muted">No se encontraron resultados</div>';
                return;
              }
              resultados.innerHTML = arr.map(emp => `
                <div class="p-2 border-bottom">
                  <div><strong>${emp.NOMBRES} ${emp['APELLIDO PATERNO']} ${emp['APELLIDO MATERNO']}</strong></div>
                  <div class="small text-muted">ATTUID: ${emp.ATTUID} · CURP: ${emp.CURP}</div>
                  <div class="mt-1"><button class="btn btn-sm btn-primary btn-select-person" data-attuid="${emp.ATTUID}" data-nombre="${emp.NOMBRES} ${emp['APELLIDO PATERNO']} ${emp['APELLIDO MATERNO']}">Seleccionar</button></div>
                </div>
              `).join('');
              // attach events
              resultados.querySelectorAll('.btn-select-person').forEach(btn => {
                btn.addEventListener('click', () => {
                  const attuid = btn.getAttribute('data-attuid');
                  const nombre = btn.getAttribute('data-nombre');
                  // cerrar modal y regresar objeto seleccionado
                  Swal.close();
                  abrirFormularioDeduccion({ solicitante: nombre, solicitante_attuid: attuid });
                });
              });
            } catch (err) {
              resultados.innerHTML = '<div class="p-2 text-danger">Error al buscar</div>';
            }
          }, 300);
        });
      }
    });
    // Si el usuario cierra el modal sin seleccionar, no hacemos nada
  });

  async function fetchConceptos() {
    const res = await fetch('../../backend/deducciones/get_conceptos.php');
    const json = await res.json();
    return json.conceptos || [];
  }

  // Abre el formulario de deducción con datos opcionales de solicitante
  async function abrirFormularioDeduccion(prefill = {}) {
      // Obtener quincenas disponibles del backend
      async function fetchQuincenas() {
        const res = await fetch('../../backend/deducciones/get_quincenas_disponibles.php');
        const json = await res.json();
        return json.quincenas || [];
      }

      const conceptos = await fetchConceptos();
      const opcionesConceptos = conceptos.map(c => `<option value="${c.concepto}" data-id="${c.id}">${c.concepto}</option>`).join('');
      const quincenas = await fetchQuincenas();
      // Formatear fecha a DD/MM/AAAA
      function formatFecha(fechaStr) {
        if (!fechaStr) return '';
        // Forzar a tratar la fecha como UTC para evitar desfase de zona horaria
        const [y, m, d] = fechaStr.split('-');
        return `${d.padStart(2, '0')}/${m.padStart(2, '0')}/${y}`;
      }
      const opcionesQuincenas = quincenas.map(q => `<option value="${q.id_quincena}">${formatFecha(q.fecha_fin)}</option>`).join('');

  // Construir contenido HTML con estilos mejorados
  const html = `
    <style>
      .dedu-modal-container {
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
      }
      
      .form-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 16px;
        width: 100%;
        box-sizing: border-box;
      }
      
      .form-group {
        margin-bottom: 12px;
        width: 100%;
        box-sizing: border-box;
      }
      
      .form-group.full-width {
        grid-column: span 2;
      }
      
      .form-group.half-width {
        grid-column: span 1;
      }
      
      .form-label {
        display: block;
        margin-bottom: 6px;
        font-weight: 600;
        color: #495057;
        font-size: 0.9rem;
      }
      
      .swal2-input, .swal2-select {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
        margin: 0 !important;
        padding: 8px 12px !important;
        border-radius: 6px !important;
        border: 1px solid #ced4da !important;
        font-size: 0.95rem !important;
      }
      
      .input-row {
        display: flex;
        gap: 12px;
        width: 100%;
        box-sizing: border-box;
      }
      
      .input-row > div {
        flex: 1;
        min-width: 0;
      }
      
      .summary-panel {
        background: #f8f9fa;
        border-radius: 8px;
        padding: 16px;
        margin-top: 16px;
        border-left: 4px solid #007bff;
      }
      
      .summary-title {
        font-weight: 600;
        margin-bottom: 8px;
        color: #2c3e50;
      }
      
      @media (max-width: 768px) {
        .form-grid {
          grid-template-columns: 1fr;
        }
        
        .form-group.full-width, 
        .form-group.half-width {
          grid-column: span 1;
        }
        
        .input-row {
          flex-direction: column;
          gap: 8px;
        }
      }
    </style>

    <div class="dedu-modal-container">
      <div class="form-grid">
        <!-- Concepto -->
        <div class="form-group full-width">
          <label class="form-label">Concepto</label>
          <select id="swal-desc" class="swal2-select">
            <option value="" disabled selected>Seleccione un concepto...</option>
            ${opcionesConceptos}
          </select>
        </div>

        <!-- Monto e Interés -->
        <div class="form-group full-width">
          <div class="input-row">
            <div>
              <label class="form-label">Monto</label>
              <input id="swal-monto" class="swal2-input" placeholder="0.00" type="text" inputmode="decimal" autocomplete="off">
            </div>
            <div>
              <label class="form-label">Interés fijo (%)</label>
              <input id="swal-interes" class="swal2-input" placeholder="0.00" type="number" step="0.01">
            </div>
          </div>
        </div>


        <!-- Parcialidades -->
        <div class="form-group half-width">
          <label class="form-label">Parcialidades</label>
          <input id="swal-parc" class="swal2-input" placeholder="0" type="number">
        </div>

        <!-- Periodicidad -->
        <div class="form-group half-width">
          <label class="form-label">Selecciona periodicidad</label>
          <select id="swal-periodicidad" class="swal2-select">
            <option value="" disabled selected>Selecciona...</option>
            <option value="Quincenal">Quincenal</option>
            <option value="Mensual">Mensual</option>
          </select>
        </div>

        <!-- Quincena de inicio -->
        <div class="form-group full-width">
          <label class="form-label">Quincena de inicio</label>
          <select id="swal-quincena" class="swal2-select">
            <option value="" disabled selected>Selecciona quincena...</option>
            ${opcionesQuincenas}
          </select>
        </div>

        <!-- Solicitante -->
        <div class="form-group full-width">
          <label class="form-label">Solicitante</label>
          <input id="swal-solicitante" class="swal2-input" placeholder="Nombre" value="${prefill.solicitante ? prefill.solicitante : ''}">
        </div>
      </div>

      <!-- Resumen -->
      <div class="summary-panel">
        <div class="summary-title">Resumen</div>
        <div id="monto-por-parcialidad" style="font-weight: 500; color: #2c3e50;">
          Ingrese monto y parcialidades
        </div>
        <div style="font-size: 0.85rem; color: #6c757d; margin-top: 8px;">
          Asegúrate de elegir un concepto correcto. Las fechas deben ser día 15 o último día del mes.
        </div>
      </div>
    </div>
  `;

  const result = await Swal.fire({
    title: 'Nueva deducción',
    html,
    width: '800px',
    padding: '20px',
    showCancelButton: true,
    confirmButtonText: 'Generar formato',
    cancelButtonText: 'Cancelar',
    customClass: {
      container: 'dedu-modal-container',
      popup: 'custom-swal-popup'
    },
    didOpen: () => {
      // Configurar eventos y validaciones
      const montoEl = document.getElementById('swal-monto');
  const parcEl = document.getElementById('swal-parc');
  const interesEl = document.getElementById('swal-interes');
  const periodicidadEl = document.getElementById('swal-periodicidad');
  const quincenaEl = document.getElementById('swal-quincena');
  const display = document.getElementById('monto-por-parcialidad');

      // Formatear monto con separador de miles en vivo
      const formatMiles = n => {
        if (n === '' || n === null || n === undefined) return '';
        const parts = n.toString().replace(/[^\d.]/g, '').split('.');
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
        return parts.join('.');
      };

      const actualizarResumen = () => {
        // Obtener valor numérico real del input (sin comas)
        const rawMonto = montoEl.value.replace(/,/g, '');
        const monto = parseFloat(rawMonto) || 0;
        const parc = parseInt(parcEl.value) || 0;
        const interes = parseFloat(interesEl.value) || 0;
        
        if (parc > 0) {
          const total = monto + (monto * (interes / 100));
          const porParcialidad = total / parc;
          display.innerHTML = `
            <strong>Total con interés:</strong> $${formatNumber(total)}<br>
            <strong>Por parcialidad:</strong> $${formatNumber(porParcialidad)}
          `;
        } else {
          display.textContent = 'Ingrese número de parcialidades válido';
        }
      };

      // Evento para formatear el input de monto en vivo
      montoEl.addEventListener('input', (e) => {
        // Mantener el cursor al final
        const pos = montoEl.selectionStart;
        let val = montoEl.value.replace(/,/g, '');
        // Permitir solo números y punto
        val = val.replace(/[^\d.]/g, '');
        // Formatear
        montoEl.value = formatMiles(val);
        // Restaurar posición del cursor
        montoEl.setSelectionRange(montoEl.value.length, montoEl.value.length);
        actualizarResumen();
      });

      const validarFecha = (fechaStr) => {
        if (!fechaStr) return true;
        const fecha = new Date(fechaStr);
        const dia = fecha.getDate();
        const ultimoDia = new Date(fecha.getFullYear(), fecha.getMonth() + 1, 0).getDate();
        return dia === 15 || dia === ultimoDia;
      };

      // Event listeners
      [montoEl, parcEl, interesEl].forEach(el => {
        el.addEventListener('input', actualizarResumen);
      });

  // Ahora la fecha es libre, sin restricciones de día

  // Prellenar datos si existen
  if (prefill.monto) montoEl.value = prefill.monto;
  if (prefill.parcialidades) parcEl.value = prefill.parcialidades;
  if (prefill.interes_fijo) interesEl.value = prefill.interes_fijo;
  if (prefill.periodicidad) periodicidadEl.value = prefill.periodicidad;
  if (prefill.id_quincena) quincenaEl.value = prefill.id_quincena;

  actualizarResumen();
    },
    preConfirm: () => {
      // Validaciones antes de confirmar
      const descEl = document.getElementById('swal-desc');
      const descripcion = descEl && descEl.value ? descEl.value : '';
  const monto = parseFloat(document.getElementById('swal-monto').value.replace(/,/g, ''));
      const parc = parseInt(document.getElementById('swal-parc').value);
      const periodicidad = document.getElementById('swal-periodicidad').value;
      const id_quincena = document.getElementById('swal-quincena').value;

      if (!descripcion || descripcion === '') {
        Swal.showValidationMessage('Seleccione un concepto válido');
        return false;
      }
      if (!monto || monto <= 0) {
        Swal.showValidationMessage('Ingrese un monto válido');
        return false;
      }
      if (!parc || parc <= 0) {
        Swal.showValidationMessage('Ingrese un número válido de parcialidades');
        return false;
      }
      if (!periodicidad) {
        Swal.showValidationMessage('Seleccione la periodicidad');
        return false;
      }
      if (!id_quincena) {
        Swal.showValidationMessage('Seleccione la quincena de inicio');
        return false;
      }

      const interes = parseFloat(document.getElementById('swal-interes').value) || 0;
      return {
        concepto: descripcion, // Enviar como 'concepto' para el backend
        descripcion,
        monto,
        parcialidades: parc,
        interes_fijo: interes,
        periodicidad,
        id_quincena,
        solicitante: document.getElementById('swal-solicitante').value || prefill.solicitante_attuid || prefill.solicitante,
        monto_por_parcialidad: parseFloat((monto + (monto * (interes / 100))) / parc).toFixed(2)
      };
    }
  });

    // Si hay datos válidos, generar el PDF y mostrar preview antes de guardar
    const formValues = result && result.value ? result.value : null;
    if (formValues) {
      // Generar PDF en backend
      const res = await fetch('../../backend/deducciones/generar_formato_deduccion.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formValues)
      });
      const json = await res.json();
      if (json.success && json.file) {
        // Mostrar preview del PDF y botón para guardar
        const pdfUrl = '../../' + json.file;
        const previewHtml = `
          <iframe src="${pdfUrl}" style="width:100%;height:500px;border:1px solid #ccc;"></iframe>
          <div style="margin-top:20px;text-align:right;">
            <a href="${pdfUrl}" target="_blank" class="btn btn-secondary">Descargar PDF</a>
          </div>
        `;
        const confirm = await Swal.fire({
          title: 'Previsualización de formato',
          html: previewHtml,
          width: '900px',
          showCancelButton: true,
          confirmButtonText: 'Guardar deducción',
          cancelButtonText: 'Cancelar'
        });
        if (confirm.isConfirmed) {
          // Guardar deducción
          const res2 = await fetch('../../backend/deducciones/insert_deduccion.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(formValues)
          });
          const json2 = await res2.json();
          if (json2.success) {
            showToast('Deducción creada', 'success');
            loadAndRender();
          } else {
            showToast(json2.message || 'Error', 'danger');
          }
        } else {
          showToast('No se guardó la deducción', 'info');
        }
      } else {
        showToast(json.message || 'Error al generar formato', 'danger');
      }
    }
  }

  // Delegación para editar y toggle
  $('#tablaDeducciones tbody').on('click', '.btn-edit', async function() {
    const id = $(this).data('id');
    const row = dataTable.data().toArray().find(r => r.id == id);
    if (!row) return;

    // Modal de abono a capital estilizado
  const monto = Number(row.monto) || 0;
  const interes = Number(row.interes_fijo) || 0;
  const total = monto + (monto * (interes / 100));
  const aportacionVoluntaria = Number(row.aportacionVoluntaria) || 0;
  const saldoAportacion = Number(row.saldo_aportacion) || 0;
  let saldoPendiente = total - (aportacionVoluntaria + saldoAportacion);
  if (!isFinite(saldoPendiente) || saldoPendiente < 0) saldoPendiente = 0;

    const html = `
      <style>
        .abono-modal-container {
          width: 100%;
          max-width: 100%;
          box-sizing: border-box;
        }
        .abono-modal-grid {
          display: flex;
          flex-direction: column;
          gap: 12px;
          width: 100%;
          box-sizing: border-box;
        }
        .abono-modal-label {
          font-weight: 600;
          color: #495057;
          margin-bottom: 4px;
        }
        .swal2-input, .swal2-select {
          width: 100% !important;
          max-width: 100% !important;
          box-sizing: border-box !important;
          margin: 0 !important;
          padding: 8px 12px !important;
          border-radius: 6px !important;
          border: 1px solid #ced4da !important;
          font-size: 0.95rem !important;
        }
        .abono-modal-info {
          background: #f8f9fa;
          border-radius: 8px;
          padding: 12px 16px;
          margin-bottom: 8px;
          border-left: 4px solid #28a745;
        }
        @media (max-width: 600px) {
          .swal2-popup { width: 98vw !important; }
        }
      </style>
      <div class="abono-modal-container">
        <div class="abono-modal-info">
          <div><span class="abono-modal-label">Solicitante:</span> ${row.solicitante}</div>
          <div><span class="abono-modal-label">Concepto:</span> ${row.descripcion}</div>
          <div><span class="abono-modal-label">Monto total con intereses:</span> $${formatNumber(total)}</div>
          <div><span class="abono-modal-label">Saldo pendiente por cubrir:</span> $${formatNumber(saldoPendiente)}</div>
        </div>
        <div class="abono-modal-grid">
          <div>
            <label class="abono-modal-label">Monto del abono a capital</label>
            <input id="abono-capital" class="swal2-input" type="number" min="1" max="${saldoPendiente}" placeholder="0.00">
          </div>
          <div>
            <label class="abono-modal-label">¿Qué deseas hacer con el abono?</label>
            <select id="opcion-abono" class="swal2-select">
              <option value="adelantar">Adelantar la fecha fin (reducir número de pagos)</option>
              <option value="reducir">Reducir el monto de los pagos mensuales</option>
            </select>
          </div>
          <div id="info-reduccion-pagos" style="display:none; margin-top:8px; background:#f1f3f4; border-radius:6px; padding:10px 14px; font-size:0.97em; color:#333;"></div>
        </div>
      </div>
    `;

    const result = await Swal.fire({
      title: 'Abono a capital / Aportación voluntaria',
      html,
      width: '600px',
      padding: '20px',
      showCancelButton: true,
      confirmButtonText: 'Aplicar abono',
      cancelButtonText: 'Cancelar',
      customClass: {
        container: 'abono-modal-container',
        popup: 'custom-swal-popup'
      },
      didOpen: () => {
        const abonoInput = document.getElementById('abono-capital');
        const opcionSelect = document.getElementById('opcion-abono');
        const infoDiv = document.getElementById('info-reduccion-pagos');
        if (!infoDiv) {
          // elemento info-reduccion-pagos no encontrado
        }
        function actualizarInfoReduccion() {
          try {
            // Intentar normalizar / inferir periodicidad
            const periodicidadRaw = row.periodicidad ?? row.periodicidad_pago ?? row.periodicidad_periodo ?? '';
            let periodicidadVal = (periodicidadRaw || '').toString().toLowerCase();
            let periodicidadInferida = false;
            if (!periodicidadVal && row.fecha_fin) {
              try {
                const ftmp = new Date(row.fecha_fin);
                const dia = ftmp.getDate();
                // Si la fecha de fin cae en día 15, es muy probable que sea quincenal; si no, asumir mensual
                periodicidadVal = dia === 15 ? 'quincenal' : 'mensual';
                periodicidadInferida = true;
              } catch (e) {
                periodicidadVal = '';
              }
            }

            // Actualiza la vista previa de la nueva fecha fin en tiempo real
            if (opcionSelect.value === 'adelantar') {
              let abono = parseFloat(abonoInput.value);
              if (!abono || abono <= 0 || abono > saldoPendiente) {
                infoDiv.style.display = 'block';
                infoDiv.innerHTML = '<span style="color:#c00">Ingrese un abono válido para ver el cálculo.</span>';
                return;
              }
              const parcialidadesPendientes = Number(row.parcialidades_pendientes ?? row.parcialidadesPendientes ?? 0);
              let montoPorParcialidad = 0;
              if (row.nuevo_monto_a_pagar && Number(row.nuevo_monto_a_pagar) > 0) {
                montoPorParcialidad = Number(row.nuevo_monto_a_pagar);
              } else {
                montoPorParcialidad = parcialidadesPendientes > 0 ? saldoPendiente / parcialidadesPendientes : 0;
              }
              const pagosAdelantados = montoPorParcialidad > 0 ? Math.floor(abono / montoPorParcialidad) : 0;
              const nuevosPendientes = Math.max(0, parcialidadesPendientes - pagosAdelantados);

              // Calcular nueva fecha fin partiendo de la fecha_fin actual y restando periodos
              let nuevaFechaFin = row.fecha_fin;
              if (periodicidadVal && row.fecha_fin && pagosAdelantados > 0) {
                const fechaFin = new Date(row.fecha_fin);
                if (periodicidadVal === 'mensual') {
                  let anio = fechaFin.getFullYear();
                  let mes = fechaFin.getMonth();
                  let dia = fechaFin.getDate();
                  mes -= pagosAdelantados;
                  while (mes < 0) { mes += 12; anio--; }
                  let ultimoDiaMes = new Date(anio, mes + 1, 0).getDate();
                  let diaFinal = dia > ultimoDiaMes ? ultimoDiaMes : dia;
                  nuevaFechaFin = `${anio}-${String(mes+1).padStart(2,'0')}-${String(diaFinal).padStart(2,'0')}`;
                } else if (periodicidadVal === 'quincenal') {
                  const fecha = new Date(row.fecha_fin);
                  fecha.setDate(fecha.getDate() - (pagosAdelantados * 15));
                  nuevaFechaFin = fecha.toISOString().slice(0,10);
                } else {
                  // Si periodicidad desconocida, no intentar ajustar fecha
                  nuevaFechaFin = row.fecha_fin;
                }
              }

              infoDiv.style.display = 'block';
              let notaInferencia = '';
              if (periodicidadInferida) {
                notaInferencia = `<div style="color:#b36b00;font-size:0.9em;margin-top:6px;">Nota: periodicidad no provista; se infirió como <b>${periodicidadVal}</b> para el cálculo.</div>`;
              }
              infoDiv.innerHTML = `
                <b>Vista previa de adelanto:</b><br>
                <ul style="margin:0 0 0 18px;padding:0;">
                  <li><b>Pagos adelantados:</b> ${pagosAdelantados}</li>
                  <li><b>Pagos restantes:</b> ${nuevosPendientes}</li>
                  <li><b>Nueva fecha fin:</b> <span id="nueva-fecha-fin">${nuevaFechaFin ? nuevaFechaFin.split('-').reverse().join('/') : '-'}</span></li>
                </ul>
                ${notaInferencia}
                <span style="color:#888;font-size:0.93em;">* Este cálculo es informativo y se aplicará al confirmar el adelanto.</span>
              `;

              // Forzar actualización visual inmediata
              const nuevaFechaFinEl = document.getElementById('nueva-fecha-fin');
              if (nuevaFechaFinEl) {
                nuevaFechaFinEl.textContent = nuevaFechaFin ? nuevaFechaFin.split('-').reverse().join('/') : '-';
              }
              return;
            }
            if (opcionSelect.value === 'reducir') {
              let abono = parseFloat(abonoInput.value);
              if (!abono || abono <= 0 || abono > saldoPendiente) {
                infoDiv.style.display = 'block';
                infoDiv.innerHTML = '<span style="color:#c00">Ingrese un abono válido para ver el cálculo.</span>';
                return;
              }
              // Cálculo de nuevo saldo y nuevo monto por pago
              const saldoPendienteReducido = saldoPendiente - abono;
              const parcialidadesPendientes = Number(row.parcialidades_pendientes ?? row.parcialidadesPendientes ?? 0);
              const nuevoMontoPorPago = parcialidadesPendientes > 0 ? saldoPendienteReducido / parcialidadesPendientes : 0;
              infoDiv.style.display = 'block';
              infoDiv.innerHTML = `
                <b>Nuevo cálculo de pagos:</b><br>
                <ul style="margin:0 0 0 18px;padding:0;">
                  <li><b>Saldo pendiente tras abono:</b> $${formatNumber(saldoPendienteReducido)}</li>
                  <li><b>Pagos restantes:</b> ${parcialidadesPendientes}</li>
                  <li><b>Nuevo monto estimado por pago:</b> $${formatNumber(nuevoMontoPorPago)}</li>
                </ul>
                <span style="color:#888;font-size:0.93em;">* Este cálculo es informativo y se aplicará al confirmar la reducción.</span>
              `;
              return;
            }
            infoDiv.style.display = 'none';
            infoDiv.innerHTML = '';
          } catch (err) {
            // error silenciado en preview (se puede reportar si se desea)
          }
        }
        if (abonoInput) abonoInput.addEventListener('input', actualizarInfoReduccion);
        if (opcionSelect) opcionSelect.addEventListener('change', actualizarInfoReduccion);
        // Ejecutar una vez al abrir para inicializar la vista previa
        try {
          actualizarInfoReduccion();
        } catch (err) {
          // inicialización fallida
        }
      },
      preConfirm: () => {
        const abono = parseFloat(document.getElementById('abono-capital').value);
        const opcion = document.getElementById('opcion-abono').value;
        if (!abono || abono <= 0 || abono > saldoPendiente) {
          Swal.showValidationMessage('Ingrese un monto válido de abono');
          return false;
        }
        if (!opcion) {
          Swal.showValidationMessage('Seleccione una opción');
          return false;
        }
        return { id, abono, opcion };
      }
    });

    const formValues = result && result.value ? result.value : null;
    if (formValues) {
      // Aquí deberías llamar a un endpoint backend para procesar el abono y reestructuración
      // Por ejemplo: abonar_capital.php
      const res = await fetch('../../backend/deducciones/abonar_capital.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formValues)
      });
      const json = await res.json();
      if (json.success) {
        showToast('Abono aplicado correctamente', 'success');
        loadAndRender();
      } else {
        showToast(json.message || 'Error', 'danger');
      }
    }
  });

  $('#tablaDeducciones tbody').on('click', '.btn-toggle', async function() {
    const id = $(this).data('id');
    // Buscar la fila de la deducción
    const row = dataTable.data().toArray().find(r => r.id == id);
    if (!row) return;



  // Nuevo cálculo de mensualidad actual basado en parcialidades y parcialidades pendientes
  const total = Number(row.monto) + (Number(row.monto) * (Number(row.interes_fijo) / 100));
  const parcialidades = Number(row.parcialidades) || 0; // total
  const parcialidadesPendientes = Number(row.parcialidades_pendientes ?? row.parcialidadesPendientes ?? 0); // pendientes
  const mensualidadesCubiertas = parcialidades - parcialidadesPendientes; // ya pagadas
  const montoPorParcialidad = parcialidades > 0 ? total / parcialidades : 0;
  const pendientes = parcialidadesPendientes;
  let saldoPendiente = montoPorParcialidad * pendientes;
  if (!isFinite(saldoPendiente) || saldoPendiente < 0) saldoPendiente = 0;

    const { value: confirmar } = await Swal.fire({
      title: 'Liquidar adeudo',
      html: `
        <div style="text-align:left">
      <p><strong>Solicitante:</strong> ${row.solicitante}</p>
      <p><strong>Concepto:</strong> ${row.descripcion}</p>
      <p><strong>Mensualidades cubiertas:</strong> ${mensualidadesCubiertas} de ${parcialidades}</p>
      <p><strong>Saldo pendiente a liquidar:</strong> <span style="color:#c00;font-weight:bold;">$${formatNumber(saldoPendiente)}</span></p>
      <p>¿Deseas liquidar el préstamo antes de tiempo? Esto marcará la deducción como <b>LIQUIDADA</b> y no se generarán más cobros.</p>
        </div>
      `,
      showCancelButton: true,
      confirmButtonText: 'Liquidar y cambiar estatus',
      cancelButtonText: 'Cancelar',
      icon: 'warning',
      focusConfirm: false
    });

    if (confirmar) {
      // Llamar backend para liquidar y cambiar estatus
      try {
        const res = await fetch('../../backend/deducciones/liquidar_adeudo.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id })
        });
        const json = await res.json();
        if (json.success) {
          showToast('Adeudo liquidado correctamente', 'success');
          loadAndRender();
        } else {
          showToast(json.message || 'Error al liquidar', 'danger');
        }
      } catch (e) {
        showToast('Error de conexión', 'danger');
      }
    }
  });

  // Inicializar
  loadAndRender();
});
