(() => {
  'use strict';

  const filterForm = document.querySelector('[data-inventory-filter-form]');
  if (filterForm) {
    const state = filterForm.querySelector('[data-inventory-filter-state]');
    const search = filterForm.querySelector('[data-inventory-search]');
    let searchTimer = 0;
    let submitting = false;

    const submitFilters = (message = 'Updating inventory results') => {
      if (submitting) return;
      submitting = true;
      if (state) state.textContent = message;
      const page = filterForm.querySelector('input[name="page"]');
      if (page) page.value = '1';
      if (typeof filterForm.requestSubmit === 'function') filterForm.requestSubmit();
      else filterForm.submit();
    };

    filterForm.querySelectorAll('[data-auto-inventory-filter]').forEach(control => {
      control.addEventListener('change', () => submitFilters());
    });

    if (search) {
      search.addEventListener('input', () => {
        window.clearTimeout(searchTimer);
        const term = search.value.trim();
        if (term.length === 1) return;
        searchTimer = window.setTimeout(() => submitFilters('Searching inventory'), 450);
      });
    }

    filterForm.addEventListener('submit', () => {
      submitting = true;
      if (state) state.textContent = 'Updating inventory results';
    });
  }

  const dialog = document.querySelector('[data-inventory-transaction]');
  if (!dialog) return;

  const form = dialog.querySelector('form');
  const typeInput = dialog.querySelector('[data-inventory-type]');
  const title = dialog.querySelector('[data-inventory-title]');
  const description = dialog.querySelector('[data-inventory-description]');
  const submitButton = dialog.querySelector('[data-inventory-submit]');
  const branchSelect = dialog.querySelector('[data-inventory-branch]');
  const standardSection = dialog.querySelector('[data-standard-lines]');
  const returnSection = dialog.querySelector('[data-return-lines]');
  const lineBody = dialog.querySelector('[data-inventory-lines]');
  const returnBody = dialog.querySelector('[data-return-line-body]');
  const lineTemplate = document.querySelector('#inventory-line-template');
  const totalLabel = dialog.querySelector('[data-inventory-total]');
  const impactLabel = dialog.querySelector('[data-impact-label]');
  const contextEndpoint = dialog.dataset.contextEndpoint || 'api/inventory_context.php';
  const lookupEndpoint = dialog.dataset.lookupEndpoint || 'api/management_lookup.php';
  const patientId = dialog.querySelector('[data-inventory-patient-id]');
  const chairId = dialog.querySelector('[data-inventory-chair-id]');
  const issueDestination = dialog.querySelector('[data-issue-destination]');
  const chairSelect = dialog.querySelector('[data-chair-select]');
  const procedureSelect = dialog.querySelector('[data-inventory-procedure]');
  let workflow = 'issue';

  const workflowCopy = {
    issue: ['Issue supplies', 'Release stock to an active treatment, staff member, chair, sterilization area, or department.', 'Submit stock issue'],
    purchase_order: ['Purchase request', 'Request items from an approved supplier. Stock increases only after a separate goods receipt.', 'Submit purchase request'],
    transfer: ['Transfer stock', 'Move verified lots between branches with separate dispatch and destination receipt controls.', 'Submit transfer'],
    return: ['Return unused supplies', 'Restore unused stock only against the original posted issue and original lot.', 'Submit return'],
    stock_count: ['Physical count', 'Compare the system lot balance with the actual counted quantity and submit the variance.', 'Submit count variance'],
    damage: ['Record damaged stock', 'Remove damaged stock from a specific lot with supporting evidence.', 'Submit damage write-off'],
    expiry: ['Record expired stock', 'Remove the full remaining balance of a lot that has reached its expiry date.', 'Submit expiry write-off'],
    disposal: ['Controlled disposal', 'Remove stock through an auditable disposal workflow with evidence.', 'Submit disposal request'],
  };

  const setDisabledWithin = (element, disabled) => {
    element.querySelectorAll('input,select,textarea,button').forEach(control => {
      if (control.matches('[data-close]')) return;
      control.disabled = disabled;
    });
  };

  const refreshIssueContext = () => {
    const destination = issueDestination?.value || 'active_treatment';
    dialog.querySelectorAll('[data-issue-context]').forEach(section => {
      const contexts = (section.dataset.issueContext || '').split(/\s+/).filter(Boolean);
      const visible = workflow === 'issue' && contexts.includes(destination);
      section.hidden = !visible;
      setDisabledWithin(section, !visible);
    });
    if (destination !== 'active_treatment') {
      patientId.value = '';
      if (destination !== 'chair') chairId.value = '';
      if (procedureSelect) {
        procedureSelect.replaceChildren(new Option('Select the active or completed procedure', ''));
      }
    }
  };

  const configureColumns = () => {
    const showLot = workflow !== 'purchase_order';
    const showQuantity = workflow !== 'stock_count';
    const showCount = workflow === 'stock_count';
    const showCost = workflow === 'purchase_order';
    dialog.querySelectorAll('[data-col="lot"],[data-cell="lot"]').forEach(el => { el.hidden = !showLot; });
    dialog.querySelectorAll('[data-col="quantity"],[data-cell="quantity"]').forEach(el => { el.hidden = !showQuantity; });
    dialog.querySelectorAll('[data-col="count"],[data-cell="count"]').forEach(el => { el.hidden = !showCount; });
    dialog.querySelectorAll('[data-col="cost"],[data-cell="cost"]').forEach(el => { el.hidden = !showCost; });
    dialog.querySelectorAll('[data-inventory-line]').forEach(row => {
      row.querySelector('[data-lot-select]').disabled = !showLot;
      row.querySelector('[data-line-quantity]').disabled = !showQuantity;
      row.querySelector('[data-line-count]').disabled = !showCount;
      row.querySelector('[data-line-cost]').disabled = !showCost;
      row.querySelector('[data-line-quantity]').readOnly = workflow === 'expiry';
    });
    if (impactLabel) impactLabel.textContent = workflow === 'purchase_order' ? 'Estimated purchase value' : workflow === 'stock_count' ? 'Count variance' : 'Projected stock impact';
  };

  const resetContext = () => {
    patientId.value = '';
    chairId.value = '';
    dialog.querySelectorAll('[data-context-patient],[data-context-dentist],[data-context-assistant],[data-context-chair]').forEach(el => { el.textContent = '—'; });
    if (procedureSelect) procedureSelect.replaceChildren(new Option('Select the active or completed procedure', ''));
  };

  const applyWorkflow = (nextWorkflow, open = true) => {
    workflow = workflowCopy[nextWorkflow] ? nextWorkflow : 'issue';
    typeInput.value = workflow;
    const copy = workflowCopy[workflow];
    title.textContent = copy[0];
    description.textContent = copy[1];
    submitButton.textContent = copy[2];

    dialog.querySelectorAll('[data-inventory-section]').forEach(section => {
      const types = (section.dataset.types || '').split(/\s+/).filter(Boolean);
      const visible = types.includes(workflow);
      section.hidden = !visible;
      setDisabledWithin(section, !visible);
    });
    standardSection.hidden = workflow === 'return';
    returnSection.hidden = workflow !== 'return';
    setDisabledWithin(standardSection, workflow === 'return');
    setDisabledWithin(returnSection, workflow !== 'return');
    resetContext();
    refreshIssueContext();
    configureColumns();
    if (workflow !== 'return' && !lineBody.querySelector('[data-inventory-line]')) addLine();
    updateTotals();
    if (open && typeof dialog.showModal === 'function' && !dialog.open) dialog.showModal();
  };

  const requestJson = async (url) => {
    const response = await fetch(url, { credentials: 'same-origin', headers: { Accept: 'application/json' } });
    const raw = await response.text();
    let data;
    try { data = raw ? JSON.parse(raw) : null; } catch { throw new Error(`Inventory lookup returned an invalid response (HTTP ${response.status}).`); }
    if (!response.ok || !data?.ok) throw new Error(data?.message || `Inventory lookup failed (HTTP ${response.status}).`);
    return data;
  };

  const renderItemResults = (row, items, message = '') => {
    const results = row.querySelector('[data-item-results]');
    results.replaceChildren();
    if (!items.length) {
      const empty = document.createElement('div');
      empty.className = 'remote-picker-empty';
      empty.textContent = message || 'No matching inventory item.';
      results.append(empty);
      results.hidden = false;
      return;
    }
    items.forEach(item => {
      const button = document.createElement('button');
      button.type = 'button';
      button.className = 'remote-picker-option';
      button.innerHTML = '<strong></strong><small></small>';
      button.querySelector('strong').textContent = item.label || item.name || '';
      button.querySelector('small').textContent = item.meta || '';
      button.addEventListener('click', () => chooseItem(row, item));
      results.append(button);
    });
    results.hidden = false;
  };

  const searchItems = async (row, term) => {
    const branch = branchSelect.value;
    const url = new URL(lookupEndpoint, window.location.href);
    url.searchParams.set('type', 'inventory_item');
    url.searchParams.set('branch_id', branch);
    url.searchParams.set('q', term);
    const data = await requestJson(url);
    renderItemResults(row, data.results || [], data.message || '');
    return data.results || [];
  };

  const chooseItem = async (row, item) => {
    const query = row.querySelector('[data-item-query]');
    const hidden = row.querySelector('[data-item-id]');
    const results = row.querySelector('[data-item-results]');
    query.value = item.label || item.name || '';
    hidden.value = item.id || '';
    results.hidden = true;
    results.replaceChildren();
    row.dataset.itemId = String(item.id || '');
    try {
      const url = new URL(contextEndpoint, window.location.href);
      url.searchParams.set('mode', 'item');
      url.searchParams.set('item_id', item.id);
      url.searchParams.set('branch_id', branchSelect.value);
      const data = await requestJson(url);
      const detail = data.item;
      row.dataset.stock = String(detail.current_stock ?? 0);
      row.dataset.unit = detail.unit || '';
      row.dataset.reorder = String(detail.reorder_level ?? 0);
      row.querySelector('[data-item-meta]').textContent = `${detail.category || 'Uncategorized'} · available ${detail.current_stock} ${detail.unit}`;
      const cost = row.querySelector('[data-line-cost]');
      if (workflow === 'purchase_order' && !cost.value) cost.value = Number(detail.purchase_cost || 0).toFixed(2);
      const lotSelect = row.querySelector('[data-lot-select]');
      lotSelect.replaceChildren(new Option(data.lots.length ? 'Select lot' : 'No valid lot available', ''));
      data.lots.forEach((lot, index) => {
        const label = `${lot.lot_number} · ${lot.quantity_remaining} ${detail.unit}${lot.expiry_date ? ` · expires ${lot.expiry_date}` : ' · no expiry'}`;
        const option = new Option(label, lot.id);
        option.dataset.balance = String(lot.quantity_remaining);
        option.dataset.expiry = lot.expiry_date || '';
        option.dataset.fefo = index === 0 ? '1' : '0';
        lotSelect.add(option);
      });
      if (data.suggested_lot_id) {
        lotSelect.value = String(data.suggested_lot_id);
        lotSelect.dispatchEvent(new Event('change', { bubbles: true }));
      }
      if (workflow === 'purchase_order') updateLineImpact(row);
    } catch (error) {
      row.querySelector('[data-item-meta]').textContent = error.message || 'Unable to load item balance.';
    }
  };

  const updateLineImpact = (row) => {
    const impact = row.querySelector('[data-line-impact]');
    const warning = row.querySelector('[data-line-warning]');
    const quantity = Number(row.querySelector('[data-line-quantity]').value || 0);
    const count = Number(row.querySelector('[data-line-count]').value || 0);
    const cost = Number(row.querySelector('[data-line-cost]').value || 0);
    const lotSelect = row.querySelector('[data-lot-select]');
    const option = lotSelect.selectedOptions[0];
    const lotBalance = Number(option?.dataset.balance || 0);
    const unit = row.dataset.unit || '';
    warning.textContent = '';
    warning.className = '';

    if (workflow === 'purchase_order') {
      impact.textContent = quantity > 0 ? `₱${(quantity * cost).toFixed(2)}` : '—';
    } else if (workflow === 'stock_count') {
      impact.textContent = option?.value && row.querySelector('[data-line-count]').value !== '' ? `${count - lotBalance >= 0 ? '+' : ''}${(count - lotBalance).toFixed(2)} ${unit}` : '—';
    } else if (option?.value) {
      if (workflow === 'expiry') {
        row.querySelector('[data-line-quantity]').value = lotBalance ? String(lotBalance) : '';
      }
      const effectiveQuantity = workflow === 'expiry' ? lotBalance : quantity;
      const projected = lotBalance - effectiveQuantity;
      impact.textContent = effectiveQuantity > 0 ? `${lotBalance} → ${projected.toFixed(2)} ${unit}` : `${lotBalance} ${unit}`;
      if (projected < 0) {
        warning.textContent = 'Exceeds available lot balance.';
        warning.className = 'danger-text';
      } else if (option.dataset.fefo !== '1' && ['issue', 'transfer'].includes(workflow)) {
        warning.textContent = 'FEFO override: an earlier valid lot is available.';
        warning.className = 'warning-text';
      } else {
        const reorder = Number(row.dataset.reorder || 0);
        const branchProjected = Number(row.dataset.stock || 0) - effectiveQuantity;
        if (branchProjected <= 0) warning.textContent = 'This will leave the item out of stock.';
        else if (reorder > 0 && branchProjected <= reorder) warning.textContent = 'This will place the item at or below reorder level.';
      }
    } else impact.textContent = 'Select a lot';
    updateTotals();
  };

  const bindLine = (row) => {
    const query = row.querySelector('[data-item-query]');
    const hidden = row.querySelector('[data-item-id]');
    const results = row.querySelector('[data-item-results]');
    let timer = 0;
    query.addEventListener('input', () => {
      hidden.value = '';
      row.dataset.itemId = '';
      window.clearTimeout(timer);
      const term = query.value.trim();
      if (term.length < 2) { results.hidden = true; results.replaceChildren(); return; }
      timer = window.setTimeout(() => searchItems(row, term).catch(error => renderItemResults(row, [], error.message)), 220);
    });
    query.addEventListener('keydown', event => { if (event.key === 'Escape') results.hidden = true; });
    row.querySelector('[data-lot-select]').addEventListener('change', event => {
      const option = event.currentTarget.selectedOptions[0];
      row.querySelector('[data-lot-meta]').textContent = option?.value ? `${option.dataset.balance || 0} ${row.dataset.unit || ''} available${option.dataset.expiry ? ` · expires ${option.dataset.expiry}` : ''}` : '';
      updateLineImpact(row);
    });
    row.querySelectorAll('[data-line-quantity],[data-line-count],[data-line-cost]').forEach(input => input.addEventListener('input', () => updateLineImpact(row)));
    row.querySelector('[data-remove-inventory-line]').addEventListener('click', () => {
      row.remove();
      if (!lineBody.querySelector('[data-inventory-line]')) addLine();
      updateTotals();
    });
    configureColumns();
  };

  function addLine() {
    const fragment = lineTemplate.content.cloneNode(true);
    const row = fragment.querySelector('[data-inventory-line]');
    lineBody.append(row);
    bindLine(row);
    row.querySelector('[data-item-query]').focus();
    return row;
  }

  const updateTotals = () => {
    if (workflow === 'return') {
      const values = Array.from(returnBody.querySelectorAll('input[name="quantity[]"]')).map(input => Number(input.value || 0)).filter(value => value > 0);
      totalLabel.textContent = `${values.length} return line${values.length === 1 ? '' : 's'}`;
      return;
    }
    const rows = Array.from(lineBody.querySelectorAll('[data-inventory-line]')).filter(row => row.querySelector('[data-item-id]').value);
    if (workflow === 'purchase_order') {
      const total = rows.reduce((sum, row) => sum + Number(row.querySelector('[data-line-quantity]').value || 0) * Number(row.querySelector('[data-line-cost]').value || 0), 0);
      totalLabel.textContent = `${rows.length} item line${rows.length === 1 ? '' : 's'} · ₱${total.toFixed(2)}`;
    } else totalLabel.textContent = `${rows.length} item line${rows.length === 1 ? '' : 's'}`;
  };

  const loadEncounter = async (encounterId) => {
    const url = new URL(contextEndpoint, window.location.href);
    url.searchParams.set('mode', 'encounter');
    url.searchParams.set('encounter_id', encounterId);
    url.searchParams.set('branch_id', branchSelect.value);
    const data = await requestJson(url);
    const encounter = data.encounter;
    patientId.value = encounter.patient_id || '';
    chairId.value = encounter.chair_id || '';
    dialog.querySelector('[data-context-patient]').textContent = `${encounter.patient_no} · ${encounter.patient_name}`;
    dialog.querySelector('[data-context-dentist]').textContent = encounter.dentist_name || 'Not assigned';
    dialog.querySelector('[data-context-assistant]').textContent = encounter.assistant_name || 'Not assigned';
    dialog.querySelector('[data-context-chair]').textContent = encounter.chair_name || 'Not assigned';
    procedureSelect.replaceChildren(new Option('Select the active or completed procedure', ''));
    data.procedures.forEach(procedure => {
      const label = `${procedure.name}${procedure.tooth_region ? ` · ${procedure.tooth_region}` : ''} · ${procedure.status.replaceAll('_', ' ')}`;
      procedureSelect.add(new Option(label, procedure.id));
    });
  };

  const loadOriginalIssue = async (documentId) => {
    const url = new URL(contextEndpoint, window.location.href);
    url.searchParams.set('mode', 'issue');
    url.searchParams.set('document_id', documentId);
    url.searchParams.set('branch_id', branchSelect.value);
    const data = await requestJson(url);
    patientId.value = data.document.patient_id || '';
    chairId.value = data.document.chair_id || '';
    returnBody.replaceChildren();
    if (!data.lines.length) {
      const row = document.createElement('tr');
      row.innerHTML = '<td colspan="6" class="muted">Every line from this issue has already been returned.</td>';
      returnBody.append(row);
      return;
    }
    data.lines.forEach(line => {
      const row = document.createElement('tr');
      row.innerHTML = '<td><strong></strong><small></small></td><td></td><td></td><td></td><td></td><td></td>';
      row.children[0].querySelector('strong').textContent = line.item_name;
      row.children[0].querySelector('small').textContent = line.sku;
      row.children[1].textContent = `${line.lot_number || '—'}${line.expiry_date ? ` · exp ${line.expiry_date}` : ''}`;
      row.children[2].textContent = `${line.issued_quantity} ${line.unit}`;
      row.children[3].textContent = `${line.returned_quantity} ${line.unit}`;
      const quantity = document.createElement('input');
      quantity.type = 'number'; quantity.name = 'quantity[]'; quantity.min = '0'; quantity.max = String(line.returnable_quantity); quantity.step = '0.01'; quantity.placeholder = `Max ${line.returnable_quantity}`;
      quantity.addEventListener('input', updateTotals);
      row.children[4].append(quantity);
      const source = document.createElement('input'); source.type = 'hidden'; source.name = 'source_line_id[]'; source.value = line.source_line_id; row.children[4].append(source);
      const item = document.createElement('input'); item.type = 'hidden'; item.name = 'item_id[]'; item.value = line.item_id; row.children[4].append(item);
      const lot = document.createElement('input'); lot.type = 'hidden'; lot.name = 'lot_id[]'; lot.value = line.lot_id; row.children[4].append(lot);
      const note = document.createElement('input'); note.name = 'line_notes[]'; note.placeholder = 'Return condition / note'; row.children[5].append(note);
      returnBody.append(row);
    });
    updateTotals();
  };

  document.querySelectorAll('[data-inventory-workflow]').forEach(button => button.addEventListener('click', () => applyWorkflow(button.dataset.inventoryWorkflow)));
  dialog.querySelector('[data-add-inventory-line]')?.addEventListener('click', addLine);
  issueDestination?.addEventListener('change', refreshIssueContext);
  chairSelect?.addEventListener('change', () => { chairId.value = chairSelect.value; });

  dialog.querySelectorAll('[data-record-picker]').forEach(picker => {
    const hidden = picker.querySelector('[data-record-id]');
    if (!hidden) return;
    if (hidden.name === 'encounter_id') picker.addEventListener('record-selected', event => loadEncounter(event.detail.id).catch(error => window.alert(error.message)));
    if (hidden.name === 'source_document_id') picker.addEventListener('record-selected', event => loadOriginalIssue(event.detail.id).catch(error => window.alert(error.message)));
  });

  dialog.querySelector('[data-inventory-scan]')?.addEventListener('keydown', async event => {
    if (event.key !== 'Enter') return;
    event.preventDefault();
    const term = event.currentTarget.value.trim();
    if (term.length < 2) return;
    let row = Array.from(lineBody.querySelectorAll('[data-inventory-line]')).find(candidate => !candidate.querySelector('[data-item-id]').value) || addLine();
    try {
      const items = await searchItems(row, term);
      const exact = items.find(item => String(item.sku || '').toLowerCase() === term.toLowerCase() || String(item.barcode || '').toLowerCase() === term.toLowerCase()) || items[0];
      if (!exact) throw new Error('No item matched the scanned code.');
      await chooseItem(row, exact);
      event.currentTarget.value = '';
      row.querySelector('[data-line-quantity]').focus();
    } catch (error) { window.alert(error.message || 'The item could not be scanned.'); }
  });

  branchSelect.addEventListener('change', () => {
    dialog.querySelectorAll('[data-record-picker]').forEach(picker => {
      try {
        const endpoint = new URL(picker.dataset.endpoint || lookupEndpoint, window.location.href);
        endpoint.searchParams.set('branch_id', branchSelect.value);
        picker.dataset.endpoint = endpoint.toString();
      } catch (_) { /* Keep the existing endpoint when it cannot be parsed. */ }
      const query = picker.querySelector('[data-record-query]');
      const id = picker.querySelector('[data-record-id]');
      const selection = picker.querySelector('[data-record-selection]');
      const results = picker.querySelector('[data-record-results]');
      if (query) query.value = '';
      if (id) id.value = '';
      if (selection) { selection.textContent = ''; selection.hidden = true; }
      if (results) { results.replaceChildren(); results.hidden = true; }
    });
    lineBody.replaceChildren();
    addLine();
    resetContext();
  });

  form.addEventListener('submit', event => {
    if (workflow === 'return') {
      const source = form.querySelector('input[name="source_document_id"]');
      const hasQuantity = Array.from(returnBody.querySelectorAll('input[name="quantity[]"]')).some(input => Number(input.value || 0) > 0);
      if (!source?.value || !hasQuantity) {
        event.preventDefault();
        window.alert('Select the original posted issue and enter at least one return quantity.');
      }
      return;
    }
    const validRows = Array.from(lineBody.querySelectorAll('[data-inventory-line]')).filter(row => row.querySelector('[data-item-id]').value);
    if (!validRows.length) {
      event.preventDefault();
      window.alert('Add at least one inventory item.');
      return;
    }
    if (workflow === 'issue' && issueDestination.value === 'active_treatment') {
      const encounter = form.querySelector('input[name="encounter_id"]');
      if (!encounter?.value || !procedureSelect.value) {
        event.preventDefault();
        window.alert('Select the active encounter and the performed procedure for treatment consumption.');
      }
    }
  });

  const requestedWorkflow = new URL(window.location.href).searchParams.get('workflow');
  addLine();
  applyWorkflow(requestedWorkflow || 'issue', Boolean(requestedWorkflow));
})();
