Favor de revisar el código y encontrar errores de programación: 

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cálculo de Nómina</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <style>
        body { 
            padding: 0; 
            background-color: #f5f5f5; 
            font-size: 11px;
        }
        .container { 
            width: 98%; 
            max-width: none;
            margin-bottom: 20px;
            overflow-x: hidden;
        }
        .table-container {
            overflow-x: auto;
            width: 100%;
            padding: 15px;
            margin-bottom: 20px;
            background: #fff;
        }
        table { 
            font-size: 11px;
            min-width: max-content;
            border-collapse: collapse;
            margin: 10px 0;
            table-layout: auto;
        }
        table th, table td { 
            padding: 8px 6px;
            text-align: right; 
            white-space: nowrap; 
            border: 1px solid #ddd;
            min-width: 100px;
            position: relative;
            box-sizing: border-box;
        }
        table th { 
            background-color: #e8eaf6;
            text-align: center;
            font-weight: bold;
            color: #1a237e;
            height: auto;
            vertical-align: middle;
            font-size: 14px;
            line-height: 1.2;
            z-index: 3;
            position: sticky;
            top: 0;
        }
        table th:first-child {
            min-width: 200px;
            z-index: 4;
            left: 0;
        }
        table td:first-child { 
            text-align: left; 
            padding-left: 8px;
            min-width: 200px;
            position: sticky;
            left: 0;
            background-color: #fff;
            z-index: 1;
            white-space: normal;
            overflow: hidden;
            text-overflow: ellipsis;
            word-wrap: break-word;
            line-height: 1.2;
            box-shadow: 2px 0 5px -2px #888;
        }
        .resizable {
            position: relative;
        }
        .resizer {
            position: absolute;
            right: 0;
            top: 0;
            height: 100%;
            width: 5px;
            cursor: col-resize;
            user-select: none;
        }
  
  .header-cell {
            cursor: pointer;
        }
        .header-cell:hover {
            background-color: #d1d9ff;
        }
        .nombre-column {
            min-width: 200px;
            max-width: 200px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: normal;
            word-wrap: break-word;
            line-height: 1.2;
            padding: 4px 8px;
            background: #fff;
            z-index: 2;
        }
        input[type="number"] { 
            width: 100%; 
            text-align: right;
            margin: 0; 
            height: 1.5rem; 
            font-size: 11px; 
            padding: 0 4px 0 15px;
            border: none;
            background-color: transparent;
            -moz-appearance: textfield;
        }
        input[type="number"]::-webkit-outer-spin-button,
        input[type="number"]::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
        .totals-row { 
            font-weight: bold;
            background-color: #e8eaf6;
            position: sticky;
            bottom: 0;
            z-index: 2;
        }
        .total-neto { 
            font-weight: bold;
            color: #1a237e;
        }
        nav .brand-logo { 
            font-size: 1.8rem;
            left: 50%;
            transform: translateX(-50%);
        }
        nav .date { 
            font-size: 1.2rem;
            padding-right: 20px;
        }
        .separator { 
            height: 3px;
            background-color: #90caf9;
            margin: 15px 0;
        }
        .narrow-col { min-width: 100px; }
        .medium-col { min-width: 120px; }
        .wide-col { min-width: 140px; }
        .modal { 
            max-height: 90%;
            width: 90%;
        }
        .button-container { 
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 20px 0;
            padding: 10px 0;
            position: sticky;
            top: 0;
            background: #f5f5f5;
            z-index: 5;
        }
        .button-group { 
            display: flex;
            gap: 15px;
        }
        .btn {
            color: black !important;
            margin: 0 5px;
            padding: 0 20px;
            height: 36px;
            line-height: 36px;
        }
        #isrResult { 
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            margin-top: 20px;
        }
        #isrResult p { 
            margin: 8px 0;
            font-size: 14px;
        }
        #payrollReceipt { 
            display: none;
            padding: 20px;
        }
        input[type="number"]:focus {
            background-color: #f5f5f5;
            border-radius: 3px;
        }
        .card {
            margin: 1rem 0;
            border-radius: 8px;
            overflow: visible;
        }
        tbody tr:hover {
            background-color: #f5f5f5;
        }
        [data-field] {
            color: #1a237e;
            text-align: right !important;
            padding-right: 8px !important;
        }
  
  input[readonly] {
            background-color: #f8f9fa;
            color: #495057;
        }
        .expandable-columns, .deduction-columns {
            display: none;
            transition: all 0.3s ease;
            min-width: 100px !important;
        }
        .expandable-columns.expanded, .deduction-columns.expanded {
            display: table-cell;
        }
        .col-fixed {
            min-width: 120px;
            background-color: #f8f9fa;
            position: sticky;
            right: auto;
            z-index: 1;
        }
        .col-total {
            min-width: 140px;
            background-color: #f8f9fa;
            display: table-cell !important;
            position: sticky;
            right: auto;
            z-index: 1;
        }
        .expand-column {
            width: 40px;
            min-width: 40px;
            max-width: 40px;
            text-align: center;
            padding: 0 !important;
            background-color: #e8eaf6;
            position: relative;
            z-index: 2;
        }
        .expand-button {
            cursor: pointer;
            font-weight: bold;
            font-size: 16px;
            padding: 0 5px;
            display: inline-block;
            width: 100%;
            height: 100%;
            line-height: 40px;
        }
        .expand-button.expanded {
            transform: rotate(45deg);
            transition: transform 0.3s ease;
        }
        .expand-button.percep {
            background-color: #e3f2fd;
            border-radius: 4px;
            color: #1565c0;
        }
        .expand-button.deduc {
            background-color: #fff3e0;
            border-radius: 4px;
            color: #ef6c00;
        }
        .expand-button.percep:hover {
            background-color: #bbdefb;
        }
        .expand-button.deduc:hover {
            background-color: #ffe0b2;
        }
        .percep-expanded {
            background-color: #e3f2fd !important;
            border-top: 2px solid #1565c0 !important;
            border-bottom: 2px solid #1565c0 !important;
            color: #1565c0 !important;
        }
        .deduc-expanded {
            background-color: #fff3e0 !important;
            border-top: 2px solid #ef6c00 !important;
            border-bottom: 2px solid #ef6c00 !important;
            color: #ef6c00 !important;
        }
        .gasto-bio {
            background-color: #e3f2fd;
            font-weight: bold;
        }
        .currency-input {
            position: relative;
        }
        .currency-input::before {
            content: '$';
            position: absolute;
            left: 4px;
            top: 50%;
            transform: translateY(-50%);
            z-index: 1;
            pointer-events: none;
            color: #666;
        }
        table td {
            padding: 8px 6px;
            height: 40px;
            vertical-align: middle;
        }
        .table-wrapper {
            position: relative;
            margin: auto;
            overflow: auto;
            white-space: nowrap;
        }
        .table-fixed-header {
            position: sticky;
            top: 0;
            z-index: 3;
            background: #e8eaf6;
        }
        .table-fixed-left {
            position: sticky;
            left: 0;
            z-index: 2;
            background: white;
        }
        .table-fixed-right {
            position: sticky;
            right: 0;
            z-index: 2;
            background: white;
        }

