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

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

/* ── Stats ── */
.stats { display: flex; gap: 12px; margin-bottom: 1.4rem; flex-wrap: wrap; }
.stat  { background: #fff; border: 1px solid #ece8f5; border-radius: 10px; padding: 12px 20px; box-shadow: 0 1px 4px rgba(156,72,147,.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 ── */
.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: #9C4893; }
.fg input.filter-active { border-color: #9C4893; background: #fdf8fd; }

.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: #9C4893; color: #9C4893; }
.btn.primary { background: #9C4893; color: #fff; border-color: #9C4893; }
.btn.primary:hover { background: #7a3572; }

/* ── Table ── */
.table-wrap { border-radius: 10px; overflow: hidden; border: 1px solid #ece8f5; box-shadow: 0 2px 12px rgba(156,72,147,.07); }
table { width: 100%; border-collapse: collapse; background: #fff; }
thead th {
    background: #9C4893; 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 #f4f0f9; font-size: 13px; color: #333; vertical-align: middle; }
tbody td.r { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr:hover        { background: #fdf8fd; }
tbody tr.stripe       { background: #faf7fd; }
tbody tr.stripe:hover { background: #f4eef9; }

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

/* Cost colours */
.c-mat   { color: #c0392b; font-weight: 600; }
.c-lab   { color: #2980b9; font-weight: 600; }
.c-mac   { color: #8e44ad; font-weight: 600; }
.c-total { color: #1a1a2e; font-weight: 700; }

/* BOP tags */
.bop-wrap { display: flex; flex-wrap: wrap; gap: 4px; max-width: 280px; }
.bop-tag  { background: #f0eaf5; color: #6a2d80; border-radius: 4px; font-size: 11px; padding: 2px 7px; font-weight: 500; white-space: nowrap; }

/* ── Pagination ── */
.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: #9C4893; color: #fff; border-color: #9C4893; }
.pag .active   { background: #9C4893; color: #fff; border-color: #9C4893; font-weight: 600; }
.pag .disabled { opacity: .4; pointer-events: none; }

/* Toast */
#sc-toast {
    position: fixed; bottom: 24px; right: 24px; padding: 12px 22px;
    border-radius: 8px; font-size: 14px; font-weight: 500; color: #fff;
    z-index: 99999; opacity: 0; pointer-events: none;
    transition: opacity .3s; box-shadow: 0 4px 16px rgba(0,0,0,.2);
}
#sc-toast.show    { opacity: 1; }
#sc-toast.error   { background: #c0392b; }
#sc-toast.success { background: #27ae60; }
</style>

<h2>Standard Cost Report</h2>

<!-- Stats -->
<div class="stats hide">
    <div class="stat"><div class="stat-label">Total Parts</div><div class="stat-value" id="sc-stat-total">—</div></div>
    <div class="stat"><div class="stat-label">Showing</div><div class="stat-value" id="sc-stat-range" style="font-size:15px;padding-top:5px">—</div></div>
    <div class="stat"><div class="stat-label">Avg Material Cost</div><div class="stat-value" id="sc-stat-mat" style="font-size:17px;padding-top:4px">—</div></div>
    <div class="stat"><div class="stat-label">Avg Total Std Cost</div><div class="stat-value" id="sc-stat-avg" style="font-size:17px;padding-top:4px;color:#9C4893">—</div></div>
</div>

<!-- Toolbar -->
<div class="toolbar-row">
    <div class="fg">
        <label>Part Number</label>
        <input type="text" id="sc-f-part" placeholder="Search part…" oninput="scDebounce()">
    </div>
    <div class="fg">
        <label>Min Total Cost</label>
        <input type="number" id="sc-f-min" placeholder="e.g. 10" oninput="scDebounce()" style="width:120px">
    </div>
    <div class="fg">
        <label>Max Total Cost</label>
        <input type="number" id="sc-f-max" placeholder="e.g. 500" oninput="scDebounce()" style="width:120px">
    </div>
    <div class="fg">
        <label>Per page</label>
        <select id="sc-per-page" onchange="scLoad()">
            <option value="25" selected>25</option>
            <option value="50">50</option>
            <option value="100">100</option>
        </select>
    </div>
    <button class="btn" onclick="scReset()">↺ Reset</button>
    <button class="btn primary" onclick="scLoad()">Search</button>
</div>

<!-- Table -->
<div class="table-wrap">
<table>
    <thead>
        <tr>
            <th>#</th>
            <th>Part Number</th>
            <th class="r">Material Cost</th>
            <th>BOP (Bought-In Parts)</th>
            <th class="r">Labour Cost</th>
            <th class="r">Machine Cost</th>
            <th class="r">Total Std Cost</th>
        </tr>
    </thead>
    <tbody id="sc-tbody">
        <tr><td colspan="7" class="no-data">Loading…</td></tr>
    </tbody>
</table>
</div>

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

<div id="sc-toast"></div>

<script>
(function () {

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

/* ── Filter persistence ── */
function saveFilters() {
    var s = {
        part    : document.getElementById('sc-f-part').value,
        min     : document.getElementById('sc-f-min').value,
        max     : document.getElementById('sc-f-max').value,
        perPage : document.getElementById('sc-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.part    !== undefined) document.getElementById('sc-f-part').value   = s.part;
        if (s.min     !== undefined) document.getElementById('sc-f-min').value    = s.min;
        if (s.max     !== undefined) document.getElementById('sc-f-max').value    = s.max;
        if (s.perPage !== undefined) document.getElementById('sc-per-page').value = s.perPage;
        if (s.page    !== undefined) currentPage = parseInt(s.page) || 1;
        highlightFilters();
    } catch(e) {}
}

function highlightFilters() {
    ['sc-f-part','sc-f-min','sc-f-max'].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('sc-per-page').value,
        part         : document.getElementById('sc-f-part').value.trim(),
        min_cost     : document.getElementById('sc-f-min').value.trim(),
        max_cost     : document.getElementById('sc-f-max').value.trim()
    };
}

/* ── Debounce for text inputs ── */
window.scDebounce = function () {
    saveFilters();
    clearTimeout(debTimer);
    debTimer = setTimeout(function () { currentPage = 1; scLoad(false); }, 400);
};

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

    document.getElementById('sc-tbody').innerHTML =
        '<tr><td colspan="7" class="no-data">Loading…</td></tr>';

    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_std_costs&' + qs,
        type: 'GET',
        dataType: 'json',
        success: function(res) {
            if (!res.success) {
                document.getElementById('sc-tbody').innerHTML =
                    '<tr><td colspan="7" 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, status, error) {
            var raw = xhr.responseText || '';
            console.log('[stdcost] HTTP status:', xhr.status);
            console.log('[stdcost] raw response (first 500 chars):', raw.substring(0, 500));

            // Try to parse as JSON even on error status
            try {
                var res = JSON.parse(raw);
                document.getElementById('sc-tbody').innerHTML =
                    '<tr><td colspan="7" class="no-data" style="color:red">' +
                    esc(res.message || 'Error loading data.') + '</td></tr>';
            } catch(e) {
                document.getElementById('sc-tbody').innerHTML =
                    '<tr><td colspan="7" 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>';
            }
        }
    });
};

/* ── Render rows ── */
function renderRows(rows, pag) {
    var tbody = document.getElementById('sc-tbody');
    if (!rows.length) {
        tbody.innerHTML = '<tr><td colspan="7" class="no-data">No parts found.</td></tr>';
        return;
    }

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

    rows.forEach(function (r, i) {
        var stripe  = (i % 2 === 1) ? ' stripe' : '';
        var matCost = parseFloat(r.material_cost || 0);
        var labCost = parseFloat(r.labour_cost   || 0);
        var macCost = parseFloat(r.machine_cost  || 0);
        var total   = parseFloat(r.total_cost    || 0);

        var bopHtml = (r.bop_parts && r.bop_parts.length)
            ? '<div class="bop-wrap">' +
              r.bop_parts.map(function (p) { return '<span class="bop-tag">' + esc(p) + '</span>'; }).join('') +
              '</div>'
            : '<span style="color:#ddd;font-size:11px">—</span>';

        html +=
            '<tr class="' + stripe + '">' +
            '<td style="color:#ccc;font-size:11px">'     + (offset + i + 1)   + '</td>' +
            '<td style="font-weight:700;color:#1a1a2e">' + esc(r.part_number) + '</td>' +
            '<td class="r c-mat">£' + fmt(matCost) + '</td>' +
            '<td>' + bopHtml + '</td>' +
            '<td class="r c-lab">£' + fmt(labCost) + '</td>' +
            '<td class="r c-mac">£' + fmt(macCost) + '</td>' +
            '<td class="r c-total">£' + fmt(total)  + '</td>' +
            '</tr>';
    });

    tbody.innerHTML = html;
}

/* ── Stats ── */
function updateStats(pag, summary) {
    if (pag) {
        document.getElementById('sc-stat-total').textContent = pag.total_records;
        document.getElementById('sc-stat-range').textContent = pag.showing_from + ' – ' + pag.showing_to;
    }
    if (summary) {
        document.getElementById('sc-stat-mat').textContent = '£' + fmt(summary.avg_material || 0);
        document.getElementById('sc-stat-avg').textContent = '£' + fmt(summary.avg_total    || 0);
    }
}

/* ── Pagination ── */
function renderPagination(pag) {
    var wrap = document.getElementById('sc-pag-wrap');
    if (!pag || pag.total_pages <= 1) { wrap.style.display = 'none'; return; }
    wrap.style.display = 'flex';
    document.getElementById('sc-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="scGoTo(1)">«</a><a onclick="scGoTo(' + (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="scGoTo(' + i + ')">' + i + '</a>';
    }
    if (e < tp) html += '<span>…</span>';
    html += cp < tp
        ? '<a onclick="scGoTo(' + (cp+1) + ')">›</a><a onclick="scGoTo(' + tp + ')">»</a>'
        : '<span class="disabled">›</span><span class="disabled">»</span>';

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

window.scGoTo = function (p) { currentPage = p; saveFilters(); scLoad(false); };

/* ── Reset — clears filters then reloads all data ── */
window.scReset = function () {
    ['sc-f-part','sc-f-min','sc-f-max'].forEach(function (id) { document.getElementById(id).value = ''; });
    document.getElementById('sc-per-page').value = '25';
    currentPage = 1;
    try { sessionStorage.removeItem(FILTER_KEY); } catch(e) {}
    highlightFilters();
    scLoad(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();
scLoad(false);

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

})();
</script>