<?php
// ======================================================================
//  ASSET IMPORT – UPDATED FOR DESCRIPTION MATCH, FREQUENCY, LAST DATE,
//  SUB-LOCATION, LOADER, PURE JS, MDB, DUPLICATE PROTECTION
// ======================================================================

$tenant = $_REQUEST['tenant'] ?? null;
if (file_exists('../../../' . $tenant . '/config.php')) {
    require_once('../../../' . $tenant . '/config.php');
}
if (file_exists('/config.php')) {
    require_once('/config.php');
}

?>
<style>
/* Scrollable table, header fixed, no page overflow */
#tableWrapper {
    max-height: calc(100vh - 260px);
    /* adjust if needed */
    overflow-y: auto;
}

#tableWrapper table {
    margin-bottom: 0;
}

#tableWrapper thead th {
    position: sticky;
    top: 0;
    z-index: 5;
    background-color: #343a40;
    /* match .table-dark */
    color: #fff;
}

#importIssueSummary:empty {
    display: none;
}

.asset-import-issue-summary {
    border-left: 4px solid #e4a11b;
}

.asset-import-issue-summary details summary {
    cursor: pointer;
    list-style: none;
}

.asset-import-issue-summary details summary::-webkit-details-marker {
    display: none;
}

.asset-import-issue-list {
    display: grid;
    gap: .35rem;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    max-height: 180px;
    overflow-y: auto;
}

.asset-import-issue-item {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, .08);
    border-radius: .25rem;
    color: inherit;
    display: block;
    padding: .35rem .5rem;
    text-decoration: none;
}

.asset-import-issue-item:hover,
.asset-import-issue-item:focus {
    border-color: rgba(0, 85, 166, .45);
    color: inherit;
    outline: 0;
    text-decoration: none;
}

.asset-import-row-focus {
    animation: assetImportRowFocusOutline 2.6s ease-out;
}

.asset-import-row-focus > td {
    animation: assetImportRowFocusCells 2.6s ease-out;
}

@keyframes assetImportRowFocusCells {
    0%, 45% {
        background: #fff3cd;
    }

    100% {
        background: transparent;
    }
}

@keyframes assetImportRowFocusOutline {
    0%, 45% {
        box-shadow: inset 0 0 0 2px #e4a11b;
    }

    100% {
        box-shadow: inset 0 0 0 0 rgba(228, 161, 27, 0);
    }
}
</style>

