/**
 * purchase-orders.js
 * Handles dynamic line-item management for Purchase Order Create/Edit forms.
 * A single searchable text input per row: type to filter inventory items or
 * enter a free-text description. Selecting an inventory item stores its ID in
 * a hidden field; typing something custom leaves the hidden field empty.
 */

'use strict';

let inventoryData = [];
let itemIndex = 0;

document.addEventListener('DOMContentLoaded', () => {
    const dataEl = document.getElementById('inventoryItemsData');
    if (dataEl) {
        try { inventoryData = JSON.parse(dataEl.textContent); } catch (e) { inventoryData = []; }
    }

    const tbody = document.getElementById('lineItemsBody');
    if (tbody) {
        itemIndex = tbody.querySelectorAll('tr[data-index]').length;
    }

    updateTotals();
});

// ─── Add / Remove rows ────────────────────────────────────────────────────────

function addItem() {
    const tbody = document.getElementById('lineItemsBody');
    if (!tbody) return;

    const i = itemIndex++;
    const tr = document.createElement('tr');
    tr.setAttribute('data-index', i);
    tr.innerHTML = buildRowHtml(i, {});
    tbody.appendChild(tr);
    toggleEmptyMessage();
    updateTotals();

    tr.querySelector('.item-search-input')?.focus();
}

function removeItem(btn) {
    const tr = btn.closest('tr');
    if (tr) {
        tr.remove();
        reindexRows();
        updateTotals();
        toggleEmptyMessage();
    }
}

function reindexRows() {
    const rows = document.querySelectorAll('#lineItemsBody tr[data-index]');
    rows.forEach((tr, newIndex) => {
        tr.setAttribute('data-index', newIndex);
        tr.querySelectorAll('[name]').forEach(el => {
            el.name = el.name.replace(/Items\[\d+\]/, `Items[${newIndex}]`);
        });
        const searchInput = tr.querySelector('.item-search-input');
        if (searchInput) {
            searchInput.setAttribute('data-row-index', newIndex);
            searchInput.setAttribute('oninput', `onItemSearch(this, ${newIndex})`);
        }
    });
    itemIndex = rows.length;
}

// ─── Row HTML builder ─────────────────────────────────────────────────────────

/**
 * opts: { type: 'inventory'|'custom', selectedId, description, qty, cost, notes }
 */
function buildRowHtml(i, opts = {}) {
    const isInventory = opts.type === 'inventory' && opts.selectedId;
    const qty         = opts.qty  ?? 1;
    const cost        = opts.cost ?? 0;
    const notes       = opts.notes ?? '';
    const lineTotal   = (qty * cost).toFixed(2);

    let displayText = '';
    if (isInventory) {
        const inv = inventoryData.find(x => String(x.value) === String(opts.selectedId));
        displayText = inv ? inv.text : (opts.description || '');
    } else {
        displayText = opts.description || '';
    }

    return `
        <td style="min-width:240px">
            <input type="text"
                   class="form-control form-control-sm item-search-input"
                   name="Items[${i}].Description"
                   value="${escHtml(displayText)}"
                   placeholder="Search inventory or enter description…"
                   autocomplete="off"
                   oninput="onItemSearch(this, ${i})"
                   onblur="hideAutocomplete()"
                   data-row-index="${i}" />
            <input type="hidden"
                   name="Items[${i}].InventoryItemId"
                   class="inventory-id-field"
                   value="${isInventory ? (opts.selectedId || '') : ''}" />
        </td>
        <td>
            <input type="number" name="Items[${i}].QuantityOrdered"
                   class="form-control form-control-sm"
                   value="${qty}" min="0.001" step="0.001" style="width:85px"
                   oninput="updateLineTotals()" required />
        </td>
        <td>
            <input type="number" name="Items[${i}].UnitCost"
                   class="form-control form-control-sm"
                   value="${cost}" min="0" step="0.01" style="width:105px"
                   oninput="updateLineTotals()" />
        </td>
        <td class="item-line-total text-end fw-semibold align-middle">$${lineTotal}</td>
        <td>
            <input type="text" name="Items[${i}].Notes"
                   class="form-control form-control-sm"
                   value="${escHtml(notes)}" placeholder="Optional" />
        </td>
        <td class="text-center">
            <button type="button" class="btn btn-sm btn-outline-danger" onclick="removeItem(this)" title="Remove">
                <i class="bi bi-trash"></i>
            </button>
        </td>`;
}

// ─── Autocomplete ─────────────────────────────────────────────────────────────
// Uses a single body-level dropdown so it's never clipped by table overflow.

let _activeSearchInput = null;

function getAutocompleteDropdown() {
    let el = document.getElementById('po-autocomplete');
    if (!el) {
        el = document.createElement('ul');
        el.id = 'po-autocomplete';
        el.className = 'list-group shadow';
        el.style.cssText = 'position:fixed;z-index:9999;max-height:220px;overflow-y:auto;'
                         + 'margin:0;padding:0;border-radius:.35rem;min-width:180px;display:none;';
        document.body.appendChild(el);
    }
    return el;
}

