<?php
/**
 * PayrollTaxRecalcHistory.php
 * View saved payroll tax recalculation history
 * Nested drill-down: Runs → Employees → Period Traces (Reg 6)
 *
 * API endpoints (same file):
 *   ?api=employees&run_id=X         → JSON employee list for run
 *   ?api=traces&run_id=X&empid=Y    → JSON period traces for employee
 *   ?api=delete&run_id=X            → Delete a run
 */
error_reporting(E_ALL & ~E_NOTICE);
$PageSecurity = 0;

$api = isset($_GET['api']) ? $_GET['api'] : '';

/* ============================================================
   API ENDPOINTS — Return JSON (buffer session output)
   ============================================================ */
if ($api) {
    ob_start();
    include('includes/session.inc');
    ob_end_clean();

    global $db;
    header('Content-Type: application/json');

    if ($api == 'employees') {
        $runId = intval(isset($_GET['run_id']) ? $_GET['run_id'] : 0);
        $search = isset($_GET['search']) ? trim($_GET['search']) : '';

        $where = "run_id = $runId";
        if ($search) {
            $s = mysqli_real_escape_string($db, $search);
            $where .= " AND (employeeid LIKE '%$s%' OR employee_name LIKE '%$s%' OR department LIKE '%$s%')";
        }

        $r = mysqli_query($db, "SELECT employeeid, employee_name, employee_type, f_value, department, rate,
            annual_est, periods, total_gross, old_ytd_tax, new_ytd_tax, difference
        FROM payroll_recalc_employees WHERE $where ORDER BY ABS(difference) DESC");

        $rows = array();
        if ($r) { while ($row = mysqli_fetch_assoc($r)) $rows[] = $row; }
        echo json_encode(array('success'=>true, 'data'=>$rows, 'count'=>count($rows)));
        exit;
    }

    if ($api == 'traces') {
        $runId = intval(isset($_GET['run_id']) ? $_GET['run_id'] : 0);
        $empId = isset($_GET['empid']) ? mysqli_real_escape_string($db, trim($_GET['empid'])) : '';

        $r = mysqli_query($db, "SELECT cal_id, tax_year, f_value, g_value, normal_pay, ph_pay, d_value, e_value, bonus,
            h_value, b1_value, c1_value, c2_value, a1_value, a2_value,
            old_tax, new_tax, diff, gross, old_net, new_net
        FROM payroll_recalc_traces
        WHERE run_id = $runId AND employeeid = '$empId'
        ORDER BY cal_id ASC");

        $rows = array();
        if ($r) { while ($row = mysqli_fetch_assoc($r)) $rows[] = $row; }
        echo json_encode(array('success'=>true, 'data'=>$rows, 'count'=>count($rows)));
        exit;
    }

    if ($api == 'delete') {
        $runId = intval(isset($_GET['run_id']) ? $_GET['run_id'] : 0);
        if ($runId > 0) {
            mysqli_query($db, "DELETE FROM payroll_recalc_traces WHERE run_id = $runId");
            mysqli_query($db, "DELETE FROM payroll_recalc_employees WHERE run_id = $runId");
            mysqli_query($db, "DELETE FROM payroll_recalc_runs WHERE run_id = $runId");
            echo json_encode(array('success'=>true));
        } else {
            echo json_encode(array('success'=>false));
        }
        exit;
    }

    echo json_encode(array('success'=>false, 'error'=>'Unknown API'));
    exit;
}

/* ============================================================
   NORMAL PAGE — Include header & menu
   ============================================================ */
include('includes/session.inc');
$Title = _('Payroll Tax Recalculation History');
include('includes/newheader.php');

global $db;
$userid = $_SESSION['UserID'];

/* ============================================================
   LOAD ALL RUNS
   ============================================================ */
$runs = array();
$r = mysqli_query($db, "SELECT r.*,
    (SELECT COUNT(*) FROM payroll_recalc_employees e WHERE e.run_id = r.run_id) AS emp_count,
    (SELECT COUNT(*) FROM payroll_recalc_traces t WHERE t.run_id = r.run_id) AS trace_count
FROM payroll_recalc_runs r ORDER BY r.run_id DESC");
if ($r) { while ($row = mysqli_fetch_assoc($r)) $runs[] = $row; }
?>

<!-- ===== CUSTOM STYLES (scoped to this page) ===== -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
.recalc-wrap{font-family:'Poppins',sans-serif;padding:20px;color:#1F2937;font-size:13px}
.recalc-wrap h2{color:#187278;margin:28px 0 12px;font-size:16px;border-bottom:2px solid #2AABB3;padding-bottom:6px}
.rc-card{background:#fff;border-radius:10px;padding:20px;margin-bottom:16px;box-shadow:0 1px 3px rgba(0,0,0,.08)}
.rc-banner{background:linear-gradient(135deg,#2AABB3,#187278);color:#fff;padding:24px;border-radius:12px;margin-bottom:20px}
.rc-banner h1{color:#fff;font-size:20px;margin:0 0 4px} .rc-banner p{color:rgba(255,255,255,.85);margin-top:4px;font-size:13px}
.rc-banner a{color:#fff;text-decoration:underline}
.recalc-wrap table{width:100%;border-collapse:collapse;font-size:12px;margin:8px 0}
.recalc-wrap th{background:#F8FAFB;padding:8px 10px;text-align:left;font-weight:600;font-size:11px;text-transform:uppercase;border-bottom:2px solid #E5E7EB;white-space:nowrap}
.recalc-wrap td{padding:7px 10px;border-bottom:1px solid #F0F0F0}
.recalc-wrap tr:hover > td{background:#F8FAFB}
.rc-right{text-align:right}
.rc-danger{color:#FF4D4F;font-weight:600}
.rc-success{color:#52C41A;font-weight:600}
.rc-warn{color:#D48806;font-weight:600}
.rc-muted{color:#9CA3AF}
.rc-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;font-weight:500;cursor:pointer}
.rc-badge.blue{background:#E6F7F8;color:#1E8F96}
.rc-badge.green{background:#F6FFED;color:#52C41A}
.rc-badge.yellow{background:#FFFBE6;color:#D48806}
.rc-badge.red{background:#FFF1F0;color:#FF4D4F}
.rc-btn{display:inline-block;padding:6px 14px;border:none;border-radius:6px;font-size:12px;font-weight:500;cursor:pointer;text-decoration:none;font-family:'Poppins',sans-serif;transition:all .2s}
.rc-btn-primary{background:#2AABB3;color:#fff} .rc-btn-primary:hover{background:#1E8F96}
.rc-btn-outline{background:#fff;color:#374151;border:1px solid #D1D5DB} .rc-btn-outline:hover{border-color:#2AABB3}
.rc-nested td{padding:0;border:none}
.rc-nested-content{background:#FAFBFC;padding:16px 20px;border:1px solid #E5E7EB;border-radius:8px;margin:4px 10px 10px}
.rc-nested-content table{margin:0}
.rc-nested-content th{background:#F0F4F5;font-size:10px}
.rc-nested-content td{padding:5px 8px;font-size:11px}
.rc-trace{background:#F8F9FA;padding:12px 16px;border:1px solid #E5E7EB;border-radius:6px;margin:8px 0}
.rc-trace th{background:#EEF0F2;font-size:10px}
.rc-trace td{padding:4px 6px;font-size:10px;font-family:monospace}
.rc-search{padding:7px 12px;border:1px solid #D1D5DB;border-radius:6px;font-family:'Poppins',sans-serif;font-size:12px;outline:none;width:250px}
.rc-search:focus{border-color:#2AABB3;box-shadow:0 0 0 3px rgba(42,171,179,.15)}
.rc-loading{text-align:center;padding:20px;color:#9CA3AF}
.rc-empty{text-align:center;padding:30px;color:#9CA3AF}
.rc-formula{margin-top:10px;padding:10px;background:#F8FAFB;border-radius:6px;font-size:11px;color:#6B7280}
.rc-kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}
@media(max-width:768px){.rc-kpi-grid{grid-template-columns:repeat(2,1fr)}}
.rc-kpi{background:#fff;border-radius:8px;padding:16px;text-align:center;box-shadow:0 1px 3px rgba(0,0,0,.06)}
.rc-kpi .val{font-size:22px;font-weight:700;color:#1F2937}
.rc-kpi .lbl{font-size:11px;color:#6B7280;margin-top:4px}
</style>

<div class="recalc-wrap">

<div class="rc-banner">
    <h1>📂 Payroll Tax Recalculation — History</h1>
    <p><?php echo count($runs); ?> saved run<?php echo count($runs)!=1?'s':''; ?> |
   </p>
</div>

<?php if (empty($runs)): ?>
<div class="rc-card rc-empty">
    <p style="font-size:16px;margin-bottom:8px">No saved recalculation runs yet.</p>
    <p>Run a <a href="PayrollTaxRecalculate.php" style="color:#2AABB3">dry run</a> and click "Save to History" to store results here.</p>
</div>
<?php else: ?>

<!-- SUMMARY KPIs -->
<?php
$totalRuns = count($runs);
$executedRuns = 0; $dryRuns = 0; $allDiff = 0;
foreach ($runs as $rn) {
    if ($rn['executed']) $executedRuns++; else $dryRuns++;
    $allDiff += floatval($rn['total_diff']);
}
?>
<div class="rc-kpi-grid">
    <div class="rc-kpi"><div class="val"><?php echo $totalRuns; ?></div><div class="lbl">Total Runs</div></div>
    <div class="rc-kpi"><div class="val rc-success"><?php echo $executedRuns; ?></div><div class="lbl">Executed</div></div>
    <div class="rc-kpi"><div class="val rc-warn"><?php echo $dryRuns; ?></div><div class="lbl">Dry Runs</div></div>
    <div class="rc-kpi"><div class="val <?php echo $allDiff > 0 ? 'rc-danger' : ($allDiff < 0 ? 'rc-success' : ''); ?>">$<?php echo number_format($allDiff,2); ?></div><div class="lbl">Total Cumulative Diff</div></div>
</div>

<!-- RUNS TABLE -->
<div class="rc-card">
<table>
    <thead><tr>
        <th></th>
        <th>Run #</th>
        <th>Date</th>
        <th>Periods</th>
        <th>YTD Reset</th>
        <th class="rc-right">Records</th>
        <th class="rc-right">Employees</th>
        <th class="rc-right">Traces</th>
        <th class="rc-right">Old Tax</th>
        <th class="rc-right">New Tax</th>
        <th class="rc-right">Difference</th>
        <th>Status</th>
        <th>Actions</th>
    </tr></thead>
    <tbody>
    <?php foreach ($runs as $run):
        $yb = isset($run['year_boundary']) ? intval($run['year_boundary']) : 0;
    ?>
    <tr id="run-row-<?php echo $run['run_id']; ?>" style="cursor:pointer" onclick="toggleRun(<?php echo $run['run_id']; ?>)">
        <td><span id="run-arrow-<?php echo $run['run_id']; ?>" style="font-size:10px;color:#9CA3AF">▶</span></td>
        <td><strong>#<?php echo $run['run_id']; ?></strong></td>
        <td><?php echo date('d M Y H:i', strtotime($run['run_date'])); ?></td>
        <td><?php echo $run['start_cid']; ?> → <?php echo $run['end_cid']; ?></td>
        <td><?php echo $yb > 0 ? '<span class="rc-badge blue">CalID '.$yb.'</span>' : '<span class="rc-muted">None</span>'; ?></td>
        <td class="rc-right"><?php echo number_format($run['total_records']); ?></td>
        <td class="rc-right"><?php echo number_format($run['emp_count']); ?></td>
        <td class="rc-right"><?php echo number_format($run['trace_count']); ?></td>
        <td class="rc-right">$<?php echo number_format($run['total_old_tax'],2); ?></td>
        <td class="rc-right">$<?php echo number_format($run['total_new_tax'],2); ?></td>
        <td class="rc-right <?php echo $run['total_diff'] > 0 ? 'rc-danger' : ($run['total_diff'] < 0 ? 'rc-success' : 'rc-muted'); ?>">
            $<?php echo number_format($run['total_diff'],2); ?>
        </td>
        <td>
            <?php if ($run['executed']): ?>
                <span class="rc-badge green">Executed</span>
            <?php else: ?>
                <span class="rc-badge yellow">Dry Run</span>
            <?php endif; ?>
        </td>
        <td onclick="event.stopPropagation()">
            <span class="rc-badge blue" onclick="exportRunCSV(<?php echo $run['run_id']; ?>)">📥 Export</span>
            <span class="rc-badge red" onclick="deleteRun(<?php echo $run['run_id']; ?>)" style="margin-left:4px">🗑</span>
        </td>
    </tr>
    <!-- NESTED EMPLOYEE TABLE — loaded via AJAX -->
    <tr id="run-detail-<?php echo $run['run_id']; ?>" class="rc-nested" style="display:none">
        <td colspan="13">
            <div class="rc-nested-content" id="run-content-<?php echo $run['run_id']; ?>">
                <div class="rc-loading">Loading employees...</div>
            </div>
        </td>
    </tr>
    <?php endforeach; ?>
    </tbody>
</table>
</div>
<?php endif; ?>

<div style="text-align:center;margin-top:20px;color:#9CA3AF;font-size:11px">
    <a href="PayrollTaxRecalculate.php" style="color:#2AABB3">← Back to Recalculate</a>
</div>

</div><!-- end .recalc-wrap -->

<script>
var openRuns = {};
var runData = {};

function toggleRun(runId) {
    var detailRow = document.getElementById('run-detail-' + runId);
    var arrow = document.getElementById('run-arrow-' + runId);

    if (openRuns[runId]) {
        detailRow.style.display = 'none';
        arrow.textContent = '▶';
        openRuns[runId] = false;
        return;
    }

    detailRow.style.display = '';
    arrow.textContent = '▼';
    openRuns[runId] = true;

    if (!runData[runId]) {
        loadEmployees(runId, '');
    }
}

function loadEmployees(runId, search) {
    var container = document.getElementById('run-content-' + runId);
    container.innerHTML = '<div class="rc-loading">Loading employees...</div>';

    var url = 'PayrollTaxRecalcHistory.php?api=employees&run_id=' + runId;
    if (search) url += '&search=' + encodeURIComponent(search);

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            try {
                var resp = JSON.parse(xhr.responseText);
                if (resp.success) {
                    runData[runId] = resp.data;
                    renderEmployees(runId, resp.data);
                } else {
                    container.innerHTML = '<div class="rc-empty">Failed to load employees</div>';
                }
            } catch(e) {
                container.innerHTML = '<div class="rc-empty">Error parsing response</div>';
            }
        }
    };
    xhr.send();
}

function renderEmployees(runId, data) {
    var container = document.getElementById('run-content-' + runId);
    var html = '<div style="display:flex;gap:10px;align-items:center;margin-bottom:10px">';
    html += '<input type="text" class="rc-search" placeholder="Search employee..." oninput="loadEmployees(' + runId + ', this.value)">';
    html += '<span style="font-size:11px;color:#6B7280">' + data.length + ' employee' + (data.length!=1?'s':'') + '</span>';
    html += '<span class="rc-badge blue" onclick="exportRunCSV(' + runId + ')" style="margin-left:auto">📥 Export All</span>';
    html += '</div>';

    html += '<div style="max-height:400px;overflow-y:auto">';
    html += '<table><thead><tr>';
    html += '<th></th><th>ID</th><th>Name</th><th>Type</th><th>F</th><th>Dept</th>';
    html += '<th class="rc-right">Rate</th><th class="rc-right">Annual</th><th class="rc-right">Periods</th>';
    html += '<th class="rc-right">Gross</th><th class="rc-right">Old Tax</th><th class="rc-right">New Tax</th>';
    html += '<th class="rc-right">Diff</th>';
    html += '</tr></thead><tbody>';

    for (var i = 0; i < data.length; i++) {
        var e = data[i];
        var diff = parseFloat(e.difference);
        var dc = diff > 0.01 ? 'rc-danger' : (diff < -0.01 ? 'rc-success' : 'rc-muted');
        var bc = e.employee_type === 'Management' ? 'yellow' : 'blue';
        var isMg = e.employee_type === 'Management';
        var rateLabel = isMg ? '$' + num(e.rate,2) + '/mo' : '$' + num(e.rate,2) + '/hr';

        html += '<tr id="emp-row-' + runId + '-' + i + '" style="cursor:pointer" onclick="toggleTrace(' + runId + ',' + i + ',\'' + esc(e.employeeid) + '\')">';
        html += '<td><span id="emp-arrow-' + runId + '-' + i + '" style="font-size:10px;color:#9CA3AF">▶</span></td>';
        html += '<td>' + esc(e.employeeid) + '</td>';
        html += '<td><strong>' + esc(e.employee_name) + '</strong></td>';
        html += '<td><span class="rc-badge ' + bc + '">' + e.employee_type + '</span></td>';
        html += '<td>' + e.f_value + '</td>';
        html += '<td>' + esc(e.department) + '</td>';
        html += '<td class="rc-right">' + rateLabel + '</td>';
        html += '<td class="rc-right">$' + num(e.annual_est,0) + '</td>';
        html += '<td class="rc-right">' + e.periods + '</td>';
        html += '<td class="rc-right">$' + num(e.total_gross,2) + '</td>';
        html += '<td class="rc-right">$' + num(e.old_ytd_tax,2) + '</td>';
        html += '<td class="rc-right">$' + num(e.new_ytd_tax,2) + '</td>';
        html += '<td class="rc-right ' + dc + '">$' + num(diff,2) + '</td>';
        html += '</tr>';

        // Trace row placeholder
        html += '<tr id="trace-row-' + runId + '-' + i + '" style="display:none"><td colspan="13">';
        html += '<div class="rc-trace" id="trace-content-' + runId + '-' + i + '"><div class="rc-loading">Loading traces...</div></div>';
        html += '</td></tr>';
    }

    html += '</tbody></table></div>';
    container.innerHTML = html;
}

var openTraces = {};
var traceData = {};

function toggleTrace(runId, idx, empId) {
    var key = runId + '-' + idx;
    var traceRow = document.getElementById('trace-row-' + key);
    var arrow = document.getElementById('emp-arrow-' + key);

    if (openTraces[key]) {
        traceRow.style.display = 'none';
        arrow.textContent = '▶';
        openTraces[key] = false;
        return;
    }

    traceRow.style.display = '';
    arrow.textContent = '▼';
    openTraces[key] = true;

    if (!traceData[key]) {
        loadTraces(runId, idx, empId);
    }
}

function loadTraces(runId, idx, empId) {
    var key = runId + '-' + idx;
    var container = document.getElementById('trace-content-' + key);
    container.innerHTML = '<div class="rc-loading">Loading period traces...</div>';

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'PayrollTaxRecalcHistory.php?api=traces&run_id=' + runId + '&empid=' + encodeURIComponent(empId), true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            try {
                var resp = JSON.parse(xhr.responseText);
                if (resp.success) {
                    traceData[key] = resp.data;
                    renderTraces(key, resp.data);
                }
            } catch(e) {
                container.innerHTML = '<div class="rc-empty">Error parsing response</div>';
            }
        }
    };
    xhr.send();
}

function renderTraces(key, data) {
    var container = document.getElementById('trace-content-' + key);
    if (!data.length) {
        container.innerHTML = '<div class="rc-empty">No trace data available</div>';
        return;
    }

    var html = '<div style="max-height:300px;overflow-y:auto">';
    html += '<table><thead><tr>';
    html += '<th>CalID</th><th>Year</th><th>F</th><th>G</th>';
    html += '<th class="rc-right">Normal$</th><th class="rc-right">PH$</th><th class="rc-right">D</th>';
    html += '<th class="rc-right">E (YTD)</th><th class="rc-right">Bonus$</th><th class="rc-right">H (YTD)</th>';
    html += '<th class="rc-right">B1 (Tax)</th><th class="rc-right">C1</th><th class="rc-right">C2</th>';
    html += '<th class="rc-right">A1</th><th class="rc-right">A2</th><th class="rc-right">Gross</th>';
    html += '<th class="rc-right">Old Tax</th><th class="rc-right">New Tax</th><th class="rc-right">Diff</th>';
    html += '<th class="rc-right">Old Net</th><th class="rc-right">New Net</th>';
    html += '</tr></thead><tbody>';

    var prevYear = '';
    for (var i = 0; i < data.length; i++) {
        var t = data[i];
        var yr = t.tax_year || '';
        var diff = parseFloat(t.diff);
        var cls = Math.abs(diff) > 0.01 ? ' style="background:#FFFBE6"' : '';
        var dc = diff > 0.01 ? 'rc-danger' : (diff < -0.01 ? 'rc-success' : 'rc-muted');

        // Year boundary separator row
        if (prevYear && yr && yr !== prevYear) {
            html += '<tr style="background:#E6F7F8;border-top:3px solid #2AABB3">';
            html += '<td colspan="21" style="text-align:center;font-weight:700;color:#187278;padding:6px;font-size:11px">';
            html += '↓ YTD RESET — ' + yr + ' starts at CalID ' + t.cal_id + ' (G resets to 1) ↓';
            html += '</td></tr>';
        }
        prevYear = yr;

        var yrBadge = yr === '2026' ? '<span class="rc-badge green">' + yr + '</span>' : '<span class="rc-badge blue">' + yr + '</span>';

        html += '<tr' + cls + '>';
        html += '<td>' + t.cal_id + '</td><td>' + yrBadge + '</td><td>' + t.f_value + '</td><td>' + t.g_value + '</td>';
        html += '<td class="rc-right">$' + num(t.normal_pay,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.ph_pay,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.d_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.e_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.bonus,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.h_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.b1_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.c1_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.c2_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.a1_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.a2_value,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.gross,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.old_tax,2) + '</td>';
        html += '<td class="rc-right ' + dc + '">$' + num(t.new_tax,2) + '</td>';
        html += '<td class="rc-right ' + dc + '">$' + num(diff,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.old_net,2) + '</td>';
        html += '<td class="rc-right">$' + num(t.new_net,2) + '</td>';
        html += '</tr>';
    }

    html += '</tbody></table></div>';
    html += '<div class="rc-formula">';
    html += '<strong>FRCS Reg 6 Formula:</strong> Tax = max(0, (A1/F × G) − B1 + (A2 − A1))<br>';
    html += 'F = 52 (weekly) or 12 (monthly) | D = Normal + PH | E = YTD Normal | H = YTD Bonus | B1 = YTD New Tax<br>';
    html += 'C1 = D×(F−G+1)+E | C2 = C1+H | A1 = Tax(C1) | A2 = Tax(C2)<br>';
    html += '<strong>YTD Reset:</strong> All YTD accumulators (E, H, B1, G) reset to zero at the year boundary';
    html += '</div>';
    container.innerHTML = html;
}

function exportRunCSV(runId) {
    var data = runData[runId];
    if (!data) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'PayrollTaxRecalcHistory.php?api=employees&run_id=' + runId, true);
        xhr.onload = function() {
            if (xhr.status === 200) {
                try {
                    var resp = JSON.parse(xhr.responseText);
                    if (resp.success) {
                        runData[runId] = resp.data;
                        doExport(runId, resp.data);
                    }
                } catch(e) {}
            }
        };
        xhr.send();
        return;
    }
    doExport(runId, data);
}

function doExport(runId, data) {
    var csv = '\uFEFF';
    csv += 'Employee ID,Name,Type,F,Department,Rate,Annual Est,Periods,Total Gross,Old YTD Tax,New YTD Tax,Difference\n';
    for (var i = 0; i < data.length; i++) {
        var e = data[i];
        csv += '"' + e.employeeid + '","' + (e.employee_name||'').replace(/"/g,'""') + '","' + e.employee_type + '",' +
            e.f_value + ',"' + (e.department||'').replace(/"/g,'""') + '",' + parseFloat(e.rate).toFixed(2) + ',' +
            Math.round(parseFloat(e.annual_est)) + ',' + e.periods + ',' + parseFloat(e.total_gross).toFixed(2) + ',' +
            parseFloat(e.old_ytd_tax).toFixed(2) + ',' + parseFloat(e.new_ytd_tax).toFixed(2) + ',' +
            parseFloat(e.difference).toFixed(2) + '\n';
    }
    var blob = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
    var url = URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = url;
    a.download = 'PayrollRecalcHistory_Run' + runId + '.csv';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

function deleteRun(runId) {
    if (!confirm('Delete Run #' + runId + '? This will permanently remove all employee and trace data for this run.')) return;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'PayrollTaxRecalcHistory.php?api=delete&run_id=' + runId, true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            try {
                var resp = JSON.parse(xhr.responseText);
                if (resp.success) {
                    var row = document.getElementById('run-row-' + runId);
                    var detail = document.getElementById('run-detail-' + runId);
                    if (row) row.remove();
                    if (detail) detail.remove();
                }
            } catch(e) {}
        }
    };
    xhr.send();
}

function esc(s) { if (!s) return ''; var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
function num(v, d) { return parseFloat(v).toLocaleString('en-US', {minimumFractionDigits:d, maximumFractionDigits:d}); }
</script>
