<style>
*, *::before, *::after { box-sizing: border-box; }

h2 { margin-bottom: .4rem; font-size: 1.4rem; color: #1a1a2e; letter-spacing: -.3px; }

.stats { display: flex; gap: 12px; margin-bottom: 1.4rem; flex-wrap: wrap; }
.stat  { background: #fff; border: 1px solid #e0e6ed; border-radius: 10px; padding: 12px 20px; box-shadow: 0 1px 4px rgba(44,62,80,.07); }
.stat-label { font-size: 11px; color: #999; text-transform: uppercase; letter-spacing: .5px; }
.stat-value { font-size: 22px; font-weight: 700; color: #1a1a2e; }

.toolbar-row { display: flex; align-items: flex-end; gap: 12px; margin-bottom: 1rem; flex-wrap: wrap; }
.fg { display: flex; flex-direction: column; gap: 4px; }
.fg label { font-size: 11px; font-weight: 600; color: #666; text-transform: uppercase; letter-spacing: .4px; }
.fg input, .fg select {
    padding: 8px 12px; border: 1px solid #ddd; border-radius: 7px;
    font-size: 13px; background: #fff; transition: border-color .15s;
}
.fg input:focus, .fg select:focus { outline: none; border-color: #117a8b; }
.fg input.filter-active { border-color: #117a8b; background: #e8f6f8; }

.btn { padding: 8px 16px; border: 1px solid #ddd; border-radius: 7px; cursor: pointer; background: #fff; font-size: 13px; height: 36px; align-self: flex-end; transition: all .15s; font-weight: 500; }
.btn:hover { border-color: #117a8b; color: #117a8b; }
.btn.primary { background: #117a8b; color: #fff; border-color: #117a8b; }
.btn.primary:hover { background: #0e6070; }

.table-wrap { border-radius: 10px; overflow: hidden; border: 1px solid #e0e6ed; box-shadow: 0 2px 12px rgba(44,62,80,.07); }
table { width: 100%; border-collapse: collapse; background: #fff; }
thead th {
    background: #117a8b; padding: 11px 14px; text-align: left;
    font-size: 12px; color: #fff; font-weight: 600; letter-spacing: .4px; text-transform: uppercase;
}
thead th.r { text-align: right; }
tbody td { padding: 10px 14px; border-top: 1px solid #f0f3f6; font-size: 13px; color: #333; vertical-align: middle; }
tbody td.r { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr:hover        { background: #e8f6f8; }
tbody tr.stripe       { background: #fafbfc; }
tbody tr.stripe:hover { background: #d0edf2; }
tfoot td { padding: 11px 14px; background: #ecf0f1; font-weight: 700; font-size: 13px; border-top: 2px solid #bdc3c7; }
tfoot td.r { text-align: right; font-variant-numeric: tabular-nums; }

.no-data { padding: 2.5rem; text-align: center; color: #bbb; font-size: 14px; }

.c-qty { color: #117a8b; font-weight: 600; }
.c-dn  { color: #d35400; font-weight: 600; }
.c-so  { color: #7d6608; font-weight: 500; }

.pag-wrap { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; flex-wrap: wrap; gap: 10px; }
.pag { display: flex; gap: 5px; flex-wrap: wrap; }
.pag a, .pag span {
    padding: 6px 11px; border: 1px solid #dee2e6; border-radius: 5px;
    font-size: 13px; cursor: pointer; background: #fff; color: #495057; text-decoration: none; transition: all .15s;
}
.pag a:hover   { background: #117a8b; color: #fff; border-color: #117a8b; }
.pag .active   { background: #117a8b; color: #fff; border-color: #117a8b; font-weight: 600; }
.pag .disabled { opacity: .4; pointer-events: none; }
</style>

<h2>🚛 Customer Delivery Report</h2>

<!-- Stats -->
<div class="stats">
    <div class="stat"><div class="stat-label">Total Records</div><div class="stat-value" id="cd-stat-total">—</div></div>
    <div class="stat"><div class="stat-label">Showing</div><div class="stat-value" id="cd-stat-range" style="font-size:15px;padding-top:5px">—</div></div>
    <div class="stat"><div class="stat-label">Total Qty Delivered</div><div class="stat-value" id="cd-stat-qty" style="font-size:17px;padding-top:4px;color:#117a8b">—</div></div>
</div>

<!-- Toolbar -->
<div class="toolbar-row">
    <div class="fg">
        <label>From Date</label>
        <input type="date" id="cd-f-from" oninput="cdDebounce()">
    </div>
    <div class="fg">
        <label>To Date</label>
        <input type="date" id="cd-f-to" oninput="cdDebounce()">
    </div>
    <div class="fg">
        <label>Part Number</label>
        <input type="text" id="cd-f-part" placeholder="Search part…" oninput="cdDebounce()">
    </div>
    <div class="fg">
        <label>Sales Order No</label>
        <input type="text" id="cd-f-order" placeholder="Sales order…" oninput="cdDebounce()">
    </div>
    <div class="fg">
        <label>Per page</label>
        <select id="cd-per-page" onchange="cdLoad()">
            <option value="25" selected>25</option>
            <option value="50">50</option>
            <option value="100">100</option>
        </select>
    </div>
    <button class="btn" onclick="cdReset()">↺ Reset</button>
    <button class="btn primary" onclick="cdLoad()">Search</button>
</div>

<!-- Table -->
<div class="table-wrap">
<table>
    <thead>
        <tr>
            <th>#</th>
            <th>Delivery Note</th>
            <th>Sales Order No</th>
            <th>Customer Code</th>
            <th>Part Number</th>
            <th>Part Description</th>
            <th class="r">Qty Delivered</th>
            <th>Date Delivered</th>
        </tr>
    </thead>
    <tbody id="cd-tbody">
        <tr><td colspan="8" class="no-data">Loading…</td></tr>
    </tbody>
    <tfoot id="cd-tfoot" style="display:none">
        <tr>
            <td colspan="6" class="r">Page Total</td>
            <td class="r" id="cd-foot-qty">—</td>
            <td></td>
        </tr>
    </tfoot>
</table>
</div>

<!-- Pagination -->
<div class="pag-wrap" id="cd-pag-wrap" style="display:none">
    <div style="font-size:13px;color:#666">Page <strong id="cd-pag-info">1 of 1</strong></div>
    <div class="pag" id="cd-pag-controls"></div>
</div>

<script>
(function () {

var FILTER_KEY  = 'cd_report_filters';
var currentPage = 1;
var debTimer    = null;

function saveFilters() {
    var s = {
        from    : document.getElementById('cd-f-from').value,
        to      : document.getElementById('cd-f-to').value,
        part    : document.getElementById('cd-f-part').value,
        order   : document.getElementById('cd-f-order').value,
        perPage : document.getElementById('cd-per-page').value,
        page    : currentPage
    };
    try { sessionStorage.setItem(FILTER_KEY, JSON.stringify(s)); } catch(e) {}
    highlightFilters();
}

function restoreFilters() {
    try {
        var raw = sessionStorage.getItem(FILTER_KEY);
        if (!raw) return;
        var s = JSON.parse(raw);
        if (s.from    !== undefined) document.getElementById('cd-f-from').value   = s.from;
        if (s.to      !== undefined) document.getElementById('cd-f-to').value     = s.to;
        if (s.part    !== undefined) document.getElementById('cd-f-part').value   = s.part;
        if (s.order   !== undefined) document.getElementById('cd-f-order').value  = s.order;
        if (s.perPage !== undefined) document.getElementById('cd-per-page').value = s.perPage;
        if (s.page    !== undefined) currentPage = parseInt(s.page) || 1;
        highlightFilters();
    } catch(e) {}
}

function highlightFilters() {
    ['cd-f-from','cd-f-to','cd-f-part','cd-f-order'].forEach(function(id) {
        var el = document.getElementById(id);
        if (el) el.classList.toggle('filter-active', el.value !== '');
    });
}

function getParams() {
    return {
        current_page   : currentPage,
        per_page       : document.getElementById('cd-per-page').value,
        from_date      : document.getElementById('cd-f-from').value,
        to_date        : document.getElementById('cd-f-to').value,
        part_number    : document.getElementById('cd-f-part').value.trim(),
        customer_order : document.getElementById('cd-f-order').value.trim()
    };
}

window.cdDebounce = function () {
    saveFilters();
    clearTimeout(debTimer);
    debTimer = setTimeout(function () { currentPage = 1; cdLoad(false); }, 400);
};

window.cdLoad = function (resetPage) {
    if (resetPage !== false) currentPage = 1;
    saveFilters();

    document.getElementById('cd-tbody').innerHTML =
        '<tr><td colspan="8" class="no-data">Loading…</td></tr>';
    document.getElementById('cd-tfoot').style.display = 'none';

    var params = getParams();
    var qs = Object.keys(params).map(function(k) {
        return encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
    }).join('&');

    $.ajax({
        url      : site_url + '/modules/report_management/index.php?page=ajax_actions&action=get_customer_delivery&' + qs,
        type     : 'GET',
        dataType : 'json',
        success  : function (res) {
            if (!res.success) {
                document.getElementById('cd-tbody').innerHTML =
                    '<tr><td colspan="8" class="no-data" style="color:red">' +
                    esc(res.message || 'Error loading data.') + '</td></tr>';
                return;
            }
            renderRows(res.data || [], res.pagination);
            updateStats(res.pagination, res.summary);
            renderPagination(res.pagination);
        },
        error    : function (xhr) {
            var raw = xhr.responseText || '';
            try {
                var res = JSON.parse(raw);
                document.getElementById('cd-tbody').innerHTML =
                    '<tr><td colspan="8" class="no-data" style="color:red">' +
                    esc(res.message || 'Error loading data.') + '</td></tr>';
            } catch(e) {
                document.getElementById('cd-tbody').innerHTML =
                    '<tr><td colspan="8" class="no-data" style="color:red">' +
                    '<strong>Server did not return valid JSON.</strong>' +
                    '<br><pre style="text-align:left;font-size:11px;color:#555;white-space:pre-wrap;margin-top:8px">' +
                    esc(raw.substring(0, 800)) + '</pre></td></tr>';
            }
        }
    });
};

function fmtDate(d) {
    if (!d) return '—';
    var p = d.substring(0, 10).split('-');
    return p[2] + '-' + p[1] + '-' + p[0];
}

function renderRows(rows, pag) {
    var tbody = document.getElementById('cd-tbody');
    if (!rows.length) {
        tbody.innerHTML = '<tr><td colspan="8" class="no-data">No delivery records found.</td></tr>';
        document.getElementById('cd-tfoot').style.display = 'none';
        return;
    }

    var perPage  = parseInt(document.getElementById('cd-per-page').value);
    var offset   = ((pag ? pag.current_page : currentPage) - 1) * perPage;
    var html     = '';
    var pageQty  = 0;

    rows.forEach(function (r, i) {
        var stripe = (i % 2 === 1) ? ' stripe' : '';
        var qty    = parseFloat(r.qty_delivered || 0);
        pageQty   += qty;

        html +=
            '<tr class="' + stripe + '">' +
            '<td style="color:#ccc;font-size:11px">'     + (offset + i + 1)                  + '</td>' +
            '<td class="c-dn">'                          + esc(r.delivery_note_number || '—') + '</td>' +
            '<td class="c-so">'                          + esc(r.sales_order_number   || '—') + '</td>' +
            '<td style="font-weight:600;color:#1a1a2e">' + esc(r.customer_code        || '—') + '</td>' +
            '<td style="font-weight:700;color:#117a8b">' + esc(r.part_number          || '—') + '</td>' +
            '<td style="color:#555">'                    + esc(r.part_description     || '—') + '</td>' +
            '<td class="r c-qty">'                       + fmt(qty)                            + '</td>' +
            '<td style="color:#555">'                    + fmtDate(r.date_delivered)           + '</td>' +
            '</tr>';
    });

    tbody.innerHTML = html;

    document.getElementById('cd-foot-qty').textContent = fmt(pageQty);
    document.getElementById('cd-tfoot').style.display  = '';
}

function updateStats(pag, summary) {
    if (pag) {
        document.getElementById('cd-stat-total').textContent = pag.total_records;
        document.getElementById('cd-stat-range').textContent = pag.showing_from + ' – ' + pag.showing_to;
    }
    if (summary) {
        document.getElementById('cd-stat-qty').textContent = fmt(summary.total_qty || 0);
    }
}

function renderPagination(pag) {
    var wrap = document.getElementById('cd-pag-wrap');
    if (!pag || pag.total_pages <= 1) { wrap.style.display = 'none'; return; }
    wrap.style.display = 'flex';
    document.getElementById('cd-pag-info').textContent = pag.current_page + ' of ' + pag.total_pages;

    var cp = pag.current_page, tp = pag.total_pages, html = '';
    html += cp > 1
        ? '<a onclick="cdGoTo(1)">«</a><a onclick="cdGoTo(' + (cp-1) + ')">‹</a>'
        : '<span class="disabled">«</span><span class="disabled">‹</span>';

    var s = Math.max(1, cp-2), e = Math.min(tp, cp+2);
    if (s > 1) html += '<span>…</span>';
    for (var i = s; i <= e; i++) {
        html += i === cp
            ? '<span class="active">' + i + '</span>'
            : '<a onclick="cdGoTo(' + i + ')">' + i + '</a>';
    }
    if (e < tp) html += '<span>…</span>';
    html += cp < tp
        ? '<a onclick="cdGoTo(' + (cp+1) + ')">›</a><a onclick="cdGoTo(' + tp + ')">»</a>'
        : '<span class="disabled">›</span><span class="disabled">»</span>';

    document.getElementById('cd-pag-controls').innerHTML = html;
}

window.cdGoTo = function (p) { currentPage = p; saveFilters(); cdLoad(false); };

window.cdReset = function () {
    ['cd-f-from','cd-f-to','cd-f-part','cd-f-order'].forEach(function(id) {
        document.getElementById(id).value = '';
    });
    document.getElementById('cd-per-page').value = '25';
    currentPage = 1;
    try { sessionStorage.removeItem(FILTER_KEY); } catch(e) {}
    highlightFilters();
    cdLoad(false);
};

function fmt(v) { return parseFloat(v).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ','); }
function esc(s) {
    return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

restoreFilters();
cdLoad(false);

setInterval(function () { cdLoad(false); }, 5 * 60 * 1000);

})();
</script>