function onItemSearch(input, rowIndex) {
    _activeSearchInput = input;

    // Clear previously selected inventory item when user edits the field
    const tr = input.closest('tr');
    const idField = tr?.querySelector('.inventory-id-field');
    if (idField) idField.value = '';

    const query = input.value.trim().toLowerCase();
    const dropdown = getAutocompleteDropdown();

    if (!query) {
        dropdown.style.display = 'none';
        return;
    }

    const matches = inventoryData
        .filter(item => item.text.toLowerCase().includes(query))
        .slice(0, 12);

    if (matches.length === 0) {
        dropdown.style.display = 'none';
        return;
    }

    dropdown.innerHTML = matches.map(item => `
        <li class="list-group-item list-group-item-action py-1 px-2 small"
            style="cursor:pointer"
            data-value="${item.value}"
            data-cost="${item.cost}"
            data-text="${escHtml(item.text)}"
            onmousedown="selectInventoryItem(this, ${rowIndex})">
            ${escHtml(item.text)}
        </li>`).join('');

    // Position below the input
    const rect = input.getBoundingClientRect();
    dropdown.style.top   = (rect.bottom + 2) + 'px';
    dropdown.style.left  = rect.left + 'px';
    dropdown.style.width = rect.width + 'px';
    dropdown.style.display = '';
}

function selectInventoryItem(li, rowIndex) {
    const tr = document.querySelector(`#lineItemsBody tr[data-index="${rowIndex}"]`);
    if (!tr) return;

    const searchInput = tr.querySelector('.item-search-input');
    const idField     = tr.querySelector('.inventory-id-field');
    const costInput   = tr.querySelector(`[name="Items[${rowIndex}].UnitCost"]`);

    if (searchInput) searchInput.value = li.dataset.text;
    if (idField)     idField.value     = li.dataset.value;

    if (costInput) {
        const cost = parseFloat(li.dataset.cost);
        if (cost > 0) costInput.value = cost.toFixed(2);
    }

    getAutocompleteDropdown().style.display = 'none';
    _activeSearchInput = null;

    updateLineTotals();
}

function hideAutocomplete() {
    // Delay so mousedown on a list item fires before blur hides the dropdown
    setTimeout(() => {
        getAutocompleteDropdown().style.display = 'none';
    }, 150);
}

// Reposition on scroll/resize so the dropdown tracks the input
window.addEventListener('scroll', () => {
    if (!_activeSearchInput) return;
    const rect = _activeSearchInput.getBoundingClientRect();
    const dd = document.getElementById('po-autocomplete');
    if (dd && dd.style.display !== 'none') {
        dd.style.top  = (rect.bottom + 2) + 'px';
        dd.style.left = rect.left + 'px';
    }
}, true);

// ─── Totals ───────────────────────────────────────────────────────────────────

function updateLineTotals() {
    const rows = document.querySelectorAll('#lineItemsBody tr[data-index]');
    let subTotal = 0;

    rows.forEach(tr => {
        const i    = tr.getAttribute('data-index');
        const qty  = parseFloat(tr.querySelector(`[name="Items[${i}].QuantityOrdered"]`)?.value) || 0;
        const cost = parseFloat(tr.querySelector(`[name="Items[${i}].UnitCost"]`)?.value)        || 0;
        const lineTotal = qty * cost;
        subTotal += lineTotal;

        const cell = tr.querySelector('.item-line-total');
        if (cell) cell.textContent = '$' + lineTotal.toFixed(2);
    });

    updateTotals(subTotal);
}

function updateTotals(subTotal) {
    if (subTotal === undefined) {
        subTotal = 0;
        document.querySelectorAll('#lineItemsBody tr[data-index]').forEach(tr => {
            const i    = tr.getAttribute('data-index');
            const qty  = parseFloat(tr.querySelector(`[name="Items[${i}].QuantityOrdered"]`)?.value) || 0;
            const cost = parseFloat(tr.querySelector(`[name="Items[${i}].UnitCost"]`)?.value)        || 0;
            subTotal += qty * cost;
        });
    }

    const shipping   = parseFloat(document.getElementById('shippingCostInput')?.value) || 0;
    const grandTotal = subTotal + shipping;

    setText('subTotalDisplay',   '$' + subTotal.toFixed(2));
    setText('grandTotalDisplay', '$' + grandTotal.toFixed(2));
}

function setText(id, text) {
    const el = document.getElementById(id);
    if (el) el.textContent = text;
}

function toggleEmptyMessage() {
    const tbody  = document.getElementById('lineItemsBody');
    const msg    = document.getElementById('emptyItemsMessage');
    const header = document.getElementById('lineItemsHeader');
    if (!tbody || !msg) return;
    const hasRows = tbody.querySelectorAll('tr[data-index]').length > 0;
    msg.style.display = hasRows ? 'none' : 'block';
    if (header) header.style.display = hasRows ? '' : 'none';
}

// ─── Receive form helpers ─────────────────────────────────────────────────────

function receiveAll() {
    document.querySelectorAll('.receive-qty-input').forEach(input => {
        input.value = parseFloat(input.dataset.remaining) || 0;
    });
}

function clearAll() {
    document.querySelectorAll('.receive-qty-input').forEach(input => {
        input.value = 0;
    });
}

// ─── Utilities ────────────────────────────────────────────────────────────────

function escHtml(str) {
    if (!str) return '';
    return String(str)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}