<div class="container-fluid">

    <div class="row">
        <div class="col-12 mb-3">
            <div class="note note-light">
                <strong>Asset Import:</strong>
                Upload a CSV file containing the following headers: <small class="float-end">(CSV must be UTF-8 to correctly process)</small><br>
                <code>
                    Description, Safe working load, Plant Number, Serial Number, Model,
                    Date of manufacture, Manufacturer, Due Date, Frequency, Last Date, Sub Location
                </code>
            </div>
        </div>
    </div>

    <!-- CSV Upload -->
    <div class="row mb-3">
        <div class="col-12 col-md-10">
            <input type="file" id="csvFile" accept=".csv" class="form-control" />
        </div>
        <div class="col-12 col-md-2">
            <button class="btn btn-info w-100" id="btnTemplate" data-mdb-tooltip-init data-mdb-placement="top"
                data-mdb-trigger="hover" title="Download CSV Template">
                <i class="fad fa-download me-2"></i>Template
            </button>
        </div>
    </div>

    <!-- Loaders -->
    <div id="csvLoader" class="text-center my-4 d-none">
        <i class="fad fa-spinner fa-spin fa-3x"></i>
        <div id="csvLoaderText" class="mt-2">Uploading file…</div>
    </div>

    <div id="importProcessingLoader" class="text-center py-5 d-none">
        <h4 class="mb-3">
            <i class="fad fa-cogs fa-spin fa-3x fa-fw"></i>
        </h4>
        <h5 class="mb-2">Asset creation in progress</h5>
        <p class="text-muted mb-0">Please wait while the selected assets are being created.</p>
    </div>

    <!-- Preview / Mass Options / Table -->
    <div id="importContainer" class="d-none">
        <div id="importIssueSummary" class="mt-3"></div>

        <!-- Bulk Panel (moved ABOVE table) -->
        <div class="row g-3 mt-3">
            <div class="col-md-3">
                <label class="form-label">Bulk Location</label>
                <select class="form-select form-select-sm" id="bulkLoc"></select>
            </div>

            <div class="col-md-3">
                <label class="form-label">Bulk Sub-Location</label>
                <input type="text" class="form-control form-control-sm" id="bulkSubloc" list="datalistSubloc">
            </div>

            <div class="col-md-2">
                <div class="w-100 date-picker" id="bulkLastDatePicker" data-date-type="open" data-mdb-toggle-button="false" data-format="dd-mm-yyyy">
                    <label class="form-label">Bulk Last Date</label>
                    <input
                        type="text"
                        id="bulkLastDate"
                        name="bulkLastDate"
                        class="form-control form-control-sm"
                        placeholder="Last date"
                        value=""
                        data-mdb-confirmDateOnSelect
                        data-mdb-toggle="datepicker" />
                </div>
            </div>
            
            <div class="col-md-2">
                <div class="w-100 date-picker" id="bulkDueDatePicker" data-date-type="open" data-mdb-toggle-button="false" data-format="dd-mm-yyyy">
                    <label class="form-label">Bulk Due Date</label>
                    <input
                        type="text"
                        id="bulkDueDate"
                        name="bulkDueDate"
                        class="form-control form-control-sm"
                        placeholder="Due date"
                        value=""
                        data-mdb-confirmDateOnSelect
                        data-mdb-toggle="datepicker" />
                </div>
            </div>

            <div class="col-md-2 d-flex align-items-end">
                <button class="btn btn-info w-100" id="btnApplyBulk" data-mdb-tooltip-init data-mdb-placement="top"
                    data-mdb-trigger="hover" title="Apply values to selected rows">
                    <i class="fad fa-check me-2"></i>Apply to Selected
                </button>
            </div>
        </div>

        <datalist id="datalistSubloc"></datalist>

        <!-- Import button (still near bulk options, above table) -->
        <div class="row mt-3 mb-2">
            <div class="col-12">
                <button id="btnImport" class="btn btn-success" data-mdb-tooltip-init data-mdb-placement="top"
                    data-mdb-trigger="hover" title="Import all non-duplicate rows">
                    <i class="fad fa-upload me-2"></i>Import Assets
                </button>
            </div>
        </div>

        <!-- Scrollable Table -->
        <div class="row">
            <div class="col-12">
                <div id="tableWrapper" class="table-responsive">
                    <table class="table table-striped table-sm align-middle" id="importTable">
                        <thead class="table-dark">
                            <tr>
                                <th><input type="checkbox" id="chkAll"></th>
                                <th>#</th>
                                <th>Description</th>
                                <th>SWL</th>
                                <th>Plant No</th>
                                <th>Serial No</th>
                                <th>Model</th>
                                <th>DoM</th>
                                <th>Manufacturer</th>
                                <th>Last Date</th>
                                <th>Due Date</th>
                                <th>Location</th>
                                <th>Sub-Location</th>
                                <th>Frequency (months)</th>
                                <th>Code</th>
                                <th>Status</th>
                            </tr>
                        </thead>
                        <tbody id="importBody"></tbody>
                    </table>
                </div>
            </div>
        </div>

    </div>
</div>

<script>
// ==============================================================
// GLOBALS
// ==============================================================
window.uploadRows = window.uploadRows || [];
window.locations = window.locations || [];
window.plantCodes = window.plantCodes || [];
window.allSublocs = window.allSublocs || [];

