/**
 * Slice 8Z-Vue · PC scrub surface — Vue 3 Options API.
 *
 * Mounts on #pc-scrub-root. Hydrates from window.__pcScrubData which the PHP view
 * emits with: { po, items, project_id, tender_id, hide_margin, can_edit, is_handed_over,
 *               proc_user_name, endpoints, price_label, group }.
 *
 * All CRUD calls update reactive state — no page reloads. Follows the local Vue
 * pattern (v-cloak + typeof Vue guard). Sits alongside the PHP-rendered scaffolding.
 */
(function () {
    if (typeof Vue === 'undefined') return;
    var mount = document.getElementById('pc-scrub-root');
    if (!mount) return;
    var boot = window.__pcScrubData || {};

    // Small helper — jQuery-confirm alert wrapper so we don't repeat.
    var alertFail = function (msg) { $.alert({ title: 'Something went wrong', content: msg || 'Server error', type: 'red' }); };
    var confirmDialog = function (title, content, type, onOk) {
        $.confirm({
            title: title, content: content, type: type,
            buttons: {
                confirm: { text: 'Confirm', btnClass: 'btn-' + (type === 'red' ? 'danger' : (type === 'orange' ? 'warning' : (type === 'green' ? 'success' : 'primary'))), action: onOk },
                cancel: function () {}
            }
        });
    };

    Vue.createApp({
        data: function () {
            return {
                po: boot.po || {},
                items: (boot.items || []).map(function (i) { return Object.assign({ _expanded: false, _saving: false }, i); }),
                overheads: (boot.overheads || []).slice(),
                // 8Z-b: newOverhead.amount seeds both `amount` (frozen estimate) and `amount_actual`
                // on insert; PC can then refine amount_actual on the row afterwards.
                newOverhead: { category: 'TRANSPORT', label: '', amount: 0, notes: '' },
                overheadCategories: ['TRANSPORT','HSE','INSURANCE','PACKAGING','WAREHOUSING','INSTALLATION','OTHER'],
                incoterms: ['EXW','FCA','CPT','CIP','DAP','DPU','DDP'],
                savingDelivery: false,
                projectId: boot.project_id || 0,
                tenderId: boot.tender_id || 0,
                hideMargin: !!boot.hide_margin,
                canEdit:    !!boot.can_edit,
                canHandover: !!boot.can_handover,
                isHandedOver: !!boot.is_handed_over,
                procUserName: boot.proc_user_name || '',
                priceLabel:   boot.price_label || 'Unit sell',
                endpoints:    boot.endpoints || {},
                newItem: {
                    description: '', brand: '', qty: 1, unit: '',
                    unit_price_sell: 0, margin_pct: (boot.po && boot.po.default_margin_pct) || 25,
                    source_pref: 'ANY', delivery_method: '', notes: ''
                },
                handoverNotes: '',
                busy: false,
                statusChip: {
                    PENDING:   { bg: '#F1F5F9', fg: '#334155', label: 'Pending' },
                    CONFIRMED: { bg: '#EAF2E8', fg: '#3F5C43', label: 'Confirmed' },
                    QUERIED:   { bg: '#FEF3E7', fg: '#8B6914', label: 'Queried' },
                    ACCEPTED:  { bg: '#E8EEF3', fg: '#7A8BA1', label: 'Accepted' }
                },
                sourcePill: {
                    LOCAL:  { bg: '#EAF2E8', fg: '#3D5B44', label: 'Local' },
                    IMPORT: { bg: '#F3E5D9', fg: '#6B3F2A', label: 'Import' },
                    ANY:    { bg: '#EDE7DC', fg: '#5B4F3C', label: 'Any' }
                },
                priorityColor: { LOW: '#94A3B8', MED: '#7A8BA1', HIGH: '#D4A574', CRITICAL: '#C48579' }
            };
        },
        computed: {
            itemsCount: function () { return this.items.length; },
            confirmedCount: function () {
                var n = 0; for (var i = 0; i < this.items.length; i++) if (this.items[i].item_status === 'CONFIRMED') n++;
                return n;
            },
            allConfirmed: function () { return this.itemsCount > 0 && this.confirmedCount === this.itemsCount; },
            subtotalSell: function () {
                var s = 0; for (var i = 0; i < this.items.length; i++) s += Number(this.items[i].line_total_sell || 0);
                return s;
            },
            activeOverheadCount: function () {
                var n = 0; for (var i = 0; i < this.overheads.length; i++) if (Number(this.overheads[i].active) === 1) n++;
                return n;
            },
            deliveryLocationOk: function () {
                if (this.po.delivery_mode === 'MULTI_LOCATION') return true;
                return !!(this.po.primary_delivery_location && String(this.po.primary_delivery_location).trim());
            },
            deliveryComplete: function () { return !!this.po.incoterm && this.deliveryLocationOk; },
            readyForHandover: function () {
                return this.allConfirmed && this.deliveryComplete && this.activeOverheadCount > 0;
            },
            /**
             * 8Z-c · Suggest an Incoterm from the current item source mix.
             *   any IMPORT → CIP  (supplier ships + insures; you clear customs at port)
             *   all LOCAL  → DAP  (supplier trucks to your site; you unload)
             *   mixed / empty / all ANY → DAP  (safe local default)
             */
            suggestedIncoterm: function () {
                if (!this.items.length) return 'DAP';
                var hasImport = false, hasLocal = false;
                for (var i = 0; i < this.items.length; i++) {
                    var s = String(this.items[i].source_pref || 'ANY').toUpperCase();
                    if (s === 'IMPORT') hasImport = true;
                    if (s === 'LOCAL')  hasLocal  = true;
                }
                if (hasImport) return 'CIP';
                if (hasLocal)  return 'DAP';
                return 'DAP';
            },
            headerChip: function () {
                if (this.isHandedOver) return { bg: '#7A8BA1', fg: '#fff', text: 'Handed over · Sourcing' };
                if (!this.itemsCount)  return null;
                var bg = this.allConfirmed ? '#EAF2E8' : '#F1F5F9';
                var fg = this.allConfirmed ? '#3F5C43' : '#334155';
                return { bg: bg, fg: fg, text: this.confirmedCount + ' / ' + this.itemsCount + ' confirmed' };
            }
        },
        mounted: function () {
            // 8Z-c · If PC hasn't picked an Incoterm yet, prefill from the item source mix.
            // Doesn't auto-save — PC still sees the suggestion in the dropdown, reviews, then clicks
            // "Save delivery" to commit.
            if (!this.isHandedOver && this.po && !this.po.incoterm) {
                this.po.incoterm = this.suggestedIncoterm;
            }
        },
        methods: {
            fmt: function (n) { return Number(n || 0).toLocaleString('en-US'); },
            fmtQty: function (n) { var s = Number(n || 0).toFixed(4); return s.replace(/\.?0+$/, ''); },
            overheadDelta: function (oh) {
                if (oh.amount_actual === null || oh.amount_actual === undefined || oh.amount_actual === '') return 0;
                return Number(oh.amount_actual) - Number(oh.amount || 0);
            },
            /**
             * 8Z-d · Open a reference modal explaining the 7 Incoterms + a "when to use which" guide.
             * Static content — no server round-trip. Reads naturally on a phone too (single-column table).
             */
            showIncotermHelp: function () {
                var rows = [
                    ['EXW', 'Ex Works',              'Just has the goods ready at their factory.',                          'Everything else — loading, freight, insurance, customs, delivery.'],
                    ['FCA', 'Free Carrier',          'Delivers to a named hub; handles export clearance.',                  'Freight from hub, insurance, import, delivery.'],
                    ['CPT', 'Carriage Paid To',      'Pays freight to destination. Risk passes at first carrier.',          'Insurance in transit + import clearance + unloading.'],
                    ['CIP', 'Carriage & Insurance',  'CPT + arranges insurance.',                                           'Import clearance + unloading.'],
                    ['DAP', 'Delivered At Place',    'Freight + insurance + risk all the way to your site.',                'Unload + import clearance + duties.'],
                    ['DPU', 'Delivered + Unloaded',  'Same as DAP but also unloads for you.',                               'Import clearance + duties.'],
                    ['DDP', 'Delivered Duty Paid',   'Absolutely everything — freight, insurance, duties, delivery.',       'Just receive the goods.']
                ];
                var body = '';
                for (var i = 0; i < rows.length; i++) {
                    var r = rows[i];
                    body += '<tr>' +
                        '<td style="width:60px;"><strong style="color:#7A8BA1;">' + r[0] + '</strong></td>' +
                        '<td style="width:140px;color:#334155;font-weight:500;font-size:.82rem;">' + r[1] + '</td>' +
                        '<td class="small" style="color:#3F5C43;font-size:.75rem;">' + r[2] + '</td>' +
                        '<td class="small" style="color:#8B6914;font-size:.75rem;">' + r[3] + '</td>' +
                        '</tr>';
                }
                var guide =
                    '<tr><td style="color:#94A3B8;text-transform:uppercase;font-size:.6rem;letter-spacing:.5px;">Item source</td>' +
                    '    <td colspan="3" style="color:#94A3B8;text-transform:uppercase;font-size:.6rem;letter-spacing:.5px;">Incoterm to pick</td></tr>' +
                    '<tr><td style="color:#334155;"><code>LOCAL</code></td>' +
                    '    <td colspan="3"><strong style="color:#3F5C43;">DAP</strong> <span class="text-muted small">(or DPU if unloading matters)</span></td></tr>' +
                    '<tr><td style="color:#334155;"><code>IMPORT</code></td>' +
                    '    <td colspan="3"><strong style="color:#8B6914;">CIP</strong> <span class="text-muted small">(or DDP for turnkey — most expensive)</span></td></tr>' +
                    '<tr><td style="color:#334155;"><code>ANY</code> / Mixed</td>' +
                    '    <td colspan="3"><strong style="color:#3F5C43;">DAP</strong> <span class="text-muted small">(safe default; adjust if items are mixed)</span></td></tr>';
                $.confirm({
                    title: '<i class="fas fa-info-circle me-1" style="color:#7A8BA1;"></i>Incoterms · quick reference',
                    columnClass: 'col-lg-9', boxWidth: '80%', useBootstrap: false,
                    content:
                        '<div class="small mb-2" style="font-size:.78rem;color:#64748B;">' +
                        'Incoterms (International Commercial Terms) split delivery responsibility between seller + buyer. ' +
                        'These are the 7 <em>multimodal</em> ones — they work for road / rail / air / sea. ' +
                        'Sea-only codes (FOB / CIF / FAS / CFR) intentionally not listed.' +
                        '</div>' +
                        '<div style="max-height:52vh;overflow:auto;">' +
                        '<table class="table table-sm mb-2 align-middle" style="background:#fff;">' +
                        '<thead style="background:#F1F5F9;">' +
                        '<tr><th style="color:#334155;">Code</th><th style="color:#334155;">Name</th>' +
                        '<th style="color:#3F5C43;">Seller does</th><th style="color:#8B6914;">Buyer does</th></tr>' +
                        '</thead><tbody>' + body + '</tbody></table>' +
                        '<div class="mt-3 mb-1"><strong style="color:#334155;font-size:.85rem;">' +
                        '<i class="fas fa-magic me-1" style="color:#7A9E7E;"></i>Quick pick guide</strong></div>' +
                        '<table class="table table-sm mb-0 align-middle" style="background:#F8FAFC;">' +
                        '<tbody>' + guide + '</tbody></table>' +
                        '</div>',
                    buttons: {
                        close: { text: 'Got it', btnClass: 'btn-primary' }
                    }
                });
            },
            // ── CRUD (all update local state; no reload) ────────────────────
            addItem: function () {
                var self = this;
                if (!self.newItem.description.trim()) { alertFail('Description required.'); return; }
                self.busy = true;
                $.post(self.endpoints.add, Object.assign({ project_id: self.projectId }, self.newItem), function (r) {
                    self.busy = false;
                    if (!r || !r.ok) return alertFail(r && r.msg);
                    // If this is the first item, we now have a po_id — remember it.
                    if (!self.po.c0d && r.po_id) self.po.c0d = r.po_id;
                    self.items.push({
                        c0d: r.id, item_no: self.items.length + 1, item_status: 'PENDING',
                        description: self.newItem.description, brand: self.newItem.brand,
                        source_pref: self.newItem.source_pref, delivery_method: self.newItem.delivery_method,
                        qty: self.newItem.qty, unit: self.newItem.unit,
                        unit_price_sell: self.newItem.unit_price_sell, margin_pct: self.newItem.margin_pct,
                        line_total_sell: Number(self.newItem.qty) * Number(self.newItem.unit_price_sell),
                        notes: self.newItem.notes,
                        priority: 'MED', alt_ok: 1, alt_note: '', deliver_by: '', deliver_to: '', scrub_remarks: '',
                        _expanded: false, _saving: false
                    });
                    // Reset form
                    self.newItem = Object.assign({}, self.newItem, { description: '', brand: '', qty: 1, unit: '', unit_price_sell: 0, notes: '' });
                    rsToast('Item added.', 'success');
                }, 'json').fail(function () { self.busy = false; alertFail('Network error'); });
            },
            removeItem: function (it) {
                var self = this;
                confirmDialog('Remove item?', 'This deletes the line from the DRAFT PO.', 'orange', function () {
                    $.post(self.endpoints.remove, { po_id: self.po.c0d, item_id: it.c0d }, function (r) {
                        if (!r || !r.ok) return alertFail(r && r.msg);
                        self.items = self.items.filter(function (x) { return x.c0d !== it.c0d; });
                        rsToast('Removed.', 'success');
                    }, 'json').fail(function () { alertFail('Network error'); });
                });
            },
            toggleExpand: function (it) {
                if (!this.canEdit || this.isHandedOver) return;
                it._expanded = !it._expanded;
            },
            saveDetails: function (it) {
                var self = this;
                it._saving = true;
                $.post(self.endpoints.update, {
                    po_id: self.po.c0d, item_id: it.c0d,
                    brand: it.brand, priority: it.priority,
                    alt_ok: it.alt_ok, alt_note: it.alt_note,
                    deliver_by: it.deliver_by, deliver_to: it.deliver_to,
                    scrub_remarks: it.scrub_remarks,
                    sourcing_ceiling: it.unit_price_sell
                }, function (r) {
                    it._saving = false;
                    if (!r || !r.ok) return alertFail(r && r.msg);
                    // Server recomputed line_total_sell — mirror it locally.
                    it.line_total_sell = Number(it.qty) * Number(it.unit_price_sell);
                    rsToast('Saved.', 'success');
                }, 'json').fail(function () { it._saving = false; alertFail('Network error'); });
            },
            confirmItem: function (it) {
                var self = this;
                $.post(self.endpoints.confirm, { po_id: self.po.c0d, item_id: it.c0d }, function (r) {
                    if (!r || !r.ok) return alertFail(r && r.msg);
                    it.item_status = 'CONFIRMED';
                    rsToast('Confirmed.', 'success');
                }, 'json').fail(function () { alertFail('Network error'); });
            },
            unconfirmItem: function (it) {
                var self = this;
                $.post(self.endpoints.unconfirm, { po_id: self.po.c0d, item_id: it.c0d }, function (r) {
                    if (!r || !r.ok) return alertFail(r && r.msg);
                    it.item_status = 'PENDING';
                    rsToast('Reverted to pending.', 'success');
                }, 'json').fail(function () { alertFail('Network error'); });
            },
            convertScope: function () {
                var self = this;
                if (!self.tenderId) return alertFail('No source tender on this project.');
                confirmDialog('Convert tender scope → Client PO?', 'Clones tender items. Existing lines with the same description are skipped.', 'green', function () {
                    $.post(self.endpoints.convert, { project_id: self.projectId, tender_id: self.tenderId }, function (r) {
                        if (!r || !r.ok) return alertFail(r && r.msg);
                        rsToast(r.msg || 'Cloned.', 'success');
                        // Bulk insert — refetch items list. Since we have no dedicated list endpoint,
                        // fetch fresh state by hitting the same view via a soft-reload so PHP re-hydrates.
                        setTimeout(function () { location.reload(); }, 500);
                    }, 'json').fail(function () { alertFail('Network error'); });
                });
            },
            importXlsx: function () {
                var self = this;
                if (typeof XLSX === 'undefined') return alertFail('SheetJS missing (js/Olibs/xlsx.full.min.js).');
                var fileEl = self.$refs.importFile;
                if (!fileEl || !fileEl.files || !fileEl.files.length) return alertFail('Pick a spreadsheet first.');
                var f = fileEl.files[0];
                var reader = new FileReader();
                reader.onload = function (e) {
                    try {
                        var data = new Uint8Array(e.target.result);
                        var wb   = XLSX.read(data, { type: 'array' });
                        var ws   = wb.Sheets[wb.SheetNames[0]];
                        var rows = XLSX.utils.sheet_to_json(ws, { defval: '' });
                        if (!rows.length) return alertFail('No rows found in the first sheet.');
                        var head = '<tr>' + Object.keys(rows[0]).map(function (k) { return '<th style="font-size:.7rem;">' + k + '</th>'; }).join('') + '</tr>';
                        var body = rows.slice(0, 25).map(function (r) {
                            return '<tr>' + Object.keys(rows[0]).map(function (k) { return '<td style="font-size:.75rem;">' + (r[k] == null ? '' : String(r[k])) + '</td>'; }).join('') + '</tr>';
                        }).join('');
                        $.confirm({
                            title: 'Preview ' + rows.length + ' row(s)',
                            columnClass: 'col-lg-11', boxWidth: '90%', useBootstrap: false,
                            content:
                                '<div class="alert alert-info small mb-2" style="font-size:.72rem;">First 25 shown. Required: <code>description</code>. Optional: qty, unit, unit_price_sell, margin_pct, brand, source_pref, notes.</div>' +
                                '<div style="max-height:50vh;overflow:auto;"><table class="table table-sm mb-0"><thead style="background:#F1F5F9;">' + head + '</thead><tbody>' + body + '</tbody></table></div>',
                            buttons: {
                                confirm: { text: 'Import ' + rows.length + ' row(s)', btnClass: 'btn-primary', action: function () {
                                    $.post(self.endpoints.import, { project_id: self.projectId, rows: JSON.stringify(rows) }, function (r) {
                                        if (!r || !r.ok) return alertFail(r && r.msg);
                                        rsToast(r.msg || 'Imported.', 'success');
                                        setTimeout(function () { location.reload(); }, 500);
                                    }, 'json').fail(function () { alertFail('Network error'); });
                                }},
                                cancel: function () {}
                            }
                        });
                    } catch (err) { alertFail('Could not read the file: ' + err.message); }
                };
                reader.readAsArrayBuffer(f);
            },
            handover: function () {
                var self = this;
                if (!self.allConfirmed) return alertFail('Confirm every item before handover.');
                confirmDialog(
                    'Hand over to Procurement?',
                    'PO status flips to SOURCING, items become read-only, and ' + (self.procUserName || 'Procurement') + ' will be notified.',
                    'blue',
                    function () {
                        $.post(self.endpoints.handover, { po_id: self.po.c0d, notes: self.handoverNotes }, function (r) {
                            if (!r || !r.ok) return alertFail(r && r.msg);
                            rsToast(r.msg || 'Handed over.', 'success');
                            self.isHandedOver = true;
                            self.po.status = 'SOURCING';
                            self.po.handover_at         = new Date().toISOString().slice(0, 19).replace('T', ' ');
                            self.po.handover_by_name    = boot.current_user_name || '';
                            self.po.handover_notes      = self.handoverNotes;
                            self.handoverNotes = '';
                        }, 'json').fail(function () { alertFail('Network error'); });
                    }
                );
            },
            submitForApproval: function () {
                var self = this;
                if (!self.itemsCount) return alertFail('Add items first.');
                confirmDialog('Submit for approval?', 'Sends the PO into FM → Exec → PM approval chain.', 'green', function () {
                    $.post(self.endpoints.submit, { project_id: self.projectId }, function (r) {
                        if (!r || !r.ok) return alertFail(r && r.msg);
                        rsToast('Submitted for approval.', 'success');
                        setTimeout(function () { location.reload(); }, 500);
                    }, 'json').fail(function () { alertFail('Network error'); });
                });
            },
            // ── Delivery block ─────────────────────────────────────────────
            saveDelivery: function () {
                var self = this;
                if (!self.po || !self.po.c0d) return alertFail('No PO to save against.');
                self.savingDelivery = true;
                $.post(self.endpoints.saveDelivery, {
                    po_id: self.po.c0d,
                    delivery_mode:                 self.po.delivery_mode,
                    primary_delivery_location:     self.po.primary_delivery_location || '',
                    delivery_contact_name:         self.po.delivery_contact_name || '',
                    delivery_contact_phone:        self.po.delivery_contact_phone || '',
                    incoterm:                      self.po.incoterm || '',
                    delivery_deadline:             self.po.delivery_deadline || '',
                    delivery_special_instructions: self.po.delivery_special_instructions || ''
                }, function (r) {
                    self.savingDelivery = false;
                    if (!r || !r.ok) return alertFail(r && r.msg);
                    rsToast('Delivery saved.', 'success');
                }, 'json').fail(function () { self.savingDelivery = false; alertFail('Network error'); });
            },
            // ── Overheads carry-over ───────────────────────────────────────
            seedOverheads: function () {
                var self = this;
                if (!self.tenderId) return alertFail('No source tender on this project.');
                confirmDialog('Seed overheads from tender?', 'Clones every pricing_version_overheads row from the approved tender pricing. Idempotent — safe to re-run.', 'green', function () {
                    $.post(self.endpoints.overheadSeed, { project_id: self.projectId, po_id: self.po.c0d || null, tender_id: self.tenderId }, function (r) {
                        if (!r || !r.ok) return alertFail(r && r.msg);
                        rsToast(r.msg || 'Seeded.', 'success');
                        setTimeout(function () { location.reload(); }, 500);
                    }, 'json').fail(function () { alertFail('Network error'); });
                });
            },
            addOverhead: function () {
                var self = this;
                if (!self.newOverhead.label.trim()) return alertFail('Overhead label required.');
                $.post(self.endpoints.overheadAdd, {
                    project_id: self.projectId, po_id: self.po.c0d || null,
                    category: self.newOverhead.category,
                    label:    self.newOverhead.label,
                    amount:   self.newOverhead.amount,
                    notes:    self.newOverhead.notes
                }, function (r) {
                    if (!r || !r.ok) return alertFail(r && r.msg);
                    self.overheads.push({
                        c0d: r.id, category: self.newOverhead.category,
                        label: self.newOverhead.label,
                        amount: self.newOverhead.amount,
                        amount_actual: self.newOverhead.amount,
                        notes: self.newOverhead.notes, source: 'PC_ADDED', active: 1
                    });
                    self.newOverhead = { category: 'TRANSPORT', label: '', amount: 0, notes: '' };
                    rsToast('Overhead added.', 'success');
                }, 'json').fail(function () { alertFail('Network error'); });
            },
            saveOverhead: function (oh) {
                // 8Z-b: `amount` is frozen server-side — we only send amount_actual + editable fields.
                $.post(this.endpoints.overheadUpdate, {
                    id: oh.c0d, category: oh.category, label: oh.label,
                    amount_actual: oh.amount_actual === null || oh.amount_actual === undefined ? '' : oh.amount_actual,
                    notes: oh.notes, active: oh.active
                }, function (r) {
                    if (!r || !r.ok) return alertFail(r && r.msg);
                }, 'json').fail(function () { alertFail('Network error'); });
            },
            toggleOverhead: function (oh, active) {
                oh.active = active ? 1 : 0;
                this.saveOverhead(oh);
            },
            removeOverhead: function (oh) {
                var self = this;
                confirmDialog('Remove overhead?', 'This soft-deletes the line. Audit trail preserved.', 'orange', function () {
                    $.post(self.endpoints.overheadDelete, { id: oh.c0d }, function (r) {
                        if (!r || !r.ok) return alertFail(r && r.msg);
                        self.overheads = self.overheads.filter(function (x) { return x.c0d !== oh.c0d; });
                        rsToast('Removed.', 'success');
                    }, 'json').fail(function () { alertFail('Network error'); });
                });
            }
        }
    }).mount('#pc-scrub-root');
})();
