<?php
$employeeQuery = "SELECT id, uname, clock_no FROM admin WHERE clock_no IS NOT NULL AND clock_no != '' ORDER BY uname";
$employeeResult = $conn->query($employeeQuery);
?>

<style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        background: #f4f6fb;
    }

    .page-container {
        max-width: 100%;
        margin: 0 auto;
        background: white;
        border-radius: 12px;
        box-shadow: 0 2px 12px rgba(0,0,0,0.08);
        overflow: hidden;
    }

    .page-header {
        color: Black;
        padding: 12px 24px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex-wrap: wrap;
        gap: 5px;
    }

    .page-header h1 { font-size: 20px; font-weight: 600; margin: 0; }
    .page-header p  { font-size: 13px; opacity: 0.75; margin-top: 3px; }

    /* Filters */
    .filters-bar {
        padding: 18px 30px;
        background: #f8f9fa;
        border-bottom: 1px solid #e9ecef;
        display: flex;
        gap: 16px;
        flex-wrap: wrap;
        align-items: flex-end;
    }

    .filter-group { display: flex; flex-direction: column; gap: 5px; }

    .filter-group label {
        font-size: 11px;
        font-weight: 700;
        color: #6b7280;
        text-transform: uppercase;
        letter-spacing: 0.7px;
    }

    .filter-group select,
    .filter-group input {
        padding: 9px 13px;
        border: 1.5px solid #e2e8f0;
        border-radius: 7px;
        font-size: 14px;
        color: #1a202c;
        background: white;
        min-width: 180px;
        transition: border-color 0.2s, box-shadow 0.2s;
        outline: none;
    }

    .filter-group select:focus,
    .filter-group input:focus {
        border-color: #9c4893;
        box-shadow: 0 0 0 3px rgba(156,72,147,0.1);
    }

    /* Period Toggle */
    .period-toggle {
        display: flex;
        background: #e9ecef;
        border-radius: 8px;
        padding: 3px;
        gap: 2px;
    }

    .period-btn {
        padding: 8px 18px;
        border: none;
        background: transparent;
        border-radius: 6px;
        font-size: 13px;
        font-weight: 600;
        color: #6b7280;
        cursor: pointer;
        transition: all 0.2s;
        white-space: nowrap;
    }

    .period-btn.active {
        background: white;
        color: #9c4893;
        box-shadow: 0 1px 4px rgba(0,0,0,0.12);
    }

    .period-btn:hover:not(.active) {
        color: #374151;
        background: rgba(255,255,255,0.5);
    }

    .btn-reset {
        padding: 9px 18px;
        background: #6c757d;
        color: white;
        border: none;
        border-radius: 7px;
        cursor: pointer;
        font-size: 13px;
        font-weight: 600;
        transition: background 0.2s;
        white-space: nowrap;
    }

    .btn-reset:hover { background: #5a6268; }

    /* Stats Bar */
    .stats-bar {
        padding: 12px 30px;
        background: #fff8f0;
        border-bottom: 1px solid #fde8cc;
        display: flex;
        gap: 30px;
        flex-wrap: wrap;
        align-items: center;
    }

    .stat-item { display: flex; align-items: center; gap: 6px; font-size: 13px; color: #92400e; }
    .stat-item strong { font-weight: 700; }

    .stat-value {
        background: #fed7aa;
        color: #92400e;
        padding: 2px 10px;
        border-radius: 20px;
        font-weight: 700;
        font-size: 13px;
    }

    /* Table */
    .table-wrapper {
        overflow-x: auto;
        padding: 20px 30px;
        min-height: 350px;
        position: relative;
    }

    .loading-overlay {
        position: absolute;
        top: 0; left: 0; right: 0; bottom: 0;
        background: rgba(255,255,255,0.92);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        z-index: 100;
        border-radius: 8px;
    }

    .loading-overlay.hidden { display: none; }

    .spinner {
        border: 4px solid #f3f3f3;
        border-top: 4px solid #9c4893;
        border-radius: 50%;
        width: 44px;
        height: 44px;
        animation: spin 0.9s linear infinite;
    }

    @keyframes spin {
        0%   { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }

    .loading-overlay p { margin-top: 12px; color: #9c4893; font-weight: 600; font-size: 14px; }

    table { width: 100%; border-collapse: collapse; font-size: 14px; }

    thead { background: #f8f9fa; position: sticky; top: 0; z-index: 10; }

    th {
        padding: 12px 14px;
        text-align: left;
        font-weight: 700;
        font-size: 12px;
        color: #6b7280;
        text-transform: uppercase;
        letter-spacing: 0.6px;
        border-bottom: 2px solid #e9ecef;
        white-space: nowrap;
    }

    td {
        padding: 13px 14px;
        border-bottom: 1px solid #f1f5f9;
        color: #1e293b;
        vertical-align: middle;
    }

    tbody tr { transition: background 0.15s; }
    tbody tr:hover { background: #faf5ff; }

    .employee-cell { display: flex; align-items: center; gap: 10px; }

    .avatar {
        width: 34px;
        height: 34px;
        border-radius: 50%;
        background: linear-gradient(135deg, #9c4893, #7d3876);
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 13px;
        font-weight: 700;
        flex-shrink: 0;
    }

    .employee-name { font-weight: 600; color: #1e293b; }
    .clock-no { font-size: 12px; color: #94a3b8; font-family: 'Courier New', monospace; }

    .time-cell { font-family: 'Courier New', monospace; font-size: 13px; }
    .time-cell .date-part { font-size: 11px; color: #94a3b8; margin-top: 2px; }

    .hours-badge {
        display: inline-block;
        padding: 4px 12px;
        border-radius: 20px;
        font-size: 13px;
        font-weight: 700;
        background: #ede9fe;
        color: #6d28d9;
    }

    .status-badge {
        display: inline-block;
        padding: 3px 10px;
        border-radius: 20px;
        font-size: 12px;
        font-weight: 600;
    }

    .status-active   { background: #dcfce7; color: #166534; }
    .status-inactive { background: #f1f5f9; color: #475569; }

    .no-data { text-align: center; padding: 60px 20px; color: #94a3b8; }
    .no-data .no-data-icon { font-size: 52px; margin-bottom: 14px; }
    .no-data h3 { font-size: 18px; color: #64748b; margin-bottom: 6px; }
    .no-data p  { font-size: 14px; }

    .hidden { display: none !important; }

    /* Pagination */
    .pagination-wrapper {
        padding: 16px 30px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-top: 1px solid #e9ecef;
        background: #f8f9fa;
        flex-wrap: wrap;
        gap: 12px;
    }

    .per-page-selector {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 13px;
        color: #6b7280;
        font-weight: 600;
    }

    .per-page-selector select {
        padding: 7px 10px;
        border: 1.5px solid #e2e8f0;
        border-radius: 6px;
        font-size: 13px;
        outline: none;
    }

    .pagination { display: flex; gap: 4px; align-items: center; }

    .pagination a,
    .pagination span {
        padding: 7px 12px;
        border: 1.5px solid #e2e8f0;
        background: white;
        color: #374151;
        text-decoration: none;
        border-radius: 6px;
        font-size: 13px;
        font-weight: 600;
        transition: all 0.18s;
        cursor: pointer;
    }

    .pagination a:hover      { background: #9c4893; color: white; border-color: #9c4893; }
    .pagination .active      { background: #9c4893; color: white; border-color: #9c4893; }
    .pagination .disabled    { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

    /* Action Buttons */
    .btn-action {
        padding: 5px 11px;
        border: none;
        border-radius: 6px;
        font-size: 12px;
        font-weight: 600;
        cursor: pointer;
        transition: all 0.18s;
    }

    .btn-edit            { background: #dbeafe; color: #1d4ed8; }
    .btn-edit:hover      { background: #1d4ed8; color: white; }
    .btn-delete          { background: #fee2e2; color: #dc2626; margin-left: 5px; }
    .btn-delete:hover    { background: #dc2626; color: white; }

    /* Modal */
    .modal-backdrop {
        position: fixed; inset: 0;
        background: rgba(0,0,0,0.45);
        z-index: 9999;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .modal-backdrop.hidden { display: none; }

    .modal-box {
        background: white;
        border-radius: 12px;
        padding: 28px 30px;
        width: 420px;
        max-width: 95vw;
        box-shadow: 0 8px 32px rgba(0,0,0,0.18);
    }

    .modal-box h2 { font-size: 17px; font-weight: 700; margin-bottom: 18px; color: #1e293b; }

    .modal-field { margin-bottom: 14px; }

    .modal-field label {
        display: block;
        font-size: 11px;
        font-weight: 700;
        color: #6b7280;
        text-transform: uppercase;
        letter-spacing: 0.6px;
        margin-bottom: 5px;
    }

    .modal-field input {
        width: 100%;
        padding: 9px 12px;
        border: 1.5px solid #e2e8f0;
        border-radius: 7px;
        font-size: 14px;
        outline: none;
        color: #1e293b;
    }

    .modal-field input:focus {
        border-color: #9c4893;
        box-shadow: 0 0 0 3px rgba(156,72,147,0.1);
    }

    .modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; }

    .btn-save {
        padding: 9px 22px;
        background: #9c4893;
        color: white;
        border: none;
        border-radius: 7px;
        font-weight: 600;
        font-size: 14px;
        cursor: pointer;
        transition: background 0.2s;
    }

    .btn-save:hover      { background: #7d3876; }
    .btn-save.btn-danger { background: #dc2626; }
    .btn-save.btn-danger:hover { background: #b91c1c; }

    .btn-cancel {
        padding: 9px 18px;
        background: #f1f5f9;
        color: #374151;
        border: none;
        border-radius: 7px;
        font-weight: 600;
        font-size: 14px;
        cursor: pointer;
        transition: background 0.2s;
    }

    .btn-cancel:hover { background: #e2e8f0; }

    .delete-confirm-text { font-size: 14px; color: #374151; line-height: 1.6; }
    .delete-confirm-text strong { color: #dc2626; }

    .modal-employee-info {
        background: #f8f9fa;
        border-radius: 8px;
        padding: 10px 14px;
        margin-bottom: 16px;
        font-size: 13px;
        color: #374151;
    }

    .modal-employee-info span { font-weight: 700; color: #1e293b; }

    @media (max-width: 768px) {
        .filters-bar, .stats-bar, .table-wrapper, .pagination-wrapper { padding: 14px 16px; }
        .page-header { padding: 14px 16px; }
        .filter-group select, .filter-group input { min-width: 140px; }
    }
	thead tr th {
    background-color: #9c4893;
    color: #fff;
}
</style>

<div class="page-container">

    <!-- Header -->
    <div class="page-header">
        <div>
            <h4>🕐 Shift Records</h4>
            <p>Clock In / Clock Out history for all employees</p>
        </div>
    </div>

    <!-- Filters -->
    <div class="filters-bar">
        <div class="filter-group">
            <label>Period</label>
            <div class="period-toggle">
                <button class="period-btn active" onclick="setPeriod('today', this)">Today</button>
                <button class="period-btn" onclick="setPeriod('weekly', this)">This Week</button>
                <button class="period-btn" onclick="setPeriod('monthly', this)">This Month</button>
            </div>
        </div>

        <div class="filter-group">
            <label>Employee</label>
            <select id="filterEmployee" onchange="loadData()">
                <option value="">All Employees</option>
                <?php
                if ($employeeResult && $employeeResult->num_rows > 0) {
                    while ($emp = $employeeResult->fetch_assoc()) {
                        $name  = htmlspecialchars($emp['uname']);
                        $clock = htmlspecialchars($emp['clock_no']);
                        echo "<option value='{$emp['id']}'>$name ($clock)</option>";
                    }
                }
                ?>
            </select>
        </div>

        <button class="btn-reset" onclick="resetFilters()">🔄 Reset</button>
    </div>

    <!-- Stats -->
    <div class="stats-bar">
        <div class="stat-item">
            <strong>Total Records:</strong>
            <span class="stat-value" id="totalCount">0</span>
        </div>
        <div class="stat-item">
            <strong>Showing:</strong>
            <span class="stat-value" id="showingRange">0 – 0</span>
        </div>
        <div class="stat-item">
            <strong>Page:</strong>
            <span class="stat-value" id="pageInfo">0 of 0</span>
        </div>
    </div>

    <!-- Table -->
    <div class="table-wrapper">
        <div id="loadingOverlay" class="loading-overlay">
            <div class="spinner"></div>
            <p>Loading shift records...</p>
        </div>

        <div id="noDataMessage" class="no-data hidden">
            <div class="no-data-icon">📋</div>
            <h3>No Shift Records Found</h3>
            <p>No records match the selected filters.</p>
        </div>

        <table id="shiftTable">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Employee</th>
                    <th>Clock In</th>
                    <th>Clock Out</th>
                    <th style="text-align:center;">Total Hours</th>
                    <th style="text-align:center;">Status</th>
                    <th style="text-align:center;">Actions</th>
                </tr>
            </thead>
            <tbody id="tableBody"></tbody>
        </table>
    </div>

    <!-- Pagination -->
    <div id="paginationWrapper" class="pagination-wrapper hidden">
        <div class="per-page-selector">
            <label>Records per page:</label>
            <select id="perPageSelect" onchange="changePerPage(this.value)">
                <option value="25">25</option>
                <option value="50" selected>50</option>
                <option value="100">100</option>
            </select>
        </div>
        <div id="paginationControls" class="pagination"></div>
    </div>

</div>

<!-- ── Edit Modal ── -->
<div id="editModal" class="modal-backdrop hidden">
    <div class="modal-box">
        <h2>✏️ Edit Shift Record</h2>
        <input type="hidden" id="editShiftId">
        <div id="editEmployeeInfo" class="modal-employee-info"></div>
        <div class="modal-field">
            <label>Clock In</label>
            <input type="datetime-local" id="editStartTime">
        </div>
        <div class="modal-field">
            <label>Clock Out <span style="font-weight:400;text-transform:none;font-size:11px;color:#94a3b8;">(leave empty if still active)</span></label>
            <input type="datetime-local" id="editEndTime">
        </div>
        <div class="modal-actions">
            <button class="btn-cancel" onclick="closeModal('editModal')">Cancel</button>
            <button class="btn-save"   onclick="saveEdit()">💾 Save Changes</button>
        </div>
    </div>
</div>

<!-- ── Delete Modal ── -->
<div id="deleteModal" class="modal-backdrop hidden">
    <div class="modal-box">
        <h2>🗑️ Delete Shift Record</h2>
        <input type="hidden" id="deleteShiftId">
        <div id="deleteEmployeeInfo" class="modal-employee-info"></div>
        <p class="delete-confirm-text">
            Are you sure you want to permanently delete this shift record?
            <br><strong>This action cannot be undone.</strong>
        </p>
        <div class="modal-actions">
            <button class="btn-cancel" onclick="closeModal('deleteModal')">Cancel</button>
            <button class="btn-save btn-danger" onclick="confirmDelete()">🗑️ Delete</button>
        </div>
    </div>
</div>

<script>
    let currentPage   = 1;
    let perPage       = 50;
    let totalPages    = 0;
    let currentPeriod = 'today';

    // Store row data here so onclick just passes the id
    const rowDataMap = {};

    document.addEventListener('DOMContentLoaded', loadData);

    function setPeriod(period, btn) {
        currentPeriod = period;
        document.querySelectorAll('.period-btn').forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        loadData();
    }

    function loadData(resetPage = true) {
        if (resetPage) currentPage = 1;

        const params = new URLSearchParams({
            current_page : currentPage,
            per_page     : perPage,
            period       : currentPeriod,
            employee_id  : document.getElementById('filterEmployee').value
        });

        document.getElementById('loadingOverlay').classList.remove('hidden');
        document.getElementById('noDataMessage').classList.add('hidden');
        document.getElementById('shiftTable').style.opacity = '0.3';

        const url = site_url + '/modules/clockin_clockout/index.php?page=ajax_shift_list&' + params.toString();

        fetch(url)
            .then(r => r.json())
            .then(data => {
                if (data.success) {
                    renderTable(data.data);
                    updatePagination(data.pagination);
                    updateStats(data.pagination);
                } else {
                    showError(data.error);
                }
            })
            .catch(err => showError(err.message))
            .finally(() => {
                document.getElementById('loadingOverlay').classList.add('hidden');
                document.getElementById('shiftTable').style.opacity = '1';
            });
    }

    function renderTable(records) {
        const tbody  = document.getElementById('tableBody');
        const noData = document.getElementById('noDataMessage');

        if (!records.length) {
            tbody.innerHTML = '';
            noData.classList.remove('hidden');
            return;
        }

        noData.classList.add('hidden');
        const offset = (currentPage - 1) * perPage;

        // Store all row data in the map keyed by id
        records.forEach(row => {
            rowDataMap[row.id] = row;
        });

        tbody.innerHTML = records.map((row, i) => {
            const initials = (row.uname || '?').charAt(0).toUpperCase();
            const startDT  = row.start_time ? new Date(row.start_time) : null;
            const endDT    = row.end_time   ? new Date(row.end_time)   : null;
            const isActive = row.status === 'active';

            const hours = row.total_hours
                ? parseFloat(row.total_hours).toFixed(2) + ' hrs'
                : (isActive ? '—' : '0.00 hrs');

            return `
                <tr>
                    <td style="color:#94a3b8;font-size:13px;">${offset + i + 1}</td>
                    <td>
                        <div class="employee-cell">
                            <div class="avatar">${initials}</div>
                            <div>
                                <div class="employee-name">${esc(row.uname || '—')}</div>
                                <div class="clock-no">#${esc(row.clock_no || '—')}</div>
                            </div>
                        </div>
                    </td>
                    <td class="time-cell">
                        ${startDT ? formatTime(startDT) : '—'}
                        <div class="date-part">${startDT ? formatDate(startDT) : ''}</div>
                    </td>
                    <td class="time-cell">
                        ${endDT
                            ? formatTime(endDT) + '<div class="date-part">' + formatDate(endDT) + '</div>'
                            : '<span style="color:#f59e0b;font-weight:600;">Active</span>'
                        }
                    </td>
                    <td style="text-align:center;">
                        <span class="hours-badge">${hours}</span>
                    </td>
                    <td style="text-align:center;">
                        <span class="status-badge ${isActive ? 'status-active' : 'status-inactive'}">
                            ${isActive ? '🟢 Active' : '✔ Completed'}
                        </span>
                    </td>
                    <td style="text-align:center;white-space:nowrap;">
                        <button class="btn-action btn-edit"   onclick="openEdit(${row.id})">✏️ Edit</button>
                        <button class="btn-action btn-delete" onclick="openDelete(${row.id})">🗑️</button>
                    </td>
                </tr>
            `;
        }).join('');
    }

    function updatePagination(p) {
        totalPages = p.total_pages;
        const wrapper  = document.getElementById('paginationWrapper');
        const controls = document.getElementById('paginationControls');

        if (totalPages <= 1) { wrapper.classList.add('hidden'); return; }
        wrapper.classList.remove('hidden');

        let html = '';
        html += currentPage > 1
            ? `<a onclick="goToPage(1)">« First</a><a onclick="goToPage(${currentPage - 1})">‹</a>`
            : `<span class="disabled">« First</span><span class="disabled">‹</span>`;

        const start = Math.max(1, currentPage - 2);
        const end   = Math.min(totalPages, currentPage + 2);
        if (start > 1) html += '<span>…</span>';
        for (let i = start; i <= end; i++) {
            html += i === currentPage
                ? `<span class="active">${i}</span>`
                : `<a onclick="goToPage(${i})">${i}</a>`;
        }
        if (end < totalPages) html += '<span>…</span>';

        html += currentPage < totalPages
            ? `<a onclick="goToPage(${currentPage + 1})">›</a><a onclick="goToPage(${totalPages})">Last »</a>`
            : `<span class="disabled">›</span><span class="disabled">Last »</span>`;

        controls.innerHTML = html;
    }

    function updateStats(p) {
        document.getElementById('totalCount').textContent   = p.total_records;
        document.getElementById('showingRange').textContent = `${p.showing_from} – ${p.showing_to}`;
        document.getElementById('pageInfo').textContent     = `${p.current_page} of ${p.total_pages}`;
    }

    function goToPage(page)     { currentPage = page; loadData(false); }
    function changePerPage(val) { perPage = parseInt(val); currentPage = 1; loadData(false); }

    function resetFilters() {
        document.getElementById('filterEmployee').value = '';
        currentPeriod = 'today';
        document.querySelectorAll('.period-btn').forEach((b, i) => b.classList.toggle('active', i === 0));
        loadData();
    }

    function showError(msg) {
        document.getElementById('tableBody').innerHTML = `
            <tr><td colspan="7" style="text-align:center;padding:40px;color:#e74c3c;">
                ⚠ Error loading data: ${esc(msg)}
            </td></tr>`;
    }

    /* ── Helpers ── */
    function esc(str) {
        if (!str) return '';
        const d = document.createElement('div');
        d.textContent = str;
        return d.innerHTML;
    }

    function formatTime(dt) {
        let h = dt.getHours(), m = dt.getMinutes();
        const ampm = h >= 12 ? 'PM' : 'AM';
        h = h % 12 || 12;
        return `${h}:${String(m).padStart(2,'0')} ${ampm}`;
    }

    function formatDate(dt) {
        return dt.toLocaleDateString('en-GB', { day:'2-digit', month:'short', year:'numeric' });
    }

    function toLocalInput(dtStr) {
        if (!dtStr) return '';
        const d   = new Date(dtStr);
        const pad = n => String(n).padStart(2, '0');
        return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
    }

    /* ── Edit ── */
    function openEdit(id) {
        const row = rowDataMap[id];
        if (!row) { alert('Record not found.'); return; }

        document.getElementById('editShiftId').value   = row.id;
        document.getElementById('editStartTime').value = toLocalInput(row.start_time);
        document.getElementById('editEndTime').value   = toLocalInput(row.end_time);
        document.getElementById('editEmployeeInfo').innerHTML =
            `<span>${esc(row.uname || '—')}</span> &nbsp;·&nbsp; Clock #${esc(row.clock_no || '—')}`;
        document.getElementById('editModal').classList.remove('hidden');
    }

    function saveEdit() {
        const id        = document.getElementById('editShiftId').value;
        const startTime = document.getElementById('editStartTime').value;
        const endTime   = document.getElementById('editEndTime').value;

        if (!id || id == '0') { alert('Invalid shift ID.'); return; }
        if (!startTime)       { alert('Clock In time is required.'); return; }
        if (endTime && endTime < startTime) {
            alert('Clock Out cannot be earlier than Clock In.');
            return;
        }
//alert(id);
        const saveBtn       = document.querySelector('#editModal .btn-save');
        saveBtn.textContent = 'Saving…';
        saveBtn.disabled    = true;

        const url = site_url + '/modules/clockin_clockout/index.php?page=ajax_shift_edit';
        fetch(url, {
            method  : 'POST',
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
    shift_id: id,
    start_time: startTime,
    end_time: endTime
})
        })
        .then(r => r.json())
        .then(data => {
            if (data.success) {
                closeModal('editModal');
                loadData(false);
            } else {
                alert('Error: ' + data.error);
            }
        })
        .catch(err => alert('Error: ' + err.message))
        .finally(() => {
            saveBtn.textContent = '💾 Save Changes';
            saveBtn.disabled    = false;
        });
    }

    /* ── Delete ── */
    function openDelete(id) {
        const row = rowDataMap[id];
        if (!row) { alert('Record not found.'); return; }

        document.getElementById('deleteShiftId').value = row.id;
        const dtLabel = row.start_time ? ' — ' + formatDate(new Date(row.start_time)) : '';
        document.getElementById('deleteEmployeeInfo').innerHTML =
            `<span>${esc(row.uname || '—')}</span> &nbsp;·&nbsp; Clock #${esc(row.clock_no || '—')}${dtLabel}`;
        document.getElementById('deleteModal').classList.remove('hidden');
    }

    function confirmDelete() {
        const id    = document.getElementById('deleteShiftId').value;

        if (!id || id == '0') { alert('Invalid shift ID.'); return; }

        const delBtn       = document.querySelector('#deleteModal .btn-save');
        delBtn.textContent = 'Deleting…';
        delBtn.disabled    = true;

        const url = site_url + '/modules/clockin_clockout/index.php?page=ajax_shift_delete';
        fetch(url, {
            method  : 'POST',
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
            body    : new URLSearchParams({ id })
        })
        .then(r => r.json())
        .then(data => {
            if (data.success) {
                closeModal('deleteModal');
                loadData(false);
            } else {
                alert('Error: ' + data.error);
            }
        })
        .catch(err => alert('Error: ' + err.message))
        .finally(() => {
            delBtn.textContent = '🗑️ Delete';
            delBtn.disabled    = false;
        });
    }

    function closeModal(id) {
        document.getElementById(id).classList.add('hidden');
    }

    document.getElementById('editModal').addEventListener('click', function(e) {
        if (e.target === this) closeModal('editModal');
    });
    document.getElementById('deleteModal').addEventListener('click', function(e) {
        if (e.target === this) closeModal('deleteModal');
    });

    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') {
            closeModal('editModal');
            closeModal('deleteModal');
        }
    });
</script>