function escapeImportHtml(value) {
    return String(value ?? '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

function initAssetImportDatepickers() {
    const modalElement = document.getElementById('popupBox') || document;
    const datepickerElements = modalElement.querySelectorAll('.date-picker');

    datepickerElements.forEach((datepickerEl) => {
        if (datepickerEl.dataset.dpInitialised === '1') {
            return;
        }

        const options = {
            confirmDateOnSelect: true,
            format: datepickerEl.getAttribute('data-format') || 'dd-mm-yyyy'
        };

        new mdb.Datepicker(datepickerEl, options);
        datepickerEl.dataset.dpInitialised = '1';
    });
}

initAssetImportDatepickers();
function parseCsvDateToUnix(value) {
    const s = (value || '').trim();
    if (!s) {
        return null;
    }

    let m = s.match(/^(\d{1,2})[-/](\d{1,2})[-/](\d{4})$/);
    if (m) {
        const day = parseInt(m[1], 10);
        const month = parseInt(m[2], 10) - 1;
        const year = parseInt(m[3], 10);
        const d = new Date(year, month, day);
        return Number.isNaN(d.getTime()) ? null : Math.floor(d.getTime() / 1000);
    }

    m = s.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
    if (m) {
        const year = parseInt(m[1], 10);
        const month = parseInt(m[2], 10) - 1;
        const day = parseInt(m[3], 10);
        const d = new Date(year, month, day);
        return Number.isNaN(d.getTime()) ? null : Math.floor(d.getTime() / 1000);
    }

    const fallback = new Date(s);
    return Number.isNaN(fallback.getTime()) ? null : Math.floor(fallback.getTime() / 1000);
}

function formatUnixToDisplay(unixValue) {
    const ts = parseInt(unixValue, 10);
    if (!ts) {
        return '';
    }

    const d = new Date(ts * 1000);
    if (Number.isNaN(d.getTime())) {
        return '';
    }

    const day = String(d.getDate()).padStart(2, '0');
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const year = d.getFullYear();

    return `${day}-${month}-${year}`;
}

function getNormalisedFrequency(rawValue) {
    const parsed = parseInt(rawValue, 10);
    return [4, 6, 12, 18, 21].includes(parsed) ? parsed : 12;
}

function normalisePlantDescription(value) {
    return String(value || '')
        .replace(/&nbsp;/gi, ' ')
        .replace(/\u00a0/g, ' ')
        .replace(/\s+/g, ' ')
        .trim()
        .toLowerCase();
}

function resolvePlantMatch(row, selectedFrequency = null) {
    const descKey = row.desc_key || normalisePlantDescription(row.desc);

    const sameDescription = plantCodes.filter(c =>
        (c.description_key || normalisePlantDescription(c.description)) === descKey
    );

    const hasCsvFreq = String(row.frequency_raw || '').trim() !== '';
    let effectiveFrequency;

    if (selectedFrequency !== null) {
        effectiveFrequency = getNormalisedFrequency(selectedFrequency);
    } else if (hasCsvFreq) {
        effectiveFrequency = getNormalisedFrequency(row.frequency_raw);
    } else if (sameDescription.length > 0) {
        effectiveFrequency = getNormalisedFrequency(sameDescription[0].frequency);
    } else {
        effectiveFrequency = 12;
    }

    const matchedPlant = sameDescription.find(c =>
        getNormalisedFrequency(c.frequency) === effectiveFrequency
    ) || null;

    row.frequency = effectiveFrequency;

    if (matchedPlant) {
        row.code = matchedPlant.code;
        row._matchType = 'matched';
    } else {
        row.code = '';
        row._matchType = sameDescription.length > 0 ? 'new-frequency' : 'new-description';
    }

    return {
        matchedPlant,
        effectiveFrequency,
        sameDescription
    };
}

function syncRowMatchState(tr) {
    const row = tr._row;
    const selectedFrequency = tr._freqSelect ? tr._freqSelect.value : null;
    const result = resolvePlantMatch(row, selectedFrequency);

    if (tr._freqSelect) {
        tr._freqSelect.value = String(result.effectiveFrequency);
    }

    if (tr._codeSelect) {
        tr._codeSelect.value = result.matchedPlant ? result.matchedPlant.code : '';
    }

    updateRowStatus(tr, result.matchedPlant);

    if (!row._error && !row._duplicate && tr._codeSelect && !result.matchedPlant && row.code !== '') {
        tr._codeSelect.value = row.code;
    }
}

function updateRowStatus(tr, matchedPlant) {
    const r = tr._row;
    const statusTd = tr.querySelector('.col-status');

    if (r._error) {
        statusTd.innerHTML = `<span class="badge bg-danger">Invalid – ${r._error}</span>`;
        return;
    }

    if (r._duplicate) {
        statusTd.innerHTML = `<span class="badge bg-warning">Duplicate</span>`;
        return;
    }

    if (matchedPlant) {
        statusTd.innerHTML = `<span class="badge bg-success">Matched</span>`;
        return;
    }

    statusTd.innerHTML = `<span class="badge bg-info">New Code</span>`;
}

function renderImportIssueSummary() {
    const host = document.getElementById('importIssueSummary');
    if (!host) return;

    const issues = uploadRows
        .map((row, index) => ({ row, index }))
        .filter(({ row }) => row._error || row._duplicate);

    if (issues.length < 1) {
        host.innerHTML = '';
        return;
    }

    const errorCount = issues.filter(({ row }) => row._error).length;
    const duplicateCount = issues.filter(({ row }) => row._duplicate).length;
    const selectedCount = uploadRows.filter((row) => !row._error && !row._duplicate).length;

    const issueRowsHtml = issues.map(({ row, index }) => {
        const reason = row._error ? `Invalid - ${row._error}` : 'Duplicate asset';
        const badgeClass = row._error ? 'bg-danger' : 'bg-warning text-dark';
        const identityParts = [
            row.desc || 'No description',
            row.plantnumber ? `Plant: ${row.plantnumber}` : '',
            row.serialnumber ? `Serial: ${row.serialnumber}` : ''
        ].filter(Boolean).map(escapeImportHtml);

        return `
            <a href="#assetImportRow${index + 1}" class="asset-import-issue-item small" data-import-jump-row="${index + 1}">
                <div class="d-flex justify-content-between gap-2">
                    <strong>Row ${index + 1}</strong>
                    <span class="badge ${badgeClass}">${escapeImportHtml(reason)}</span>
                </div>
                <div class="text-muted">${identityParts.join(' &middot; ')}</div>
            </a>`;
    }).join('');

    host.innerHTML = `
        <div class="note note-warning asset-import-issue-summary py-2 px-3 mb-0">
            <details open>
                <summary class="d-flex flex-wrap align-items-center justify-content-between gap-2">
                    <span>
                        <strong>CSV checks:</strong>
                        ${selectedCount} ready to import,
                        ${duplicateCount} duplicate${duplicateCount === 1 ? '' : 's'},
                        ${errorCount} error${errorCount === 1 ? '' : 's'}
                    </span>
                    <span class="small text-muted">Click to show/hide details</span>
                </summary>
                <div class="asset-import-issue-list mt-2">
                    ${issueRowsHtml}
                </div>
            </details>
        </div>`;
}

function jumpToImportRow(rowNumber) {
    const row = document.getElementById(`assetImportRow${rowNumber}`);
    if (!row) return;

    if (row._importHighlightTimer) {
        window.clearTimeout(row._importHighlightTimer);
    }
    row.classList.remove('asset-import-row-focus');
    row.querySelectorAll('td').forEach((cell) => {
        cell.style.transition = '';
        cell.style.backgroundColor = '';
        cell.style.color = '';
        cell.style.boxShadow = '';
    });

    row.scrollIntoView({
        behavior: 'smooth',
        block: 'center'
    });

    window.setTimeout(() => {
        const cells = row.querySelectorAll('td');
        cells.forEach((cell) => {
            cell.style.transition = '';
            cell.style.backgroundColor = '#0055A6';
            cell.style.color = '#ffffff';
            cell.style.boxShadow = 'inset 0 2px 0 #003f7a, inset 0 -2px 0 #003f7a';
        });

        window.setTimeout(() => {
            cells.forEach((cell) => {
                cell.style.transition = 'background-color 1.4s ease, color 1.4s ease, box-shadow 1.4s ease';
                cell.style.backgroundColor = '';
                cell.style.color = '';
                cell.style.boxShadow = '';
            });
        }, 5000);

        row._importHighlightTimer = window.setTimeout(() => {
            row.classList.remove('asset-import-row-focus');
            row.querySelectorAll('td').forEach((cell) => {
                cell.style.transition = '';
                cell.style.backgroundColor = '';
                cell.style.color = '';
                cell.style.boxShadow = '';
            });
            row._importHighlightTimer = null;
        }, 6600);
    }, 220);

    const firstControl = row.querySelector('input, select, button, a');
    if (firstControl && typeof firstControl.focus === 'function') {
        window.setTimeout(() => firstControl.focus({ preventScroll: true }), 320);
    }
}

document.addEventListener('click', function(event) {
    const jumpLink = event.target.closest('[data-import-jump-row]');
    if (!jumpLink) return;
    event.preventDefault();
    jumpToImportRow(jumpLink.getAttribute('data-import-jump-row'));
});


// ==============================================================
// CSV TEMPLATE DOWNLOAD
// ==============================================================
document.getElementById('btnTemplate').addEventListener('click', () => {
    const url = ROOT_URL + '/includes/asset/asset_functions.php?FUNCTION=assetDownloadTemplate&tenant=' +
        TENANT_URL;
    window.location.href = url;
});


// ==============================================================
// CSV UPLOAD HANDLER
// ==============================================================
document.getElementById('csvFile').addEventListener('change', function() {
    const file = this.files[0];
    if (!file) return;

    uploadRows = [];
    locations = [];
    plantCodes = [];
    allSublocs = [];

    const importContainer = document.getElementById('importContainer');
    const issueSummary = document.getElementById('importIssueSummary');
    const importBody = document.getElementById('importBody');
    if (importContainer) importContainer.classList.add('d-none');
    if (issueSummary) issueSummary.innerHTML = '';
    if (importBody) importBody.innerHTML = '';

    const loader = document.getElementById('csvLoader');
    const loaderText = document.getElementById('csvLoaderText');

    // Step 1: immediately show "Uploading file..."
    loaderText.textContent = 'Uploading file…';
    loader.classList.remove('d-none');

    const formData = new FormData();
    formData.append('FUNCTION', 'assetUploadCSV');
    formData.append('file', file);
    formData.append('clientnumber', <?= $_REQUEST['clientnumber'] ?>);
    formData.append('tenant', TENANT_URL);

    // Step 2: change text just before we actually POST
    loaderText.textContent = 'Processing CSV…';

    fetch(ROOT_URL + '/includes/asset/asset_functions.php', {
            method: 'POST',
            body: formData
        })
        .then(r => r.json())
        .then(j => {
            loader.classList.add('d-none');

            if (j.status !== 'ok') {
                showResponse('danger', j.message || 'CSV Error');
                return;
            }

            // store data
            uploadRows = j.rows || [];
            locations = j.locations || [];
            plantCodes = j.codes || [];
            allSublocs = j.sublocs || [];

            renderTable();
        })
        .catch(() => {
            loader.classList.add('d-none');
            showResponse('danger', 'Failed processing CSV');
        });
});



// ==============================================================
// RENDER TABLE
// ==============================================================
function renderTable() {

    const cont = document.getElementById('importContainer');
    const body = document.getElementById('importBody');
    body.innerHTML = '';
    const masterChk = document.getElementById('chkAll');
    if (masterChk) {
        masterChk.checked = false;
    }
    // build location dropdown (bulk + row)
    const locSel = document.getElementById('bulkLoc');
    locSel.innerHTML = '';
    locations.forEach(l => {
        const o = document.createElement('option');
        o.value = l.locnumber;
        o.textContent = l.locname + ' (' + l.postcode + ')';
        locSel.appendChild(o);
    });

    // build datalist for subloc
    const dl = document.getElementById('datalistSubloc');
    dl.innerHTML = '';
    allSublocs.forEach(s => {
        const val = String(s).trim();
        if (val === '' || val === '0') {
            return;
        }

        const o = document.createElement('option');
        o.value = val;
        dl.appendChild(o);
    })

    // Build rows
    uploadRows.forEach((r, idx) => {

        const tr = document.createElement('tr');
        tr.id = `assetImportRow${idx + 1}`;

        // row data stores
        tr._row = r;
        tr._locSelect = null;
        tr._sublocInput = null;
        tr._freqSelect = null;
        tr._codeSelect = null;

        // bookkeeping
        const isErr = r._error ? true : false;
        const isDup = r._duplicate ? true : false;

        const initialMatch = resolvePlantMatch(r);
        const matchedPlant = initialMatch.matchedPlant;

        // sub-location resolution
        let sl = (r.subloc_raw || '').trim();
        let slLower = sl.toLowerCase();

        let match = allSublocs.find(s => String(s).trim().toLowerCase() === slLower);

        if (!match && sl !== '') {
            allSublocs.push(sl);
            const o = document.createElement('option');
            o.value = sl;
            dl.appendChild(o);
            r.subloc = sl;
        } else if (match !== undefined && match !== null && String(match).trim() !== '' && String(match) !==
            '0') {
            r.subloc = String(match).trim();
        } else {
            r.subloc = sl;
        }

        // Table columns
        tr.innerHTML = `
            <td><input type="checkbox" class="chkRow"></td>
            <td>${idx + 1}</td>
            <td>${r.desc || ''}</td>
            <td>${r.swl || ''}</td>
            <td>${r.plantnumber || ''}</td>
            <td>${r.serialnumber || ''}</td>
            <td>${r.model || ''}</td>
            <td>${r.dateofmanf || ''}</td>
            <td>${r.manf || ''}</td>
            <td>${r.lastdate_display || r.lastdate_raw || ''}</td>
            <td>${r.duedate_display || ''}</td>
            <td class="col-loc"></td>
            <td class="col-subloc"></td>
            <td class="col-freq"></td>
            <td class="col-code"></td>
            <td class="col-status"></td>
        `;

        // STATUS
        const statusTd = tr.querySelector('.col-status');
        if (isErr) {
            statusTd.innerHTML = `<span class="badge bg-danger">Invalid – ${r._error}</span>`;
        } else if (isDup) {
            statusTd.innerHTML = `<span class="badge bg-warning">Duplicate</span>`;
        } else if (r._matchType === 'matched') {
            statusTd.innerHTML = `<span class="badge bg-success">Matched</span>`;
        } else if (r._matchType === 'new-frequency') {
            statusTd.innerHTML = `<span class="badge bg-info">New Code (new frequency)</span>`;
        } else {
            statusTd.innerHTML = `<span class="badge bg-info">New Code</span>`;
        }

        // disable checkbox for error/dup
        const rowChk = tr.querySelector('.chkRow');

        if (isErr || isDup) {
            rowChk.disabled = true;
            rowChk.checked = false;
            tr.classList.add('table-warning');
        } else {
            rowChk.disabled = false;
            rowChk.checked = true;
        }

        // LOCATION SELECT
        const locTD = tr.querySelector('.col-loc');
        const sel = document.createElement('select');
        sel.className = "form-select form-select-sm";
        locations.forEach(l => {
            const o = document.createElement('option');
            o.value = l.locnumber;
            o.textContent = l.locname + ' (' + l.postcode + ')';
            sel.appendChild(o);
        });
        tr._locSelect = sel;
        locTD.appendChild(sel);

        // SUB-LOCATION
        const slTD = tr.querySelector('.col-subloc');
        const slInput = document.createElement('input');
        slInput.type = "text";
        slInput.className = "form-control form-control-sm";
        slInput.setAttribute("list", "datalistSubloc");
        slInput.value = r.subloc || '';
        tr._sublocInput = slInput;
        slTD.appendChild(slInput);

        // FREQUENCY SELECT
        const fqTD = tr.querySelector('.col-freq');
        const fq = document.createElement('select');
        fq.className = "form-select form-select-sm w-100";
        [4, 6, 12, 18, 21].forEach(v => {
            const o = document.createElement('option');
            o.value = v;
            o.textContent = v;
            if (parseInt(r.frequency) === v) o.selected = true;
            fq.appendChild(o);
        });
        tr._freqSelect = fq;
        fqTD.appendChild(fq);
        fq.addEventListener('change', function() {
            syncRowMatchState(tr);
        });
        
        // CODE SELECT
        const codeTD = tr.querySelector('.col-code');
        const codeSel = document.createElement('select');
        codeSel.className = "form-select form-select-sm w-100";

        // build options
        const blankOpt = document.createElement('option');
        blankOpt.value = "";
        blankOpt.textContent = "--";
        codeSel.appendChild(blankOpt);

        plantCodes.forEach(c => {
            const o = document.createElement('option');
            o.value = c.code;
            o.textContent = c.code + " (" + c.description + ")";
            codeSel.appendChild(o);
        });

        // if matched
        if (matchedPlant) {
            codeSel.value = matchedPlant.code;
        }

        tr._codeSelect = codeSel;
        codeTD.appendChild(codeSel);
        
        syncRowMatchState(tr);
        
        body.appendChild(tr);
    });

    renderImportIssueSummary();
    document.getElementById('importContainer').classList.remove('d-none');
}


// ==============================================================
// SELECT ALL
// ==============================================================
(function() {
    const master = document.getElementById('chkAll');
    if (!master) return;

    master.addEventListener('change', function() {
        const checked = this.checked;

        // Only target the rows in the import table body
        const rows = document.querySelectorAll('#importBody tr');
        rows.forEach(tr => {
            const cb = tr.querySelector('input.chkRow');
            if (!cb || cb.disabled) return;
            cb.checked = checked;
        });
    });
})();


// ==============================================================
// BULK APPLY
// ==============================================================
document.getElementById('btnApplyBulk').addEventListener('click', () => {
    const bulkLoc = document.getElementById('bulkLoc').value;
    const bulkSL = document.getElementById('bulkSubloc').value.trim();

    const bulkDD = document.getElementById('bulkDueDate').value.trim();
    const bulkDDUnix = bulkDD !== '' ? parseCsvDateToUnix(bulkDD) : null;

    const bulkLD = document.getElementById('bulkLastDate').value.trim();
    const bulkLDUnix = bulkLD !== '' ? parseCsvDateToUnix(bulkLD) : null;

    document.querySelectorAll('#importBody tr').forEach(tr => {
        const chk = tr.querySelector('.chkRow');
        if (!chk || !chk.checked) return;

        if (bulkLoc !== '') {
            tr._locSelect.value = bulkLoc;
        }

        if (bulkSL !== '') {
            tr._sublocInput.value = bulkSL;
        }

        if (bulkDD !== '') {
            tr._row.duedate_raw = bulkDD;
            tr._row.duedate = bulkDDUnix;
            tr._row.duedate_display = bulkDD;

            const dueDateCell = tr.children[10];
            if (dueDateCell) {
                dueDateCell.textContent = bulkDD;
            }
        }

        if (bulkLD !== '') {
            tr._row.lastdate_raw = bulkLD;
            tr._row.lastdate_unix = bulkLDUnix;
            tr._row.lastdate_display = bulkLD;

            const lastDateCell = tr.children[9];
            if (lastDateCell) {
                lastDateCell.textContent = bulkLD;
            }
        }
    });

    showResponse('success', 'Bulk values applied to selected rows');
});


// ==============================================================
// IMPORT COMMIT
// ==============================================================
function collectSelectedImportRows() {
    const out = [];

    document.querySelectorAll('#importBody tr').forEach(tr => {

        const chk = tr.querySelector('.chkRow');
        if (!chk || !chk.checked) return;

        const r = tr._row;

        if (r._error || r._duplicate) return;

        out.push({
            desc: r.desc,
            swl: r.swl,
            plantnumber: r.plantnumber,
            serialnumber: r.serialnumber,
            model: r.model,
            dateofmanf: r.dateofmanf,
            manf: r.manf,
            duedate: r.duedate,
            currdate: r.lastdate_unix || null,
            locnumber: parseInt(tr._locSelect.value),
            code: tr._codeSelect.value,
            frequency: parseInt(tr._freqSelect.value),
            subloc: tr._sublocInput.value.trim()
        });
    });

    return out;
}

function confirmAssetImport(out) {
    if (!out.length) {
        showResponse('warning', 'No rows selected');
        return;
    }

    const issueCount = uploadRows.filter((row) => row._error || row._duplicate).length;
    const confirmHtml = `
        <div class="text-center">
            <i class="fad fa-upload fa-3x mb-3 text-info"></i>
            <h5 class="mb-2">Import ${out.length} selected asset${out.length === 1 ? '' : 's'}?</h5>
            <p class="text-muted mb-0">
                Duplicate and invalid rows will be skipped${issueCount > 0 ? ` (${issueCount} flagged in the CSV checks summary).` : '.'}
            </p>
        </div>`;

    if (typeof loadModalContent === 'function') {
        loadModalContent(confirmHtml, 'assetImportConfirmBox', 'modal-md', 1080, 'false', 'Confirm Asset Import',
            'cancelConfirm', function() {
                if (typeof killModal === 'function') {
                    killModal('assetImportConfirmBox');
                }
                commitAssetImport(out);
            });
        return;
    }

    commitAssetImport(out);
}

function commitAssetImport(out) {
    const importContainer = document.getElementById('importContainer');
    const processingLoader = document.getElementById('importProcessingLoader');

    if (importContainer) {
        importContainer.classList.add('d-none');
    }

    if (processingLoader) {
        processingLoader.classList.remove('d-none');
    }

    const fd = new FormData();
    fd.append('FUNCTION', 'assetCommitImport');
    fd.append('clientnumber', <?= (int)$_REQUEST['clientnumber'] ?>);
    fd.append('rows', JSON.stringify(out));
    fd.append('tenant', TENANT_URL);

    fetch(ROOT_URL + '/includes/asset/asset_functions.php', {
            method: 'POST',
            body: fd
        })
        .then(r => r.json())
        .then(j => {
            if (j.status !== 'ok') {
                showResponse('danger', 'Import failed: ' + (j.message || 'unknown error'));
                if (importContainer) {
                    importContainer.classList.remove('d-none');
                }
                return;
            }

            const inserted = parseInt(j.inserted || 0, 10);
            const duplicates = parseInt(j.skipped || 0, 10); // treated as duplicates
            const failed = Array.isArray(j.errors) ? j.errors.length : 0;

            const lines = [];
            let type = 'success';

            // 1. Successful uploads
            if (inserted > 0) {
                lines.push(inserted + ' assets uploaded successfully.');
            }

            // 2. Duplicates
            if (duplicates > 0) {
                lines.push(duplicates + ' duplicate assets skipped.');
            }

            // 3. Failed rows
            if (failed > 0) {
                lines.push(failed + ' assets failed.');
                // downgrade severity
                type = inserted > 0 ? 'warning' : 'danger';
            }

            // If literally nothing happened
            if (inserted === 0 && duplicates === 0 && failed === 0) {
                showResponse('warning', 'No assets were imported. Please check your CSV.');
                if (importContainer) {
                    importContainer.classList.remove('d-none');
                }
                return;
            }

            showResponse(type, lines.join('<br>'));

            // Close modal if available
            if (typeof killModal === 'function') {
                killModal('popupBox');
            }

            // 2 second delay then reload parent page
            setTimeout(function() {
                window.location.reload();
            }, 2000);
        })
        .catch(() => {
            showResponse('danger', 'Import error');
        });
}

document.getElementById('btnImport').addEventListener('click', () => {
    confirmAssetImport(collectSelectedImportRows());
});
</script>
