(function() {
    var cfg = window.paintopsAddExpenseCfg || {};

    // Same "+ New Vendor reveals a text box" behavior as the full
    // Financials expense table.
    document.addEventListener('change', function(e) {
        if (e.target.id !== 'workerVendorSelect') return;
        var otherInput = document.getElementById('workerVendorOther');
        if (!otherInput) return;
        if (e.target.value === '__new__') {
            otherInput.style.display = '';
            otherInput.focus();
        } else {
            otherInput.style.display = 'none';
            otherInput.value = '';
        }
    });

    // Live fuel hint (warn-but-allow). Same regex as the PHP guard,
    // injected from paintops_fuel_pattern() so they can't drift. The
    // server-side bounce in paintops_save_worker_expense_receipt()
    // remains the backstop; this just surfaces the warning while the
    // lead is still on the field. Re-checked on submit because the AI
    // receipt scan fills the vendor programmatically (no input events).
    var fuelRe = new RegExp(cfg.fuelPattern, 'i');
    function paintopsFuelVendorValue() {
        var sel = document.getElementById('workerVendorSelect');
        var other = document.getElementById('workerVendorOther');
        if (sel && sel.value === '__new__') { return other ? other.value : ''; }
        return sel ? sel.value : '';
    }
    function paintopsFuelCheck() {
        var hint = document.getElementById('workerFuelHint');
        var row = document.getElementById('workerFuelOkRow');
        var isFuel = fuelRe.test(paintopsFuelVendorValue());
        if (hint) { hint.style.display = isFuel ? 'block' : 'none'; }
        if (row && isFuel) { row.style.display = ''; }
    }
    ['change', 'input'].forEach(function (evt) {
        document.addEventListener(evt, function (e) {
            if (e.target && (e.target.id === 'workerVendorSelect' || e.target.id === 'workerVendorOther')) {
                paintopsFuelCheck();
            }
        });
    });
    var fuelForm = document.getElementById('workerAddReceiptForm');
    if (fuelForm) {
        fuelForm.addEventListener('submit', paintopsFuelCheck);
    }

    if (cfg.aiAvailable) {
        var aiControls = document.getElementById('workerAiReceiptControls');
        var aiStatus = document.getElementById('workerAiReceiptStatus');
        var aiBtn = document.getElementById('workerAiAnalyzeBtn');
        var ajaxUrl = cfg.ajaxUrl;
        var aiNonce = cfg.scanNonce;
        var jobId = cfg.jobId;

        // AI-first chooser (2026-07-25, mirrors the Vehicle Log's
        // "Scan Receipt with AI" / "Manually Enter" buttons): Scan opens the
        // receipt picker immediately and, once a photo is chosen, both
        // reveals the form and runs the scan automatically, no separate tap
        // on Analyze needed. Manually Enter just reveals the empty form; the
        // in-form Analyze button (below) still works either way, so someone
        // who started manual can still scan, and someone who scanned can
        // still re-scan.
        var chooser = document.getElementById('workerAddChooser');
        var addForm = document.getElementById('workerAddReceiptForm');
        var scanChoice = document.getElementById('workerScanChoice');
        var manualChoice = document.getElementById('workerManualChoice');
        var pendingScan = false;

        // Progressive enhancement: the PHP renders the form VISIBLE and the
        // chooser HIDDEN (so no-JS users can always submit). With JS running,
        // flip to the chooser-first flow.
        if (chooser && addForm) {
            chooser.style.display = '';
            addForm.style.display = 'none';
        }

        function showAddForm() {
            if (chooser) chooser.style.display = 'none';
            if (addForm) addForm.style.display = '';
        }

        // The Analyze row stays HIDDEN until a receipt image is actually
        // captured or selected (Mike 2026-07-22), and a PDF keeps it hidden,
        // the scan reads photos only. The click handler's PDF guard stays as
        // the backstop.
        var aiFileInput = document.getElementById('workerReceiptFile');
        if (aiFileInput && aiControls) {
            aiFileInput.addEventListener('change', function() {
                showAddForm();
                var f = aiFileInput.files && aiFileInput.files[0];
                var isPdf = !!(f && f.type === 'application/pdf');
                var showAi = !!(f && !isPdf);
                aiControls.style.display = showAi ? '' : 'none';
                if (!showAi && aiStatus) { aiStatus.textContent = ''; }
                if (pendingScan) {
                    pendingScan = false;
                    if (isPdf) {
                        // Chose "Scan Receipt with AI" but picked a PDF, the
                        // scan reads photos only; say so instead of silently
                        // doing nothing.
                        if (aiStatus) {
                            aiStatus.style.color = '#8a5a00';
                            aiStatus.textContent = 'AI scan works on photos; this PDF will attach without scanning, just fill the fields in.';
                        }
                    } else if (f) {
                        scanReceipt();
                    }
                }
            });
        }

        if (scanChoice) { scanChoice.addEventListener('click', function(){ pendingScan = true; if (aiFileInput) aiFileInput.click(); }); }
        if (manualChoice) { manualChoice.addEventListener('click', function(){ showAddForm(); }); }

        function fillVendor(name) {
            var select = document.getElementById('workerVendorSelect');
            var other = document.getElementById('workerVendorOther');
            if (!select || !name) return;
            var matched = false;
            for (var i = 0; i < select.options.length; i++) {
                if (select.options[i].value.toLowerCase() === name.toLowerCase()) {
                    select.value = select.options[i].value;
                    matched = true;
                    break;
                }
            }
            if (!matched) {
                select.value = '__new__';
                if (other) {
                    other.style.display = '';
                    other.value = name;
                }
            } else if (other) {
                other.style.display = 'none';
                other.value = '';
            }
        }

        function scanReceipt() {
            var fileInput = document.getElementById('workerReceiptFile');
            if (!fileInput || !fileInput.files || !fileInput.files[0]) {
                aiStatus.style.color = '#a94442';
                aiStatus.textContent = 'Choose or take a receipt photo first.';
                return;
            }
            // PDF receipts attach fine but the AI scan reads photos
            // (2026-07-22); say so instead of a server error.
            if (fileInput.files[0].type === 'application/pdf') {
                aiStatus.style.color = '#8a5a00';
                aiStatus.textContent = 'AI scan works on photos; PDF receipts attach without scanning, just fill the fields in.';
                return;
            }

            var formData = new FormData();
            formData.append('action', 'paintops_ai_scan_receipt');
            formData.append('nonce', aiNonce);
            formData.append('job_id', jobId);
            formData.append('ai_receipt', fileInput.files[0]);

            if (aiBtn) aiBtn.disabled = true;
            aiStatus.style.color = '#555';
            aiStatus.textContent = 'Analyzing receipt... this can take up to 30 seconds.';

            fetch(ajaxUrl, { method: 'POST', body: formData, credentials: 'same-origin' })
                .then(function(res) { return res.json(); })
                .then(function(json) {
                    if (aiBtn) aiBtn.disabled = false;
                    if (!json.success) {
                        aiStatus.style.color = '#a94442';
                        aiStatus.textContent = (json.data && json.data.message) ? json.data.message : 'Something went wrong, please try again.';
                        return;
                    }
                    var data = json.data;
                    // The scan authoritatively fills the category, so lock
                    // out the vendor-based auto-suggest below from overriding it.
                    categoryLocked = true;
                    if (data.vendor) fillVendor(data.vendor);
                    if (data.category) {
                        var catSelect = document.getElementById('workerCategorySelect');
                        if (catSelect) {
                            for (var j = 0; j < catSelect.options.length; j++) {
                                if (catSelect.options[j].value === data.category) {
                                    catSelect.value = data.category;
                                    break;
                                }
                            }
                        }
                    }
                    if (data.total_amount) {
                        var amountInput = document.getElementById('workerAmountInput');
                        if (amountInput) amountInput.value = Number(data.total_amount).toFixed(2);
                    }
                    if (data.purchase_date) {
                        var dateInput = document.getElementById('workerDateInput');
                        if (dateInput && /^\d{4}-\d{2}-\d{2}$/.test(data.purchase_date)) dateInput.value = data.purchase_date;
                    }
                    // Green = filled in clean. AMBER (not red) when the
                    // AI added a caveat note (Mike 2026-07-23: a benign
                    // "date partially blurred" caveat was painting a
                    // perfect fill alarm-red; red now only means the
                    // scan actually FAILED, handled above).
                    aiStatus.style.color = data.notes ? '#8a5a00' : 'green';
                    aiStatus.textContent = 'Details filled in, double-check before saving.' + (data.notes ? ' Note: ' + data.notes : '');
                })
                .catch(function() {
                    if (aiBtn) aiBtn.disabled = false;
                    aiStatus.style.color = '#a94442';
                    aiStatus.textContent = 'Could not reach the server, check your connection and try again.';
                });
        }

        if (aiBtn) { aiBtn.addEventListener('click', scanReceipt); }
    }

    // --- Auto-categorize the expense from the vendor (no photo needed) ---
    // Runs a free keyword match server-side first, falling back to a
    // cheap AI text call only when the vendor isn't recognized (and only
    // if Pro + OpenAI). Never overrides a category the user set by hand or
    // that a receipt scan already filled (categoryLocked).
    var categoryLocked = false;
    var catSelectEl = document.getElementById('workerCategorySelect');
    var catSuggestUrl = cfg.ajaxUrl;
    var catSuggestNonce = cfg.catNonce;
    var catSuggestJobId = cfg.jobId;
    var catHint = null;
    if (catSelectEl && catSelectEl.parentNode) {
        catHint = document.createElement('span');
        catHint.style.cssText = 'margin-left:8px;font-size:12px;color:#1a7a43;';
        catSelectEl.parentNode.appendChild(catHint);
        catSelectEl.addEventListener('change', function(){ categoryLocked = true; if (catHint) catHint.textContent = ''; });
    }
    function suggestExpenseCategory(vendorText) {
        vendorText = (vendorText || '').trim();
        if (!vendorText || categoryLocked || !catSelectEl) return;
        var b = new URLSearchParams();
        b.append('action', 'paintops_ai_suggest_expense_category');
        b.append('nonce', catSuggestNonce);
        b.append('job_id', catSuggestJobId);
        b.append('vendor', vendorText);
        fetch(catSuggestUrl, {method:'POST', body:b, credentials:'same-origin'}).then(function(r){ return r.json(); }).then(function(res){
            if (!res || !res.success || !res.data || !res.data.category || categoryLocked) return;
            var cat = res.data.category, set = false;
            for (var i = 0; i < catSelectEl.options.length; i++) {
                if (catSelectEl.options[i].value === cat) { catSelectEl.value = cat; set = true; break; }
            }
            if (set && catHint) { catHint.textContent = (res.data.source === 'ai') ? '· AI-suggested, change if needed' : '· auto-set, change if needed'; }
        }).catch(function(){});
    }
    document.addEventListener('change', function(e) {
        if (e.target.id === 'workerVendorSelect' && e.target.value && e.target.value !== '__new__') {
            suggestExpenseCategory(e.target.value);
        }
    });
    var vendorOtherEl = document.getElementById('workerVendorOther');
    if (vendorOtherEl) {
        vendorOtherEl.addEventListener('blur', function(){ suggestExpenseCategory(vendorOtherEl.value); });
    }
})();
