/**
 * Pacific Logistics · Dispatch Board (Vue 3 Options API)
 *
 * Kanban board with 4 columns — Approved requests → Dispatched → In Transit → Delivered.
 * Each action POSTs to the server and re-fetches board data on success.
 * All modals are jQuery-confirm dialogs (localised, no CDN).
 */
(function () {
    const boot = window.__pacificDispatch || {};

    Vue.createApp({
        data() {
            return {
                proot:            boot.proot,
                csrf:             boot.csrf,
                approvedRequests: boot.board.approved_requests || [],
                dispatched:       boot.board.dispatched        || [],
                inTransit:        boot.board.in_transit        || [],
                delivered:        boot.board.delivered         || [],
                drivers:          boot.drivers                 || [],
                trucks:           boot.trucks                  || [],
                loading:          false,
            };
        },
        methods: {
            /* ── Utilities ─────────────────────────────────── */
            esc(s) {
                return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
            },
            priorityClass(p) {
                return {
                    urgent: 'bg-danger text-white',
                    high:   'bg-warning text-dark',
                    normal: 'bg-light text-muted border',
                    low:    'bg-light text-muted border'
                }[p] || 'bg-light text-muted';
            },
            toast(kind, msg) {
                if (window.rsToast) {
                    (kind === 'success' ? rsToast.success : rsToast.error)(msg);
                } else {
                    $.alert({ title: kind === 'success' ? 'OK' : 'Error', content: msg, type: kind === 'success' ? 'green' : 'red' });
                }
            },

            /* ── Data refresh ──────────────────────────────── */
            async refresh() {
                this.loading = true;
                try {
                    const res = await fetch(this.proot + 'Trips/boardDataAj', {
                        headers: { 'Accept': 'application/json' },
                        credentials: 'same-origin'
                    });
                    const j = await res.json();
                    if (j.ok) {
                        this.approvedRequests = j.board.approved_requests || [];
                        this.dispatched       = j.board.dispatched        || [];
                        this.inTransit        = j.board.in_transit        || [];
                        this.delivered        = j.board.delivered         || [];
                        this.drivers          = j.drivers                 || [];
                        this.trucks           = j.trucks                  || [];
                    }
                } catch (e) {
                    this.toast('error', 'Refresh failed: ' + e.message);
                } finally {
                    this.loading = false;
                }
            },

            /* ── POST action + re-fetch on success ─────────── */
            async postAction(url, body, successMsg) {
                const fd = new FormData();
                fd.append('csrf_token', this.csrf);
                for (const [k, v] of Object.entries(body || {})) fd.append(k, v);
                try {
                    const res = await fetch(url, {
                        method: 'POST',
                        headers: { 'Accept': 'application/json' },
                        credentials: 'same-origin',
                        body: fd
                    });
                    const j = await res.json();
                    if (j.ok) {
                        this.toast('success', j.msg || successMsg);
                        await this.refresh();
                        return true;
                    } else {
                        $.alert({ title: 'Action failed', content: j.msg || 'Something went wrong.', type: 'red' });
                        return false;
                    }
                } catch (e) {
                    $.alert({ title: 'Network error', content: e.message, type: 'red' });
                    return false;
                }
            },

            /* ── Column 1 → 2: Dispatch a request as a trip ── */
            openDispatch(req) {
                const self = this;
                const driverOpts = this.drivers.map(d =>
                    `<option value="${d.c0d}">${self.esc(d.full_name)}${d.employee_no ? ' · ' + self.esc(d.employee_no) : ''}</option>`
                ).join('');
                const truckOpts = this.trucks.map(t =>
                    `<option value="${t.c0d}">${self.esc(t.reg_no)}${(t.make || t.model) ? ' · ' + self.esc((t.make || '') + ' ' + (t.model || '')) : ''}</option>`
                ).join('');

                $.confirm({
                    title: `<i class="fas fa-truck-loading me-2"></i>Dispatch ${self.esc(req.request_no)}`,
                    content: `
                        <div class="mb-2 small">
                          <strong>${self.esc(req.customer_name || 'Internal')}</strong><br>
                          <span class="text-muted">${self.esc(req.cargo_description || '—')}</span>
                        </div>
                        <label class="form-label small mb-1">Driver <span class="text-danger">*</span></label>
                        <select id="dispDriver" class="form-select form-select-sm mb-2" required>
                            <option value="">— select —</option>${driverOpts}
                        </select>
                        <label class="form-label small mb-1">Truck <span class="text-danger">*</span></label>
                        <select id="dispTruck" class="form-select form-select-sm mb-2" required>
                            <option value="">— select —</option>${truckOpts}
                        </select>
                        <label class="form-label small mb-1">Notes (optional)</label>
                        <textarea id="dispNotes" class="form-control form-control-sm" rows="2" placeholder="Any dispatch instructions to log with the trip"></textarea>
                    `,
                    type: 'blue',
                    columnClass: 'medium',
                    buttons: {
                        dispatch: {
                            text: '<i class="fas fa-truck-loading me-1"></i>Dispatch trip',
                            btnClass: 'btn-primary',
                            action: async function () {
                                const did   = document.getElementById('dispDriver').value;
                                const tid   = document.getElementById('dispTruck').value;
                                const notes = document.getElementById('dispNotes').value;
                                if (!did || !tid) { $.alert({ title: 'Missing selection', content: 'Both driver and truck are required.', type: 'orange' }); return false; }
                                await self.postAction(self.proot + 'Trips/dispatch/' + req.c0d,
                                    { driver_id: did, truck_id: tid, notes: notes },
                                    'Trip dispatched.');
                            }
                        },
                        cancel: function () {}
                    }
                });
            },

            /* ── Column 2 → 3: Driver started ── */
            startTrip(t) {
                const self = this;
                $.confirm({
                    title: `Start ${self.esc(t.trip_no)}?`,
                    content: `
                        <div class="mb-2 small text-muted">${self.esc(t.driver_name || '?')} · ${self.esc(t.truck_reg || '?')}</div>
                        <label class="form-label small mb-1">Odometer at start (km)</label>
                        <input type="text" id="startOdo" class="form-control form-control-sm" placeholder="Optional but recommended">
                    `,
                    type: 'blue',
                    onContentReady: function () {
                        const el = document.getElementById('startOdo');
                        if (el && typeof Cleave !== 'undefined') new Cleave(el, { numeral: true, numeralThousandsGroupStyle: 'thousand', numeralDecimalScale: 0 });
                    },
                    buttons: {
                        start: {
                            text: '<i class="fas fa-play me-1"></i>Start trip',
                            btnClass: 'btn-primary',
                            action: async function () {
                                const odo = document.getElementById('startOdo').value.replace(/,/g, '');
                                await self.postAction(self.proot + 'Trips/start/' + t.c0d, { odometer_start: odo }, 'Trip started.');
                            }
                        },
                        cancel: function () {}
                    }
                });
            },

            /* ── Column 3 → 4: Mark delivered ── */
            deliverTrip(t) {
                const self = this;
                $.confirm({
                    title: `Mark ${self.esc(t.trip_no)} delivered?`,
                    content: `<div class="small">Cargo has been dropped off. The trip moves to <strong>Delivered</strong> awaiting close-out paperwork.</div>`,
                    type: 'orange',
                    buttons: {
                        deliver: {
                            text: '<i class="fas fa-flag-checkered me-1"></i>Mark delivered',
                            btnClass: 'btn-warning',
                            action: async function () {
                                await self.postAction(self.proot + 'Trips/deliver/' + t.c0d, {}, 'Marked delivered.');
                            }
                        },
                        cancel: function () {}
                    }
                });
            },

            /* ── Column 4 → out: Close trip with final numbers ── */
            closeTrip(t) {
                const self = this;
                const quoteAmt = t.quote_amount || '';
                $.confirm({
                    title: `Close ${self.esc(t.trip_no)}`,
                    content: `
                        <div class="mb-2 small text-muted">Final paperwork. Trip closes and cost is booked.</div>
                        <label class="form-label small mb-1">Odometer at end (km)</label>
                        <input type="text" id="closeOdo" class="form-control form-control-sm mb-2">
                        <label class="form-label small mb-1">Invoice amount (${self.esc(t.currency || 'TZS')})</label>
                        <input type="text" id="closeInv" class="form-control form-control-sm mb-2" value="${quoteAmt}">
                        <label class="form-label small mb-1">Notes</label>
                        <textarea id="closeNotes" class="form-control form-control-sm" rows="2" placeholder="Anything worth recording on trip close"></textarea>
                    `,
                    type: 'green',
                    onContentReady: function () {
                        const odo = document.getElementById('closeOdo');
                        const inv = document.getElementById('closeInv');
                        if (typeof Cleave !== 'undefined') {
                            if (odo) new Cleave(odo, { numeral: true, numeralThousandsGroupStyle: 'thousand', numeralDecimalScale: 0 });
                            if (inv) new Cleave(inv, { numeral: true, numeralThousandsGroupStyle: 'thousand', numeralDecimalScale: 2 });
                        }
                    },
                    buttons: {
                        closeIt: {
                            text: '<i class="fas fa-check-double me-1"></i>Close trip',
                            btnClass: 'btn-success',
                            action: async function () {
                                await self.postAction(self.proot + 'Trips/close/' + t.c0d, {
                                    odometer_end:   document.getElementById('closeOdo').value.replace(/,/g, ''),
                                    invoice_amount: document.getElementById('closeInv').value.replace(/,/g, ''),
                                    notes:          document.getElementById('closeNotes').value
                                }, 'Trip closed.');
                            }
                        },
                        cancel: function () {}
                    }
                });
            },
        }
    }).mount('#dispatchBoard');
})();
