// purchaseexport.js — behaviour for Purchase Import Entry (purchaseexport.php)
//
// Modeled on the Purchase Entry (purchentry.php) pattern: client-side row
// templates, select2 brand/product pickers, live subtotal/net recalculation,
// stock-quantity lookup and a paged search modal. Kept as its own file
// (unlike purchentry.php, which inlines this logic) — same behaviour pattern,
// different table/fields underneath.
//
// Carton math: selecting a product auto-fills "Per Carton" from the product
// master's Pcs Per Carton value. Tot Qty = Ctn Qty x Per Carton, and Amount =
// Tot Qty x Cost. Per Carton stays editable in case a specific purchase packs
// differently than the master default.
//
// Charges: Freight Charges is a fixed field next to Subtotal (it's on every
// bill), while the Charges grid below it is an add-as-many-as-you-like list
// where each row picks an account from the Purchase Expense master (accmast
// grpcode 007) plus an amount — for the variable/occasional charges. Both
// are summed into Net Amount.
//
// Currency / ROE: mirrors the Currency + Rate of Exchange pattern used on
// bankrecp.php / bankpay.php / cashrecp.php / cashpay.php. Line costs,
// Subtotal, Freight Charges and Charges Total stay in the entry currency;
// Net Amount is the ONE place the ROE conversion to INR happens
// (Subtotal + Freight + Charges Total) x ROE — same single-conversion-point
// idea as those pages' feamt*roe=amount. Switching Currency back to INR
// resets ROE to 1 (only when ROE is still empty/zero, so a manually-entered
// ROE is never silently overwritten).
//
// Expects the host page to define before including this file:
//   ALL_BRANDS       — [{code,name}, ...]
//   ALL_PRODUCTS     — [{id,name,cost,brand,percarton}, ...]
//   ALL_PURCHEXPENSE — [{code,name}, ...]  (Purchase Expense master, for the Charge dropdown)
//   PEX_SEARCH_URL   — backend search endpoint, e.g. includes/purchaseexport_search.php