.number-cell {
            text-align: right;
            padding-right: 8px !important;
        }
        .sticky-header-cell {
            position: sticky;
            top: 0;
            z-index: 4;
            background: #e8eaf6;
        }
        .sticky-left-cell {
            position: sticky;
            left: 0;
            z-index: 2;
            background: white;
        }
        .sticky-right-cell {
            position: sticky;
            right: 0;
            z-index: 2;
            background: white;
        }
        .table-fixed-left::after,
        .sticky-left-cell::after {
            content: '';
            position: absolute;
            top: 0;
            right: 0;
            height: 100%;
            border-right: 2px solid #ddd;
        }
        .table-fixed-right::before,
        .sticky-right-cell::before {
            content: '';
            position: absolute;
            top: 0;
            left: -2px;
            height: 100%;
            border-left: 2px solid #ddd;
        }
        th.asc::after {
            content: ' ▲';
        }
        th.desc::after {
            content: ' ▼';
        }
    </style>
</head>

<body>
    <nav class="blue darken-1">
        <div class="nav-wrapper container">
            <a href="#" class="brand-logo">Cálculo de Nómina</a>
            <ul class="right">
                <li><span class="date">Fecha Actual: <span id="currentDate"></span></span></li>
            </ul>
        </div>
    </nav>
   
    <div class="container">
        <div class="separator"></div>
        <div class="button-container">
            <a href="#" id="backButton" class="waves-effect waves-light btn blue darken-1">
                <i class="material-icons left">arrow_back</i>Regresar
            </a>
            <div class="button-group">
                <a href="#" id="printPayrollBtn" class="waves-effect waves-light btn yellow">Imprimir Recibo de Nómina</a>
                <a href="#" id="isrCalculationBtn" class="waves-effect waves-light btn purple">Cálculo de ISR</a>
                <a href="#" id="exportExcelBtn" class="waves-effect waves-light btn green">Exportar a Excel</a>
            </div>
        </div>
      
      <div class="row">
            <div class="col s12">
                <div class="card">
                    <div class="card-content">
                        <div class="table-wrapper">
                            <div class="table-container">
                                <table class="striped">
                                    <thead class="table-fixed-header">
                                        <tr>
                                            <th class="sticky-header-cell sticky-left-cell nombre-column resizable">Nombre Completo<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col resizable">BIOCSA<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col resizable">Salario Diario<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col resizable">Toma Asistencia<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col resizable">Días Laborados<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col resizable">S.D.I.<div class="resizer"></div></th>
                                            
                                            <th class="sticky-header-cell expand-column">
                                                <span class="expand-button percep" onclick="toggleExpandableColumns(this, 'percep')">+</span>
                                            </th>
                                            
                                            <th class="sticky-header-cell medium-col expandable-columns percep-group resizable">Salario Semanal<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col expandable-columns percep-group resizable">Premio Punt<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col expandable-columns percep-group resizable">Premio Asist<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col expandable-columns percep-group resizable">Vales Despensa<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col expandable-columns percep-group resizable">Tiempo Extra<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col expandable-columns percep-group resizable">Grat<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col expandable-columns percep-group resizable">Sub Emp<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col expandable-columns percep-group resizable">Base ISR<div class="resizer"></div></th>
                                            
                                            <th class="sticky-header-cell col-fixed resizable">Total Perc<div class="resizer"></div></th>
                                            
                                            <th class="sticky-header-cell expand-column">
                                                <span class="expand-button deduc" onclick="toggleExpandableColumns(this, 'deduc')">+</span>
                                            </th>
                                            
                                            <th class="sticky-header-cell narrow-col deduction-columns deduc-group resizable">Ret IMSS<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col deduction-columns deduc-group resizable">Ret AFORE<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col deduction-columns deduc-group resizable">ISR<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col deduction-columns deduc-group resizable">Infonavit<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col deduction-columns deduc-group resizable">Ptmo<div class="resizer"></div></th>
                                            
                                            <th class="sticky-header-cell col-total sticky-right-cell resizable">Total Deduc<div class="resizer"></div></th>
                                            <th class="sticky-header-cell col-total sticky-right-cell resizable">Total Neto<div class="resizer"></div></th>
                                            <th class="sticky-header-cell narrow-col sticky-right-cell resizable">Complemento<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col sticky-right-cell resizable">Gasto BIO<div class="resizer"></div></th>
                                            <th class="sticky-header-cell medium-col sticky-right-cell resizable">Ahorro BIO<div class="resizer"></div></th>
                                        </tr>
                                    </thead>
                                    <tbody id="employeeTableBody">
                                    </tbody>
                                  
                                  <tfoot>
                                        <tr class="totals-row">
                                            <td class="sticky-left-cell nombre-column">TOTALES:</td>
                                            <td id="totalBiocsa"></td>
                                            <td id="totalSalarioDiario" class="number-cell"></td>
                                            <td id="totalTomaAsistencia" class="number-cell"></td>
                                            <td id="totalDiasLaborados" class="number-cell"></td>
                                            <td id="totalSDI" class="number-cell"></td>
                                            <td></td>
                                            <td id="totalSalarioSemanal" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalPremioPunt" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalPremioAsist" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalValesDespensa" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalTiempoExtra" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalGrat" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalSubEmpl" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalBaseISR" class="expandable-columns percep-group number-cell"></td>
                                            <td id="totalTotalPerc" class="col-fixed number-cell"></td>
                                            <td></td>
                                            <td id="totalRetIMSS" class="deduction-columns deduc-group number-cell"></td>
                                            <td id="totalRetAFORE" class="deduction-columns deduc-group number-cell"></td>
                                            <td id="totalISR" class="deduction-columns deduc-group number-cell"></td>
                                            <td id="totalInfonavit" class="deduction-columns deduc-group number-cell"></td>
                                            <td id="totalPTMO" class="deduction-columns deduc-group number-cell"></td>
                                            <td id="totalTotalDeduc" class="col-total sticky-right-cell number-cell"></td>
                                            <td id="totalTotalNeto" class="col-total sticky-right-cell total-neto number-cell"></td>
                                            <td id="totalComplemento" class="sticky-right-cell number-cell"></td>
                                            <td id="totalGastoBIO" class="sticky-right-cell gasto-bio number-cell"></td>
                                            <td id="totalAhorroBIO" class="sticky-right-cell number-cell"></td>
                                        </tr>
                                    </tfoot>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Modales -->
    <div id="isrCalculationModal" class="modal">
        <div class="modal-content">
            <h4>Cálculo de ISR</h4>
            <div class="input-field">
                <div class="currency-input">
                    <input type="number" id="isrInput" step="0.01">
                </div>
                <label for="isrInput">Ingreso Gravable</label>
            </div>
            <div id="isrResult"></div>
        </div>
        <div class="modal-footer">
            <a href="#!" class="modal-close waves-effect waves-green btn-flat">Cerrar</a>
            <a href="#!" class="waves-effect waves-green btn" id="calculateIsrBtn">Calcular</a>
        </div>
    </div>

    <div id="employeeSelectModal" class="modal">
        <div class="modal-content">
            <h4>Seleccionar Empleado</h4>
            <div class="input-field">
                <select id="employeeSelect">
                </select>
                <label>Nombre Completo</label>
            </div>
        </div>
        <div class="modal-footer">
            <a href="#!" class="modal-close waves-effect waves-green btn-flat">Cancelar</a>
            <a href="#!" class="waves-effect waves-green btn" id="generateReceiptBtn">Recibo Nómina</a>
        </div>
    </div>

    <div id="payrollReceipt"></div>

    <!-- Scripts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.2/html2canvas.min.js"></script>
    
    <script>
        const employeeData = [
            { nombre: "REYES SUAREZ MIGUEL ANGEL", sd: 248.57 },
            { nombre: "PEREZ GUTIERREZ ESLI JHOARY", sd: 270.00 },
            { nombre: "FLORES BARAJAS ELIZABETH", sd: 300.00 },
            { nombre: "GUERRA ESTRADA MARTHA ELENA", sd: 350.00 },
            { nombre: "MARTINEZ LARA DANIEL IVAN", sd: 400.00 }
        ];

        const weeklyRates = [
            { limInf: 0.01, limSup: 171.78, cuotaFija: 0.00, excedente: 0.0192 },
            { limInf: 171.79, limSup: 1458.03, cuotaFija: 3.29, excedente: 0.0640 },
            { limInf: 1458.04, limSup: 2562.35, cuotaFija: 85.61, excedente: 0.1088 },
            { limInf: 2562.36, limSup: 2978.64, cuotaFija: 205.80, excedente: 0.1600 },
            { limInf: 2978.65, limSup: 3566.22, cuotaFija: 272.37, excedente: 0.1792 },
            { limInf: 3566.23, limSup: 7192.64, cuotaFija: 377.65, excedente: 0.2136 },
            { limInf: 7192.65, limSup: 11336.57, cuotaFija: 1152.27, excedente: 0.2352 },
            { limInf: 11336.58, limSup: 21643.30, cuotaFija: 2126.95, excedente: 0.3000 },
            { limInf: 21643.31, limSup: 28857.78, cuotaFija: 5218.92, excedente: 0.3200 },
            { limInf: 28857.79, limSup: 86573.34, cuotaFija: 7527.59, excedente: 0.3400 },
            { limInf: 86573.35, limSup: Infinity, cuotaFija: 27150.83, excedente: 0.3500 }
        ];

        // Función para validación aritmética
        function validarOperacionAritmetica(operacion, a, b) {
            let resultado;
            let verificacion;
            
            a = Number(parseFloat(a).toFixed(6));
            b = Number(parseFloat(b).toFixed(6));
            
            switch(operacion) {
                case 'suma':
                    resultado = Number((a + b).toFixed(2));
                    verificacion = Number((Math.round((a + b) * 100) / 100).toFixed(2));
                    break;
                case 'resta':
                    resultado = Number((a - b).toFixed(2));
                    verificacion = Number((Math.round((a - b) * 100) / 100).toFixed(2));
                    break;
                case 'multiplicacion':
                    resultado = Number((a * b).toFixed(2));
                    verificacion = Number((Math.round((a * b) * 100) / 100).toFixed(2));
                    break;
                case 'division':
                    if (b === 0) throw new Error('División por cero no permitida');
                    resultado = Number((a / b).toFixed(2));
                    verificacion = Number((Math.round((a / b) * 100) / 100).toFixed(2));
                    break;
            }
            
            if (Math.abs(resultado - verificacion) > 0.01) {
                console.error('Error en operación:', {
                    operacion,
                    a,
                    b,
                    resultado,
                    verificacion
                });
                throw new Error(`Discrepancia en operación ${operacion}`);
            }
            
            return verificacion;
        }

        // Función para encontrar el Salario Diario que da Total Neto = BIOCSA
        function encontrarSalarioDiarioPreciso(biocsa, diasLaborados) {
            let salarioDiario = biocsa / (diasLaborados * 0.8);
            let paso = 0.001;
            let iteraciones = 0;
            const maxIteraciones = 5000;
            let mejorSD = salarioDiario;
            let mejorDiferencia = Infinity;

            while (iteraciones < maxIteraciones) {
                const totalNeto = calcularTotalNeto(salarioDiario, diasLaborados);
                const diferencia = Math.abs(totalNeto - biocsa);

                if (diferencia < mejorDiferencia) {
                    mejorSD = salarioDiario;
                    mejorDiferencia = diferencia;

                    if (diferencia <= 0.01) {
                        return salarioDiario;
                    }
                }

                if (totalNeto > biocsa) {
                    salarioDiario -= paso;
                } else {
                    salarioDiario += paso;
                }

                iteraciones++;
            }

            return mejorSD;
        }

        // Calcula el Total Neto para un Salario Diario dado
        function calcularTotalNeto(salarioDiario, diasLaborados) {
            try {
                const sdi = validarOperacionAritmetica('multiplicacion', salarioDiario, 1.0452);
                const salarioSemanal = validarOperacionAritmetica('multiplicacion', salarioDiario, diasLaborados);
                const premioPunt = diasLaborados === 7 ? 
                    validarOperacionAritmetica('multiplicacion', salarioSemanal, 0.1) : 0;
                const premioAsist = diasLaborados === 7 ? 
                    validarOperacionAritmetica('multiplicacion', salarioSemanal, 0.1) : 0;

                const baseISR = validarOperacionAritmetica('suma',
                    validarOperacionAritmetica('suma', salarioSemanal, premioPunt),
                    premioAsist
                );

                // Deducciones
                const retIMSS = validarOperacionAritmetica('multiplicacion',
                    validarOperacionAritmetica('multiplicacion', sdi, diasLaborados),
                    0.0125
                );

                const retAFORE = validarOperacionAritmetica('multiplicacion',
                    validarOperacionAritmetica('multiplicacion', sdi, diasLaborados),
                    0.01125
                );

                const inf = validarOperacionAritmetica('multiplicacion',
                    validarOperacionAritmetica('multiplicacion', salarioDiario, diasLaborados),
                    0.05
                );

                const isrResult = calculateISR(baseISR);

                const totalDeduc = validarOperacionAritmetica('suma',
                    validarOperacionAritmetica('suma',
                        validarOperacionAritmetica('suma', retIMSS, retAFORE),
                        isrResult.isr
                    ),
                    inf
                );

                const totalPerc = baseISR;
                return validarOperacionAritmetica('resta', totalPerc, totalDeduc);
            } catch (error) {
                console.error('Error en cálculo:', error);
                throw error;
            }
        }

        // Función para calcular ISR
        function calculateISR(baseISR) {
            try {
                let result = {
                    ingresoGravable: baseISR,
                    limiteInferior: 0,
                    excedente: 0,
                    porcentajeExcedente: 0,
                    impuestoMarginal: 0,
                    cuotaFija: 0,
                    impuestoDeterminado: 0,
                    isr: 0
                };

                for (let rate of weeklyRates) {
                    if (baseISR >= rate.limInf && baseISR <= rate.limSup) {
                        result.limiteInferior = rate.limInf;
                        result.excedente = validarOperacionAritmetica('resta', baseISR, rate.limInf);
                        result.porcentajeExcedente = rate.excedente;
                        result.impuestoMarginal = validarOperacionAritmetica('multiplicacion', result.excedente, rate.excedente);
                        result.cuotaFija = rate.cuotaFija;
                        break;
                    }
                }

                result.impuestoDeterminado = validarOperacionAritmetica('suma', result.impuestoMarginal, result.cuotaFija);
                result.subsidioEmpleo = baseISR <= 2091.03 ? 89.80 : 0;
                result.isr = validarOperacionAritmetica('resta', result.impuestoDeterminado, result.subsidioEmpleo);
                result.isr = Math.max(0, result.isr);

                return result;
            } catch (error) {
                console.error('Error en cálculo ISR:', error);
                throw error;
            }
        }

        // Función principal de cálculo por fila
        function calculateRow(index) {
            try {
                const row = document.querySelectorAll(`#employeeTableBody tr`)[index];
                const biocsa = parseFloat(row.querySelector('[name="biocsa"]').value) || 0;
                const sd = parseFloat(row.querySelector('[name="sd"]').value) || 0;
                const tomaAsistencia = parseInt(row.querySelector('[name="tomaAsistencia"]').value) || 0;
                const diasLaborados = validarOperacionAritmetica('division', 
                    validarOperacionAritmetica('multiplicacion', tomaAsistencia, 7), 6);

                // Cálculos base
                const sdi = validarOperacionAritmetica('multiplicacion', sd, 1.0452);
                const salarioSemanal = validarOperacionAritmetica('multiplicacion', sd, diasLaborados);
                const premioPunt = diasLaborados === 7 ? 
                    validarOperacionAritmetica('multiplicacion', salarioSemanal, 0.1) : 0;
                const premioAsist = diasLaborados === 7 ? 
                    validarOperacionAritmetica('multiplicacion', salarioSemanal, 0.1) : 0;
                const valesDespensa = parseFloat(row.querySelector('[name="valesDespensa"]').value) || 0;
                const tiempoExtra = parseFloat(row.querySelector('[name="tiempoExtra"]').value) || 0;
                const grat = parseFloat(row.querySelector('[name="grat"]').value) || 0;
                const ptmo = parseFloat(row.querySelector('[name="ptmo"]').value) || 0;

                // Base ISR y Total Percepciones
                const baseISR = validarOperacionAritmetica('suma',
                    validarOperacionAritmetica('suma', salarioSemanal, premioPunt),
                    premioAsist
                );

                const totalPerc = validarOperacionAritmetica('suma',
                    baseISR,
                    validarOperacionAritmetica('suma',
                        validarOperacionAritmetica('suma', valesDespensa, tiempoExtra),
                        grat
                    )
                );

                // Deducciones
                const retIMSS = validarOperacionAritmetica('multiplicacion',
                    validarOperacionAritmetica('multiplicacion', sdi, diasLaborados),
                    0.0125
                );

                const retAFORE = validarOperacionAritmetica('multiplicacion',
                    validarOperacionAritmetica('multiplicacion', sdi, diasLaborados),
                    0.01125
                );

                const inf = validarOperacionAritmetica('multiplicacion',
                    validarOperacionAritmetica('multiplicacion', sd, diasLaborados),
                    0.05
                );

                const isrResult = calculateISR(baseISR);
                const ispt = isrResult.isr;

                const totalDeduc = validarOperacionAritmetica('suma',
                    validarOperacionAritmetica('suma',
                        validarOperacionAritmetica('suma',
                            validarOperacionAritmetica('suma', retIMSS, retAFORE),
                            ispt
                        ),
                        inf
                    ),
                    ptmo
                );

                const totalNeto = validarOperacionAritmetica('resta', totalPerc, totalDeduc);
                const gastoBIO = validarOperacionAritmetica('suma', biocsa, totalDeduc);

                // Cálculo de Ahorro BIO
                let ahorroBIO = 0;
                if (biocsa > 0 && diasLaborados > 0) {
                    const sdPerfecto = encontrarSalarioDiarioPreciso(biocsa, diasLaborados);
                    const sdiPerfecto = validarOperacionAritmetica('multiplicacion', sdPerfecto, 1.0452);
                    const salarioSemanalPerfecto = validarOperacionAritmetica('multiplicacion', sdPerfecto, diasLaborados);
                    const premioPuntPerfecto = diasLaborados === 7 ? 
                        validarOperacionAritmetica('multiplicacion', salarioSemanalPerfecto, 0.1) : 0;
                    const premioAsistPerfecto = diasLaborados === 7 ? 
                        validarOperacionAritmetica('multiplicacion', salarioSemanalPerfecto, 0.1) : 0;

                    const baseISRPerfecto = validarOperacionAritmetica('suma',
                        validarOperacionAritmetica('suma', salarioSemanalPerfecto, premioPuntPerfecto),
                        premioAsistPerfecto
                    );

                    const retIMSSPerfecto = validarOperacionAritmetica('multiplicacion',
                        validarOperacionAritmetica('multiplicacion', sdiPerfecto, diasLaborados),
                        0.0125
                    );

                    const retAFOREPerfecto = validarOperacionAritmetica('multiplicacion',
                        validarOperacionAritmetica('multiplicacion', sdiPerfecto, diasLaborados),
                        0.01125
                    );

                    const infPerfecto = validarOperacionAritmetica('multiplicacion',
                        validarOperacionAritmetica('multiplicacion', sdPerfecto, diasLaborados),
                        0.05
                    );

                    const isrResultPerfecto = calculateISR(baseISRPerfecto);

                    const totalDeducPerfecto = validarOperacionAritmetica('suma',
                        validarOperacionAritmetica('suma',
                            validarOperacionAritmetica('suma',
                                validarOperacionAritmetica('suma', retIMSSPerfecto, retAFOREPerfecto),
                                isrResultPerfecto.isr
                            ),
                            infPerfecto
                        ),
                        ptmo
                    );

                    const gastoBIOPerfecto = validarOperacionAritmetica('suma', biocsa, totalDeducPerfecto);
                    ahorroBIO = validarOperacionAritmetica('resta', gastoBIOPerfecto, gastoBIO);
                }

                // Actualizar campos en la tabla
                row.querySelector('[data-field="diasLaborados"]').textContent = formatNumber(diasLaborados);
                row.querySelector('[data-field="sdi"]').textContent = formatCurrency(sdi);
                row.querySelector('[data-field="salarioSemanal"]').textContent = formatCurrency(salarioSemanal);
                row.querySelector('[data-field="premioPunt"]').textContent = formatCurrency(premioPunt);
                row.querySelector('[data-field="premioAsist"]').textContent = formatCurrency(premioAsist);
                row.querySelector('[data-field="subEmpl"]').textContent = formatCurrency(0);
                row.querySelector('[data-field="baseISR"]').textContent = formatCurrency(baseISR);
                row.querySelector('[data-field="totalPerc"]').textContent = formatCurrency(totalPerc);
                row.querySelector('[data-field="retIMSS"]').textContent = formatCurrency(retIMSS);
                row.querySelector('[data-field="retAFORE"]').textContent = formatCurrency(retAFORE);
                row.querySelector('[data-field="ispt"]').textContent = formatCurrency(ispt);
                row.querySelector('[name="inf"]').value = formatNumber(inf);
                row.querySelector('[data-field="totalDeduc"]').textContent = formatCurrency(totalDeduc);
                row.querySelector('[data-field="totalNeto"]').textContent = formatCurrency(totalNeto);
                row.querySelector('[data-field="complemento"]').textContent = formatCurrency(biocsa - totalNeto);
                row.querySelector('[data-field="gastoBIO"]').textContent = formatCurrency(gastoBIO);
                row.querySelector('[data-field="ahorroBIO"]').textContent = formatCurrency(ahorroBIO);

                return {
                    biocsa, sd, tomaAsistencia, diasLaborados, sdi, salarioSemanal, 
                    premioPunt, premioAsist, valesDespensa, tiempoExtra, grat, subEmpl: 0, 
                    baseISR, totalPerc, retIMSS, retAFORE, ispt, inf, ptmo, totalDeduc, 
                    totalNeto, complemento: biocsa - totalNeto, gastoBIO, ahorroBIO
                };
            } catch (error) {
                console.error('Error en cálculo de fila:', error);
                throw error;
            }
        }

        function updateTable() {
            const tableBody = document.getElementById('employeeTableBody');
            tableBody.innerHTML = '';
            
            employeeData.forEach((emp, index) => {
                const tr = document.createElement('tr');
                tr.innerHTML = `
                    <td class="sticky-left-cell nombre-column">${emp.nombre}</td>
                    <td class="currency-input">
                        <input type="number" 
                               name="biocsa" 
                               value="0.00" 
                               step="0.01" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td class="currency-input">
                        <input type="number" 
                               name="sd" 
                               value="${emp.sd.toFixed(2)}" 
                               step="0.01" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td>
                        <input type="number" 
                               name="tomaAsistencia" 
                               value="0" 
                               min="0" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td class="number-cell" data-field="diasLaborados"></td>
                    <td class="number-cell" data-field="sdi"></td>
                    <td></td>
                    <td data-field="salarioSemanal" class="expandable-columns percep-group number-cell"></td>
                    <td data-field="premioPunt" class="expandable-columns percep-group number-cell"></td>
                    <td data-field="premioAsist" class="expandable-columns percep-group number-cell"></td>
                    <td class="expandable-columns percep-group currency-input">
                        <input type="number" 
                               name="valesDespensa" 
                               value="0.00" 
                               step="0.01" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td class="expandable-columns percep-group currency-input">
                        <input type="number" 
                               name="tiempoExtra" 
                               value="0.00" 
                               step="0.01" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td class="expandable-columns percep-group currency-input">
                        <input type="number" 
                               name="grat" 
                               value="0.00" 
                               step="0.01" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td data-field="subEmpl" class="expandable-columns percep-group number-cell"></td>
                    <td data-field="baseISR" class="expandable-columns percep-group number-cell"></td>
                    <td data-field="totalPerc" class="col-fixed number-cell"></td>
                    <td></td>
                    <td data-field="retIMSS" class="deduction-columns deduc-group number-cell"></td>
                    <td data-field="retAFORE" class="deduction-columns deduc-group number-cell"></td>
                    <td data-field="ispt" class="deduction-columns deduc-group number-cell"></td>
                    <td class="deduction-columns deduc-group currency-input">
                        <input type="number" 
                               name="inf" 
                               value="0.00" 
                               step="0.01" 
                               readonly>
                    </td>
                    <td class="deduction-columns deduc-group currency-input">
                        <input type="number" 
                               name="ptmo" 
                               value="0.00" 
                               step="0.01" 
                               oninput="calculateRow(${index}); updateTotals();">
                    </td>
                    <td data-field="totalDeduc" class="col-total sticky-right-cell number-cell"></td>
                    <td data-field="totalNeto" class="col-total sticky-right-cell total-neto number-cell"></td>
                    <td data-field="complemento" class="sticky-right-cell number-cell"></td>
                    <td data-field="gastoBIO" class="sticky-right-cell gasto-bio number-cell"></td>
                    <td data-field="ahorroBIO" class="sticky-right-cell number-cell"></td>
                `;
                tableBody.appendChild(tr);
                calculateRow(index);
            });

            updateTotals();
            adjustColumnWidths();
        }

        function updateTotals() {
            let totals = {
                biocsa: 0, sd: 0, tomaAsistencia: 0, diasLaborados: 0, sdi: 0, salarioSemanal: 0, 
                premioPunt: 0, premioAsist: 0, valesDespensa: 0, tiempoExtra: 0, grat: 0, 
                subEmpl: 0, baseISR: 0, totalPerc: 0, retIMSS: 0, retAFORE: 0, ispt: 0, 
                inf: 0, ptmo: 0, totalDeduc: 0, totalNeto: 0, complemento: 0, gastoBIO: 0, ahorroBIO: 0
            };

            document.querySelectorAll('#employeeTableBody tr').forEach((row, index) => {
                const rowData = calculateRow(index);
                for (let key in rowData) {
                    totals[key] = validarOperacionAritmetica('suma', totals[key], rowData[key]);
                }
            });

            for (let key in totals) {
                const element = document.getElementById(`total${key.charAt(0).toUpperCase() + key.slice(1)}`);
                if (element) {
                    if (key === 'diasLaborados') {
                        element.textContent = formatNumber(totals[key]);
                    } else {
                        element.textContent = formatCurrency(totals[key]);
                    }
                }
            }
        }

        function formatCurrency(value) {
            const formattedValue = new Intl.NumberFormat('es-MX', {
                style: 'currency',
                currency: 'MXN',
                minimumFractionDigits: 2,
                maximumFractionDigits: 2
            }).format(value);
            return formattedValue.replace(/MX/g, '');
        }

        function formatNumber(value, decimals = 2) {
            return new Intl.NumberFormat('es-MX', {
                minimumFractionDigits: decimals,
                maximumFractionDigits: decimals
            }).format(value);
        }

        document.addEventListener('DOMContentLoaded', function() {
            var modals = document.querySelectorAll('.modal');
            M.Modal.init(modals);

            document.getElementById('isrCalculationBtn').addEventListener('click', function() {
                var modal = M.Modal.getInstance(document.getElementById('isrCalculationModal'));
                modal.open();
            });

            document.getElementById('calculateIsrBtn').addEventListener('click', performIsrCalculation);

            document.getElementById('isrInput').addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    performIsrCalculation();
                }
            });

            document.getElementById('exportExcelBtn').addEventListener('click', exportToExcel);

            const printPayrollBtn = document.getElementById('printPayrollBtn');
            const employeeSelectModal = document.getElementById('employeeSelectModal');
            const employeeSelect = document.getElementById('employeeSelect');
            const generateReceiptBtn = document.getElementById('generateReceiptBtn');

            M.Modal.init(employeeSelectModal);

            employeeData.forEach((emp, index) => {
                const option = document.createElement('option');
                option.value = index;
                option.textContent = emp.nombre;
                employeeSelect.appendChild(option);
            });

            M.FormSelect.init(employeeSelect);

            printPayrollBtn.addEventListener('click', function() {
                const modal = M.Modal.getInstance(employeeSelectModal);
                modal.open();
            });

            generateReceiptBtn.addEventListener('click', function() {
                const selectedIndex = employeeSelect.value;
                const selectedEmployee = employeeData[selectedIndex];
                generatePayrollReceipt(selectedEmployee);
                M.Modal.getInstance(employeeSelectModal).close();
            });

            const currentDate = new Date().toLocaleDateString('es-MX', { 
                year: 'numeric', 
                month: 'long', 
                day: 'numeric' 
            });
            document.getElementById('currentDate').textContent = currentDate;

            updateTable();
            window.addEventListener('resize', adjustColumnWidths);
            makeResizableTable();
            makeTableSortable();

            setTimeout(adjustColumnWidths, 100);
        });

        function makeResizableTable() {
            const table = document.querySelector('table');
            const cols = table.querySelectorAll('th');
            
            cols.forEach((col) => {
                const resizer = col.querySelector('.resizer');
                if (resizer) {
                    let x = 0;
                    let w = 0;

                    const mouseDownHandler = function(e) {
                        x = e.clientX;
                        w = col.offsetWidth;
                        
                        document.addEventListener('mousemove', mouseMoveHandler);
                        document.addEventListener('mouseup', mouseUpHandler);
                        
                        resizer.classList.add('resizing');
                    };

                    const mouseMoveHandler = function(e) {
                        const dx = e.clientX - x;
                        col.style.width = `${w + dx}px`;
                    };

                    const mouseUpHandler = function() {
                        document.removeEventListener('mousemove', mouseMoveHandler);
                        document.removeEventListener('mouseup', mouseUpHandler);
                        
                        resizer.classList.remove('resizing');
                    };

                    resizer.addEventListener('mousedown', mouseDownHandler);
                }
            });
        }

        function makeTableSortable() {
            const headers = document.querySelectorAll('th');
            headers.forEach(header => {
                if (!header.classList.contains('expand-column')) {
                    header.addEventListener('click', () => {
                        const table = header.closest('table');
                        const tbody = table.querySelector('tbody');
                        const rows = Array.from(tbody.querySelectorAll('tr'));
                        const index = Array.from(header.parentElement.children).indexOf(header);
                        
                        let isAscending = header.classList.contains('asc');
                        
                        headers.forEach(h => h.classList.remove('asc', 'desc'));
                        header.classList.toggle('asc', !isAscending);
                        header.classList.toggle('desc', isAscending);
                        
                        rows.sort((a, b) => {
                            let aValue = a.children[index].textContent.trim();
                            let bValue = b.children[index].textContent.trim();
                            
                            if (!isNaN(parseFloat(aValue))) {
                                aValue = parseFloat(aValue.replace(/[^\d.-]/g, ''));
                                bValue = parseFloat(bValue.replace(/[^\d.-]/g, ''));
                            }
                            
                            if (typeof aValue === 'number') {
                                return isAscending ? 
                                    bValue - aValue : 
                                    aValue - bValue;
                            }
                            
                            return isAscending ? 
                                bValue.localeCompare(aValue) : 
                                aValue.localeCompare(bValue);
                        });
                        
                        tbody.append(...rows);
                        updateTotals();
                    });
                }
            });
        }

        function toggleExpandableColumns(button, type) {
            button.classList.toggle('expanded');
            const columns = document.querySelectorAll(`.${type}-group`);
            const isExpanded = button.classList.contains('expanded');
            
            columns.forEach(column => {
                column.style.display = isExpanded ? 'table-cell' : 'none';
                column.classList.toggle(`${type}-expanded`);
            });
            
            adjustColumnWidths();
        }

        function adjustColumnWidths() {
            const table = document.querySelector('table');
            const headerCells = table.querySelectorAll('th');
            
            headerCells.forEach((cell, index) => {
                if (cell.classList.contains('col-fixed') || cell.classList.contains('col-total')) {
                    const width = cell.offsetWidth;
                    const columnCells = table.querySelectorAll(`td:nth-child(${index + 1})`);
                    columnCells.forEach(td => {
                        td.style.width = `${width}px`;
                    });
                }
            });
        }

        function exportToExcel() {
            const table = document.querySelector('table');
            const ws = XLSX.utils.table_to_sheet(table);
            const wb = XLSX.utils.book_new();
            XLSX.utils.book_append_sheet(wb, ws, "Nómina");
            XLSX.writeFile(wb, "Calculo_Nomina.xlsx");
        }
    </script>
</body>
</html>