(function () {

    function escapeHtml(s) {
        return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
            return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
        });
    }

    function filterProductsForRow(tr) {
        var brandSel = tr.querySelector('.brand-sel');
        var prodSel  = tr.querySelector('.product-sel');
        if (!brandSel || !prodSel) return;
        var brand = brandSel.value;
        var keepVal = prodSel.value;
        var hasSel2 = !!$(prodSel).data('select2');
        if (hasSel2) $(prodSel).select2('destroy');

        var html = '<option value="">-- Select Product --</option>';
        var keepStillValid = false;
        ALL_PRODUCTS.forEach(function (p) {
            if (!brand || String(p.brand) === String(brand)) {
                var sel = (String(p.id) === String(keepVal)) ? ' selected' : '';
                if (sel) keepStillValid = true;
                html += '<option value="' + p.id + '" data-cost="' + p.cost + '" data-brand="' + (p.brand || '').replace(/"/g, '&quot;') + '" data-percarton="' + (p.percarton || 0) + '"' + sel + '>' + escapeHtml(p.name) + '</option>';
            }
        });
        prodSel.innerHTML = html;
        if (!keepStillValid) prodSel.value = '';

        var editable = !document.getElementById('vouchdt').disabled;
        $(prodSel).select2({ dropdownAutoWidth: true, width: '100%', placeholder: '-- Select Product --', allowClear: false });
        $(prodSel).prop('disabled', !editable).trigger('change.select2');
    }

    function fetchStockQty(tr) {
        var prodSel = tr.querySelector('.product-sel');
        var $stockFld = $(tr).find('.stockqty-fld');
        if (!prodSel || !prodSel.value) { $stockFld.val('').attr('placeholder',''); return; }
        var godownEl = document.getElementById('godown');
        var godown = godownEl ? godownEl.value : '';
        if (!godown) { $stockFld.val('').attr('placeholder','Select Godown'); return; }
        $stockFld.attr('placeholder','');
        $.post('includes/stock_lookup.php', { product: prodSel.value, godown: godown }, function (data) {
            $stockFld.val(data && data.success ? data.qty : '');
        }, 'json');
    }

    function refreshAllStockQty() {
        document.querySelectorAll('#dgrid tbody tr').forEach(function (tr) { fetchStockQty(tr); });
    }

    function initRowSelects(tr, isNewRow) {
        $(tr).find('select.brand-sel').each(function () {
            if (!$(this).data('select2')) {
                $(this).select2({ dropdownAutoWidth: true, width: '100%', placeholder: '-- All Brands --', allowClear: true });
            }
            var editable = !document.getElementById('vouchdt').disabled;
            $(this).prop('disabled', !editable).trigger('change.select2');
        });

        filterProductsForRow(tr);

        $(tr).find('select.brand-sel').off('change.brandfilter').on('change.brandfilter', function () {
            filterProductsForRow(tr);
            recalc();
        });

        // Auto-fill Cost and Per Carton from the selected product's master record.
        $(tr).find('select.product-sel').off('change.autofill').on('change.autofill', function () {
            var opt = this.options[this.selectedIndex];
            var cost = opt ? (opt.getAttribute('data-cost') || '') : '';
            var perCarton = opt ? (opt.getAttribute('data-percarton') || '') : '';
            var $costInp = $(tr).find('input[name="cost[]"]');
            var $perCartonInp = $(tr).find('.percarton-fld');
            if (cost !== '' && parseFloat(cost) > 0) { $costInp.val(cost); }
            if (perCarton !== '' && parseFloat(perCarton) > 0) { $perCartonInp.val(perCarton); }
            recalc();
            // Auto-add a fresh blank row once a product is picked in the
            // last row, so entry can continue without clicking "Add Row".
            if (this.value) {
                var tbody = document.querySelector('#dgrid tbody');
                if (tr === tbody.rows[tbody.rows.length - 1]) { window.addRow(); }
            }
        });

        $(tr).find('select.product-sel').off('change.stockqty').on('change.stockqty', function () {
            var godownEl = document.getElementById('godown');
            if (this.value && godownEl && !godownEl.value) {
                Swal.fire({ icon:'warning', title:'Select Godown First', text:'Please select a Godown before picking a product, so stock can be shown correctly.', confirmButtonColor:'#2563eb' });
                if ($(godownEl).data('select2')) { $(godownEl).select2('open'); } else { godownEl.focus(); }
            }
            fetchStockQty(tr);
        });

        // Skip the live stock lookup for rows that already have a saved
        // product + stock snapshot from the database (i.e. this is the
        // initial render of an existing entry) — Stock Qty should keep
        // showing the figure recorded at save time, not silently swap in
        // today's current stock. Freshly added rows, or a product change
        // the user makes (change.stockqty above), still fetch live.
        var prodSel = tr.querySelector('.product-sel');
        var hasExistingProduct = prodSel && prodSel.value;
        if (isNewRow || !hasExistingProduct) {
            fetchStockQty(tr);
        }
    }

    function buildRowHtml() {
        var brandOpts = '<option value="">-- All Brands --</option>';
        ALL_BRANDS.forEach(function (b) {
            brandOpts += '<option value="' + b.code + '">' + escapeHtml(b.name) + '</option>';
        });
        var prodOpts = '<option value="">-- Select Product --</option>';
        ALL_PRODUCTS.forEach(function (p) {
            prodOpts += '<option value="' + p.id + '" data-cost="' + p.cost + '" data-brand="' + (p.brand || '') + '" data-percarton="' + (p.percarton || 0) + '">' + escapeHtml(p.name) + '</option>';
        });
        return '<tr>' +
            '<td class="srno" style="text-align:center;color:#94a3b8;font-weight:600;font-size:11px;"></td>' +
            '<td><button type="button" class="row-del form" onclick="delRow(this)"><i class=\'fa fa-times\'></i></button></td>' +
            '<td><select name="brand[]" class="form brand-sel">' + brandOpts + '</select></td>' +
            '<td><select name="product[]" class="form product-sel">' + prodOpts + '</select></td>' +
            '<td><input type="text" class="stockqty-fld form" readonly tabindex="-1" value=""></td>' +
            '<td><input type="number" step="any" name="ctnqty[]" class="numfld form ctnqty-fld" oninput="recalc()"></td>' +
            '<td><input type="number" step="any" name="percarton[]" class="numfld form percarton-fld" oninput="recalc()"></td>' +
            '<td><input type="number" step="any" name="qty[]" class="numfld form qty-fld" readonly tabindex="-1"></td>' +
            '<td><input type="number" step="any" name="cbm[]" class="numfld form cbm-fld" oninput="recalc()"></td>' +
            '<td><input type="number" step="any" name="weight[]" class="numfld form weight-fld" oninput="recalc()"></td>' +
            '<td><select name="calby[]" class="form calby-fld" onchange="recalc()">' +
                '<option value="QTY" selected>Qty</option>' +
                '<option value="CBM">CBM</option>' +
                '<option value="WEIGHT">Weight</option>' +
                '</select></td>' +
            '<td><input type="number" step="any" name="cost[]" class="numfld form" oninput="recalc()"></td>' +
            '<td><input type="number" step="any" name="amt[]" class="numfld form" readonly tabindex="-1"></td>' +
            '</tr>';
    }

    window.addRow = function () {
        var tbody = document.querySelector('#dgrid tbody');
        tbody.insertAdjacentHTML('beforeend', buildRowHtml());
        var tr = tbody.rows[tbody.rows.length - 1];
        initRowSelects(tr, true);
        renumber();
    };

    window.delRow = function (btn) {
        var tbody = document.querySelector('#dgrid tbody');
        if (tbody.rows.length > 1) { btn.closest('tr').remove(); recalc(); }
    };

    function renumber() {
        document.querySelectorAll('#dgrid tbody tr').forEach(function (tr, i) {
            var c = tr.querySelector('.srno'); if (c) c.textContent = i + 1;
        });
    }

    // ── Charge rows: each picks an account from the Purchase Expense master ─
    function chgExpOptsHtml(selectedCode) {
        var opts = '<option value="">-- Select Expense --</option>';
        ALL_PURCHEXPENSE.forEach(function (pe) {
            var sel = (selectedCode != null && String(pe.code) === String(selectedCode)) ? ' selected' : '';
            opts += '<option value="' + pe.code + '"' + sel + '>' + escapeHtml(pe.name) + '</option>';
        });
        return opts;
    }

    function buildChgRowHtml() {
        return '<tr>' +
            '<td class="chgsrno" style="text-align:center;color:#94a3b8;font-weight:600;font-size:11px;"></td>' +
            '<td><button type="button" class="row-del form" onclick="chgDelRow(this)"><i class=\'fa fa-times\'></i></button></td>' +
            '<td><select name="chgexp[]" class="form chgexp-sel">' + chgExpOptsHtml() + '</select></td>' +
            '<td><input type="number" step="any" name="chgamt[]" class="numfld form" oninput="recalc()"></td>' +
            '</tr>';
    }

    function initChgRowSelects(tr) {
        $(tr).find('select.chgexp-sel').each(function () {
            if (!$(this).data('select2')) {
                $(this).select2({ dropdownAutoWidth: true, width: '100%', placeholder: '-- Select Expense --', allowClear: true });
            }
            var editable = !document.getElementById('vouchdt').disabled;
            $(this).prop('disabled', !editable).trigger('change.select2');
        });
        $(tr).find('select.chgexp-sel').off('change.recalc').on('change.recalc', function () { recalc(); });
    }

    window.chgAddRow = function () {
        var tbody = document.querySelector('#chggrid tbody');
        tbody.insertAdjacentHTML('beforeend', buildChgRowHtml());
        var tr = tbody.rows[tbody.rows.length - 1];
        initChgRowSelects(tr);
        chgRenumber();
    };

    window.chgDelRow = function (btn) {
        var tbody = document.querySelector('#chggrid tbody');
        if (tbody.rows.length > 1) { btn.closest('tr').remove(); recalc(); }
        else {
            var tr = btn.closest('tr');
            tr.querySelectorAll('input').forEach(function (i) { i.value = ''; });
            var $sel = $(tr).find('select.chgexp-sel');
            $sel.val('').trigger('change.select2');
            recalc();
        }
        chgRenumber();
    };

    function chgRenumber() {
        document.querySelectorAll('#chggrid tbody tr').forEach(function (tr, i) {
            var c = tr.querySelector('.chgsrno'); if (c) c.textContent = i + 1;
        });
    }

    window.recalc = function () {
        var totAmt = 0;
        document.querySelectorAll('#dgrid tbody tr').forEach(function (tr) {
            var ctnInp    = tr.querySelector('.ctnqty-fld');
            var perInp    = tr.querySelector('.percarton-fld');
            var qtyInp    = tr.querySelector('.qty-fld');
            var cbmInp    = tr.querySelector('.cbm-fld');
            var weightInp = tr.querySelector('.weight-fld');
            var calbyInp  = tr.querySelector('.calby-fld');
            var costInp   = tr.querySelector('input[name="cost[]"]');
            var amtInp    = tr.querySelector('input[name="amt[]"]');

            var ctn = ctnInp && ctnInp.value !== '' ? parseFloat(ctnInp.value) : 0;
            var per = perInp && perInp.value !== '' ? parseFloat(perInp.value) : 0;
            if (isNaN(ctn)) ctn = 0;
            if (isNaN(per)) per = 0;
            var qty = ctn * per;
            if (qtyInp) qtyInp.value = qty ? qty.toFixed(2) : '';

            var cbm = cbmInp && cbmInp.value !== '' ? parseFloat(cbmInp.value) : 0;
            var weight = weightInp && weightInp.value !== '' ? parseFloat(weightInp.value) : 0;
            if (isNaN(cbm)) cbm = 0;
            if (isNaN(weight)) weight = 0;

            // Amount is driven by whichever basis "Calc By" selects for this line.
            var calby = calbyInp ? calbyInp.value : 'QTY';
            var basis = calby === 'CBM' ? cbm : (calby === 'WEIGHT' ? weight : qty);

            var cost = costInp && costInp.value !== '' ? parseFloat(costInp.value) : 0;
            if (isNaN(cost)) cost = 0;
            var amt = basis * cost;
            if (amtInp) amtInp.value = amt ? amt.toFixed(2) : '';
            totAmt += amt;
        });
        var t_amt = document.getElementById('t_amt');
        if (t_amt) t_amt.textContent = totAmt ? totAmt.toFixed(2) : '';

        var chargesTotal = 0;
        document.querySelectorAll('#chggrid tbody tr').forEach(function (tr) {
            var amtInp = tr.querySelector('input[name="chgamt[]"]');
            var amt = amtInp && amtInp.value !== '' ? parseFloat(amtInp.value) : 0;
            if (isNaN(amt)) amt = 0;
            chargesTotal += amt;
        });

        var freight   = parseFloat((document.getElementById('freight_charges') || {}).value || 0) || 0;
        var baddebts  = parseFloat((document.getElementById('baddebts') || {}).value || 0) || 0;
        var doamt     = parseFloat((document.getElementById('doamt') || {}).value || 0) || 0;
        var preConv = totAmt + freight + chargesTotal + baddebts + doamt;

        var roeFld = document.getElementById('roe');
        var roe = roeFld && roeFld.value !== '' ? parseFloat(roeFld.value) : 1;
        if (isNaN(roe) || roe <= 0) roe = 1;
        var net = preConv * roe;

        var fmt = function (v) { return v == 0 ? '' : Number(v.toFixed(2)).toString(); };
        document.getElementById('sum_subtotal').value  = fmt(totAmt);
        document.getElementById('sum_charges').value   = fmt(chargesTotal);
        document.getElementById('sum_netamount').value = fmt(net);
    };

    $(function () {
        document.querySelectorAll('#dgrid tbody tr').forEach(function (tr) { initRowSelects(tr); });
        document.querySelectorAll('#chggrid tbody tr').forEach(function (tr) { initChgRowSelects(tr); });
        chgRenumber();
        $('#godown').on('change', function () { refreshAllStockQty(); });

        // Switching to INR resets ROE to 1 — same auto-reset bankrecp.php uses —
        // but only when ROE is still empty/zero, so a manually-entered ROE
        // (e.g. someone re-selecting INR by mistake) is never clobbered.
        $('#currency').on('change', function () {
            if ($(this).val() === 'INR' && (!$('#roe').val() || $('#roe').val() == '0')) {
                $('#roe').val('1');
            }
            recalc();
        });

        renumber();
        recalc();

        // ── Validation + re-enable on submit ──────────────────────────────
        $('#ssubmit').on('click', function (e) {
            document.querySelectorAll('input.form[disabled], select.form[disabled]').forEach(function (inp) { inp.disabled = false; });
            var errors = [];
            if (!document.getElementById('vouchdt').value) errors.push('Date is required');
            if (!document.getElementById('supplier').value) errors.push('Supplier is required');
            if (!document.getElementById('godown').value) errors.push('Godown is required');
            var hasRow = false;
            document.querySelectorAll('#dgrid tbody tr').forEach(function (tr) {
                var p = tr.querySelector('select[name="product[]"]');
                if (p && p.value) hasRow = true;
            });
            if (!hasRow) errors.push('At least one row with Product is required');
            if (errors.length) {
                e.preventDefault(); e.stopImmediatePropagation();
                Swal.fire({
                    icon: 'warning', title: 'Required Fields',
                    html: '<ul style="text-align:left;padding-left:20px;margin:0;">' + errors.map(function (m) { return '<li style="margin-bottom:4px;">' + m + '</li>'; }).join('') + '</ul>',
                    confirmButtonColor: '#2563eb'
                });
            }
        });

        // ── hedit re-enable select2 ────────────────────────────────────────
        $('#hedit').on('click', function () {
            setTimeout(function () {
                document.querySelectorAll('#dgrid tbody tr').forEach(function (tr) {
                    $(tr).find('select.product-sel').each(function () { $(this).prop('disabled', false).trigger('change.select2'); });
                });
                document.querySelectorAll('#chggrid tbody tr').forEach(function (tr) {
                    $(tr).find('select.chgexp-sel').each(function () { $(this).prop('disabled', false).trigger('change.select2'); });
                });
            }, 0);
        });

        // ── Search modal ───────────────────────────────────────────────────
        var srchPage = 1, srchPages = 1;
        function srchLoad(page) {
            srchPage = page;
            $.post(PEX_SEARCH_URL, { search: $('#srchInput').val(), page: page }, function (data) {
                $('#srchBody').html(data.rows);
                srchPage = data.page; srchPages = data.pages;
                $('#srchPageInfo').text('Page ' + srchPage + ' of ' + srchPages + ' (' + data.total + ' records)');
                $('#srchPrevBtn').prop('disabled', srchPage <= 1).css('opacity', srchPage <= 1 ? .5 : 1);
                $('#srchNextBtn').prop('disabled', srchPage >= srchPages).css('opacity', srchPage >= srchPages ? .5 : 1);
            }, 'json');
        }
        $('#srchGoBtn').on('click', function () { srchLoad(1); });
        $('#srchInput').on('keyup', function (e) { if (e.key === 'Enter') srchLoad(1); });
        $('#srchPrevBtn').on('click', function () { if (srchPage > 1) srchLoad(srchPage - 1); });
        $('#srchNextBtn').on('click', function () { if (srchPage < srchPages) srchLoad(srchPage + 1); });
        var searchModalEl = document.getElementById('searchModal');
        if (searchModalEl) searchModalEl.addEventListener('click', function (e) { if (e.target === this) this.style.display = 'none'; });
        var hsearchEl = document.getElementById('hsearch');
        if (hsearchEl) hsearchEl.addEventListener('click', function () { srchLoad(1); setTimeout(function () { document.getElementById('srchInput').focus(); }, 60); });
    });

})();
