/* =====================================================
   File: /ui/js/barcode_sale.js
   Purpose: Barcode Sale - final polish
   ===================================================== */

(function () {
  'use strict';

  const API = {
    getBarcode: '../api/sales/get_barcode_for_sale.php',
    save: '../api/sales/barcode_sale_add.php',
    goldRate: '../api/gold/get_rate.php',
    accountCandidates: [
      '../api/cash/get_accounts.php',
      '../api/cash/accounts.php',
      '../api/settings/get_accounts.php'
    ],
    partyCandidates: [
      '../api/parties/search_party.php',
      '../api/parties/search_parties.php',
      '../api/parties/get_parties.php',
      '../api/customers/party_list.php',
      '../api/customers/search.php'
    ]
  };

  const state = {
    items: [],
    payments: [],
    accounts: [{ id: 1, name: 'Cash / Showroom' }],
    lastSale: null,
    partyTimer: null,
    goldRates: {}
  };

  const $ = (s, p = document) => p.querySelector(s);
  const $$ = (s, p = document) => Array.from(p.querySelectorAll(s));

  const el = {
    saleForm: $('#saleForm'),
    barcodeInput: $('#barcodeInput'),
    scanBtn: $('#scanBtn'),
    clearBarcodeBtn: $('#clearBarcodeBtn'),
    scanStatus: $('#scanStatus'),
    customerType: $('#customerType'),
    partySearchBox: $('#partySearchBox'),
    partySearch: $('#partySearch'),
    partyId: $('#partyId'),
    partyResults: $('#partyResults'),
    customerName: $('#customerName'),
    customerPhone: $('#customerPhone'),
    previousBalance: $('#previousBalance'),
    emptyItems: $('#emptyItems'),
    itemsTableWrap: $('#itemsTableWrap'),
    itemsTbody: $('#itemsTbody'),
    mobileItems: $('#mobileItems'),
    clearItemsBtn: $('#clearItemsBtn'),
    makingCharge: $('#makingCharge'),
    discount: $('#discount'),
    vatPercent: $('#vatPercent'),
    exchangeAmount: $('#exchangeAmount'),
    itemsTotalText: $('#itemsTotalText'),
    vatAmountText: $('#vatAmountText'),
    grandTotalText: $('#grandTotalText'),
    paidAmountText: $('#paidAmountText'),
    dueAmountText: $('#dueAmountText'),
    paymentList: $('#paymentList'),
    addPaymentBtn: $('#addPaymentBtn'),
    notes: $('#notes'),
    resultBox: $('#resultBox'),
    printBtn: $('#printBtn'),
    resetBtn: $('#resetBtn'),
    saveBtn: $('#saveBtn'),
    toast: $('#toast'),
    goldRateDisplay: $('#goldRateDisplay')
  };

  function esc(v) {
    return String(v ?? '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#039;');
  }

  function num(v, fallback = 0) {
    if (v === null || v === undefined || v === '') return fallback;
    const map = {'০':'0','১':'1','২':'2','৩':'3','৪':'4','৫':'5','৬':'6','৭':'7','৮':'8','৯':'9'};
    let str = String(v).replace(/[০-৯]/g, d => map[d] || d);
    str = str.replace(/[৳,\s]/g, '');
    const n = Number(str);
    return Number.isFinite(n) ? n : fallback;
  }

  function round(v, d = 2) {
    const m = Math.pow(10, d);
    return Math.round((num(v) + Number.EPSILON) * m) / m;
  }

  function money(v) {
    return '৳' + Number(round(v, 2)).toLocaleString('bn-BD', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    });
  }

  function cleanInputNumber(v, digits = 2) {
    return String(round(v, digits));
  }

  function weightTextFromVori(weightVori) {
    const totalPoint = Math.round(num(weightVori) * 960);
    const vori = Math.floor(totalPoint / 960);
    let remain = totalPoint % 960;
    const ana = Math.floor(remain / 60);
    remain = remain % 60;
    const roti = Math.floor(remain / 10);
    const point = remain % 10;
    return `${vori} ভরি ${ana} আনা ${roti} রতি ${point} পয়েন্ট`;
  }

  function setStatus(msg, type = '') {
    if (!el.scanStatus) return;
    el.scanStatus.className = 'status-box' + (type ? ' ' + type : '');
    el.scanStatus.textContent = msg;
  }

  function toast(msg, type = '') {
    if (!el.toast) { alert(msg); return; }
    el.toast.textContent = msg;
    el.toast.className = 'toast show' + (type ? ' ' + type : '');
    clearTimeout(toast._t);
    toast._t = setTimeout(() => { el.toast.className = 'toast'; }, 3500);
  }

  async function fetchJson(url, options = {}) {
    const res = await fetch(url, {
      credentials: 'same-origin',
      cache: 'no-store',
      ...options,
      headers: { Accept: 'application/json', ...(options.headers || {}) }
    });

    const text = await res.text();
    let data;

    try {
      data = JSON.parse(text);
    } catch (e) {
      console.error('Non JSON:', url, text);
      throw new Error('Server JSON response দেয়নি');
    }

    if (!res.ok) throw new Error(data.message || data.error || 'Request failed');
    return data;
  }

  async function loadGoldRate() {
    try {
      const data = await fetchJson(API.goldRate);
      if (data.success && data.data && data.data.rates_by_karat) {
        state.goldRates = data.data.rates_by_karat;

        if (el.goldRateDisplay) {
          const r = data.data.rates_by_karat;
          el.goldRateDisplay.innerHTML =
            `আজকের রেট (প্রতি ভরি) — ` +
            `22K: <strong>${money(r['22K'] || 0)}</strong> | ` +
            `21K: <strong>${money(r['21K'] || 0)}</strong> | ` +
            `18K: <strong>${money(r['18K'] || 0)}</strong>`;
          el.goldRateDisplay.style.display = 'block';
        }
      }
    } catch (e) {
      console.warn('Gold rate load failed:', e.message);
    }
  }

  function applyGoldRateToItem(item) {
    const karat = String(item.karat || '').trim().toUpperCase();
    const ratePerVori = num(state.goldRates[karat], 0);

    if (ratePerVori > 0) {
      item.sale_rate_per_vori = round(ratePerVori, 2);
      item.rate_per_gram = round(ratePerVori / 11.664, 2);
      item.item_price = round(item.weight_vori * ratePerVori, 2);
    }

    return item;
  }

  function normalizeArray(data) {
    if (Array.isArray(data)) return data;
    if (Array.isArray(data.parties)) return data.parties;
    if (Array.isArray(data.party)) return data.party;
    if (Array.isArray(data.customers)) return data.customers;
    if (Array.isArray(data.customer)) return data.customer;
    if (data.data && Array.isArray(data.data.accounts)) return data.data.accounts;
    if (Array.isArray(data.data)) return data.data;
    if (Array.isArray(data.items)) return data.items;
    if (Array.isArray(data.accounts)) return data.accounts;
    if (Array.isArray(data.result)) return data.result;
    return [];
  }

  function getAccountId(a) {
    return num(a.id ?? a.account_id ?? a.value, 1);
  }

  function getAccountName(a) {
    return String(a.name ?? a.account_name ?? a.title ?? a.label ?? 'Cash');
  }

  async function loadAccounts() {
    for (const url of API.accountCandidates) {
      try {
        const data = await fetchJson(url);
        const list = normalizeArray(data)
          .map(a => ({ id: getAccountId(a), name: getAccountName(a) }))
          .filter(a => a.id > 0 && a.name);

        if (list.length) {
          state.accounts = list;
          renderPayments();
          return;
        }
      } catch (e) {}
    }

    state.accounts = [{ id: 1, name: 'Cash / Showroom' }];
    renderPayments();
  }

  function accountOptions(selectedId) {
    return state.accounts.map(acc => {
      const selected = Number(selectedId) === Number(acc.id) ? 'selected' : '';
      return `<option value="${esc(acc.id)}" ${selected}>${esc(acc.name)}</option>`;
    }).join('');
  }

  function renderPayments() {
    if (!el.paymentList) return;

    el.paymentList.innerHTML = '';

    if (!state.payments.length) {
      state.payments.push({
        account_id: state.accounts[0]?.id || 1,
        account_name: state.accounts[0]?.name || 'Cash / Showroom',
        amount: 0
      });
    }

    state.payments.forEach((p, index) => {
      const row = document.createElement('div');
      row.className = 'payment-row';
      row.innerHTML = `
        <div class="field">
          <label>Account</label>
          <select class="select payment-account" data-index="${index}">
            ${accountOptions(p.account_id)}
          </select>
        </div>
        <div class="field">
          <label>Account Name</label>
          <input class="input payment-name" data-index="${index}" value="${esc(p.account_name)}">
        </div>
        <div class="field">
          <label>Amount</label>
          <input class="input payment-amount" type="number" step="0.01" data-index="${index}" value="${cleanInputNumber(p.amount, 2)}">
        </div>
        <button class="btn btn-red payment-remove" type="button" data-index="${index}">মুছুন</button>
      `;
      el.paymentList.appendChild(row);
    });

    $$('.payment-account', el.paymentList).forEach(input => {
      input.addEventListener('change', () => {
        const i = Number(input.dataset.index);
        const id = num(input.value, 1);
        const acc = state.accounts.find(a => Number(a.id) === Number(id));
        state.payments[i].account_id = id;
        state.payments[i].account_name = acc?.name || 'Cash';
        renderPayments();
        recalc();
      });
    });

    $$('.payment-name', el.paymentList).forEach(input => {
      input.addEventListener('input', () => {
        state.payments[Number(input.dataset.index)].account_name = input.value;
      });
    });

    $$('.payment-amount', el.paymentList).forEach(input => {
      input.addEventListener('input', () => {
        state.payments[Number(input.dataset.index)].amount = round(input.value, 2);
        recalc();
      });
    });

    $$('.payment-remove', el.paymentList).forEach(btn => {
      btn.addEventListener('click', () => {
        const i = Number(btn.dataset.index);
        state.payments.splice(i, 1);
        renderPayments();
        recalc();
      });
    });
  }

  function addPayment(defaultAmount = 0) {
    state.payments.push({
      account_id: state.accounts[0]?.id || 1,
      account_name: state.accounts[0]?.name || 'Cash / Showroom',
      amount: round(defaultAmount, 2)
    });
    renderPayments();
    recalc();
  }

  function itemKey(item) {
    return item.barcode_stock_id ? `id_${item.barcode_stock_id}` : `bc_${item.barcode}`;
  }

  function normalizeItem(raw) {
    const weightVori = round(raw.weight_vori || raw.vori_weight || 0, 5);
    const weightText = raw.weight_text || weightTextFromVori(weightVori);

    return {
      barcode_stock_id: num(raw.barcode_stock_id ?? raw.id, 0),
      barcode: String(raw.barcode || raw.barcode_no || raw.barcode_code || ''),
      item_name: String(raw.item_name || raw.product_name || raw.name || 'Barcode Item'),
      category: String(raw.category || raw.category_name || ''),
      karat: String(raw.karat || raw.purity || ''),
      weight_g: round(raw.weight_g || raw.weight_gram || raw.weight || raw.gross_weight || 0, 3),
      weight_vori: weightVori,
      vori: num(raw.vori, 0),
      ana: num(raw.ana, 0),
      roti: num(raw.roti, 0),
      point: num(raw.point, 0),
      weight_text: weightText,
      rate_per_gram: round(raw.rate_per_gram || 0, 2),
      sale_rate_per_vori: round(raw.sale_rate_per_vori || raw.rate_per_vori || 0, 2),
      making_charge: round(raw.making_charge || 0, 2),
      item_price: round(raw.item_price || raw.sale_price || raw.total_price || 0, 2),
      source: raw.source || 'barcode_stock',
      source_json: raw.source_json || raw
    };
  }

  async function scanBarcode() {
    const barcode = el.barcodeInput.value.trim();

    if (!barcode) {
      setStatus('বারকোড লিখুন / স্ক্যান করুন', 'err');
      el.barcodeInput.focus();
      return;
    }

    el.scanBtn.disabled = true;
    setStatus('বারকোড খোঁজা হচ্ছে...', '');

    try {
      const data = await fetchJson(`${API.getBarcode}?barcode=${encodeURIComponent(barcode)}`);

      if (!data.success) {
        setStatus(data.message || 'বারকোড পাওয়া যায়নি', 'err');
        toast(data.message || 'বারকোড পাওয়া যায়নি', 'err');
        return;
      }

      let item = normalizeItem(data.item || data.data || data);
      if (!item.barcode && barcode) item.barcode = barcode;

      if (state.items.some(x => itemKey(x) === itemKey(item))) {
        setStatus('এই বারকোডটি আগে তালিকায় যোগ করা হয়েছে', 'err');
        toast('এই বারকোডটি আগে যোগ করা হয়েছে', 'err');
        return;
      }

      item = applyGoldRateToItem(item);

      state.items.push(item);
      el.barcodeInput.value = '';

      setStatus(`যোগ হয়েছে: ${item.item_name} (${item.barcode}) — রেট: ${money(item.sale_rate_per_vori)}/ভরি`, 'ok');

      renderItems();
      autoFillRemainingDueToFirstPayment();
      recalc();
      el.barcodeInput.focus();

    } catch (e) {
      setStatus(e.message || 'Server error', 'err');
      toast(e.message || 'Server error', 'err');
    } finally {
      el.scanBtn.disabled = false;
    }
  }

  function renderItems() {
    const hasItems = state.items.length > 0;

    if (el.emptyItems) el.emptyItems.style.display = hasItems ? 'none' : 'block';
    if (el.itemsTableWrap) el.itemsTableWrap.style.display = hasItems ? 'block' : 'none';
    if (el.itemsTbody) el.itemsTbody.innerHTML = '';
    if (el.mobileItems) el.mobileItems.innerHTML = '';

    state.items.forEach((item, index) => {
      if (el.itemsTbody) {
        const tr = document.createElement('tr');
        tr.innerHTML = `
          <td>${index + 1}</td>
          <td><strong>${esc(item.barcode)}</strong></td>
          <td>${esc(item.item_name)}</td>
          <td>${esc(item.karat || '-')}</td>
          <td>${cleanInputNumber(item.weight_g, 3)}</td>
          <td>${esc(item.weight_text)}</td>
          <td>
            <input class="small-input item-rate" data-index="${index}" type="number" step="0.01" value="${cleanInputNumber(item.sale_rate_per_vori, 2)}">
            <div class="mini">প্রতি গ্রাম: ${money(item.rate_per_gram)}</div>
          </td>
          <td>
            <input class="small-input item-price" data-index="${index}" type="number" step="0.01" value="${cleanInputNumber(item.item_price, 2)}">
          </td>
          <td><button class="btn btn-red item-remove" type="button" data-index="${index}">মুছুন</button></td>
        `;
        el.itemsTbody.appendChild(tr);
      }

      if (el.mobileItems) {
        const card = document.createElement('div');
        card.className = 'item-card';
        card.innerHTML = `
          <div class="item-top">
            <div>
              <div class="item-title">${esc(item.item_name)}</div>
              <div class="mini">বারকোড: ${esc(item.barcode)} | ${esc(item.karat || '-')}</div>
            </div>
            <button class="btn btn-red item-remove" type="button" data-index="${index}">মুছুন</button>
          </div>
          <div class="item-card-grid">
            <div class="summary-line">
              <span>ওজন(g)</span>
              <strong>${cleanInputNumber(item.weight_g, 3)}</strong>
            </div>
            <div class="summary-line">
              <span>ভরি/আনা/রতি/পয়েন্ট</span>
              <strong>${esc(item.weight_text)}</strong>
            </div>
            <div class="field">
              <label>রেট/ভরি</label>
              <input class="input item-rate" data-index="${index}" type="number" step="0.01" value="${cleanInputNumber(item.sale_rate_per_vori, 2)}">
              <div class="hint">প্রতি গ্রাম: ${money(item.rate_per_gram)}</div>
            </div>
            <div class="field">
              <label>দাম</label>
              <input class="input item-price" data-index="${index}" type="number" step="0.01" value="${cleanInputNumber(item.item_price, 2)}">
            </div>
          </div>
        `;
        el.mobileItems.appendChild(card);
      }
    });

    bindItemInputs();
  }

  function bindItemInputs() {
    $$('.item-rate').forEach(input => {
      input.addEventListener('change', () => {
        const i = Number(input.dataset.index);
        state.items[i].sale_rate_per_vori = round(input.value, 2);
        state.items[i].rate_per_gram = round(state.items[i].sale_rate_per_vori / 11.664, 2);
        state.items[i].item_price = round(state.items[i].weight_vori * state.items[i].sale_rate_per_vori, 2);
        renderItems();
        recalc();
      });
    });

    $$('.item-price').forEach(input => {
      input.addEventListener('input', () => {
        state.items[Number(input.dataset.index)].item_price = round(input.value, 2);
        recalc();
      });
    });

    $$('.item-remove').forEach(btn => {
      btn.addEventListener('click', () => {
        state.items.splice(Number(btn.dataset.index), 1);
        renderItems();
        autoFillRemainingDueToFirstPayment();
        recalc();
      });
    });
  }

  function calcSummary() {
    const itemsTotal = state.items.reduce((sum, item) => sum + num(item.item_price), 0);
    const makingCharge = num(el.makingCharge?.value || 0);
    const discount = num(el.discount?.value || 0);
    const vatPercent = num(el.vatPercent?.value || 0);
    const exchangeAmount = num(el.exchangeAmount?.value || 0);

    const taxable = Math.max(0, itemsTotal + makingCharge - discount - exchangeAmount);
    const vatAmount = round((taxable * vatPercent) / 100, 2);
    const grandTotal = round(taxable + vatAmount, 2);
    const paidAmount = state.payments.reduce((sum, p) => sum + num(p.amount), 0);
    const dueAmount = Math.max(0, round(grandTotal - paidAmount, 2));

    return {
      itemsTotal: round(itemsTotal, 2),
      makingCharge: round(makingCharge, 2),
      discount: round(discount, 2),
      vatPercent: round(vatPercent, 2),
      vatAmount,
      exchangeAmount: round(exchangeAmount, 2),
      grandTotal,
      paidAmount: round(paidAmount, 2),
      dueAmount
    };
  }

  function recalc() {
    const s = calcSummary();
    if (el.itemsTotalText) el.itemsTotalText.textContent = money(s.itemsTotal);
    if (el.vatAmountText) el.vatAmountText.textContent = money(s.vatAmount);
    if (el.grandTotalText) el.grandTotalText.textContent = money(s.grandTotal);
    if (el.paidAmountText) el.paidAmountText.textContent = money(s.paidAmount);
    if (el.dueAmountText) el.dueAmountText.textContent = money(s.dueAmount);
  }

  function autoFillRemainingDueToFirstPayment() {
    if (!state.payments.length) return;

    if (state.payments.length === 1 && num(state.payments[0].amount) === 0) {
      const s = calcSummary();
      state.payments[0].amount = s.grandTotal;
      renderPayments();
    }
  }

  function collectData() {
    const s = calcSummary();

    return {
      customer_type: el.customerType?.value || 'cash',
      party_id: num(el.partyId?.value || 0, 0),
      customer_name: el.customerName?.value.trim() || '',
      customer_phone: el.customerPhone?.value.trim() || '',
      previous_balance: num(el.previousBalance?.value || 0, 0),
      items: state.items.map(item => ({
        barcode_stock_id: item.barcode_stock_id,
        barcode: item.barcode,
        item_name: item.item_name,
        karat: item.karat,
        weight_g: item.weight_g,
        weight_vori: item.weight_vori,
        weight_text: item.weight_text,
        sale_rate_per_vori: item.sale_rate_per_vori,
        rate_per_gram: item.rate_per_gram,
        item_price: item.item_price,
        source: item.source,
        source_json: item.source_json
      })),
      making_charge: s.makingCharge,
      discount: s.discount,
      vat_percent: s.vatPercent,
      vat_amount: s.vatAmount,
      exchange_amount: s.exchangeAmount,
      items_total: s.itemsTotal,
      grand_total: s.grandTotal,
      paid_amount: s.paidAmount,
      due_amount: s.dueAmount,
      payments: state.payments
        .map(p => ({
          account_id: num(p.account_id, 1),
          account_name: String(p.account_name || 'Cash'),
          amount: round(p.amount, 2)
        }))
        .filter(p => p.amount > 0),
      notes: el.notes?.value.trim() || ''
    };
  }

  async function saveSale(e) {
    e.preventDefault();

    if (!state.items.length) {
      toast('কমপক্ষে ১টি বারকোড আইটেম যোগ করুন', 'err');
      el.barcodeInput.focus();
      return;
    }

    const payload = collectData();

    el.saveBtn.disabled = true;
    el.saveBtn.textContent = 'সেভ হচ্ছে...';

    try {
      const data = await fetchJson(API.save, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json; charset=utf-8' },
        body: JSON.stringify(payload)
      });

      if (!data.success) throw new Error(data.message || 'সেল সেভ হয়নি');

      state.lastSale = {
        ...payload,
        sale_id: data.sale_id,
        invoice_no: data.invoice_no,
        sale_date: data.sale_date || new Date().toISOString(),
        status: data.status,
        summary: data.summary || calcSummary()
      };

      try {
        sessionStorage.setItem('lastSale', JSON.stringify(state.lastSale));
      } catch (err) {}

      if (el.resultBox) {
        el.resultBox.classList.add('active');
        el.resultBox.innerHTML = `
          <strong>সেভ সম্পন্ন!</strong><br>
          ইনভয়েস: <strong>${esc(data.invoice_no)}</strong><br>
          স্ট্যাটাস: <strong>${esc(data.status)}</strong><br>
          গ্র্যান্ড টোটাল: <strong>${money(data.summary?.grand_total ?? payload.grand_total)}</strong>
        `;
      }

      if (el.printBtn) el.printBtn.disabled = false;
      toast(data.message || 'সেল সেভ হয়েছে', 'ok');

    } catch (err) {
      toast(err.message || 'Save failed', 'err');
    } finally {
      el.saveBtn.disabled = false;
      el.saveBtn.textContent = 'সেল সেভ করুন';
    }
  }

  function normalizeParty(p) {
    const name = p.name || p.party_name || p.customer_name || p['নাম'] || '';
    const phone = p.phone || p.mobile || p.customer_phone || p['মোবাইল'] || '';
    const balance = p.balance ?? p.current_balance ?? p.previous_balance ?? 0;
    const id = p.id || p.party_id || p.customer_id || '';
    return { id, name: String(name || 'নাম নেই'), phone: String(phone || ''), balance: num(balance, 0) };
  }

  async function searchParty(q) {
    if (!el.partyResults) return;

    if (!q || q.length < 2) {
      el.partyResults.classList.remove('active');
      el.partyResults.innerHTML = '';
      return;
    }

    el.partyResults.classList.add('active');
    el.partyResults.innerHTML = '<div class="party-item">সার্চ হচ্ছে...</div>';

    for (const base of API.partyCandidates) {
      try {
        const joiner = base.includes('?') ? '&' : '?';
        const url = `${base}${joiner}q=${encodeURIComponent(q)}&search=${encodeURIComponent(q)}&limit=20`;
        const data = await fetchJson(url);
        const list = normalizeArray(data);

        if (list.length) {
          renderPartyResults(list.slice(0, 20));
          return;
        }
      } catch (e) {}
    }

    el.partyResults.innerHTML = '<div class="party-item">কোনো পার্টি পাওয়া যায়নি।</div>';
  }

  function renderPartyResults(list) {
    if (!el.partyResults) return;

    const parties = list.map(normalizeParty);

    el.partyResults.innerHTML = parties.map((p, i) => `
      <div class="party-item"
           data-index="${i}"
           data-id="${esc(p.id)}"
           data-name="${esc(p.name)}"
           data-phone="${esc(p.phone)}"
           data-balance="${esc(p.balance)}">
        <strong>${esc(p.name)}</strong><br>
        <span class="mini">${esc(p.phone)} | Balance: ${money(p.balance)}</span>
      </div>
    `).join('');

    el.partyResults.classList.add('active');

    $$('.party-item', el.partyResults).forEach(item => {
      item.addEventListener('click', () => {
        if (el.partyId) el.partyId.value = item.dataset.id || '';
        if (el.customerName) el.customerName.value = item.dataset.name || '';
        if (el.customerPhone) el.customerPhone.value = item.dataset.phone || '';
        if (el.previousBalance) el.previousBalance.value = num(item.dataset.balance, 0);
        if (el.partySearch) el.partySearch.value = item.dataset.name || '';
        el.partyResults.classList.remove('active');
        recalc();
      });
    });
  }

  function resetForm() {
    if (!confirm('ফর্ম রিসেট করবেন?')) return;

    state.items = [];
    state.payments = [{
      account_id: state.accounts[0]?.id || 1,
      account_name: state.accounts[0]?.name || 'Cash / Showroom',
      amount: 0
    }];
    state.lastSale = null;

    el.saleForm.reset();

    if (el.partyId) el.partyId.value = '';
    if (el.customerType) el.customerType.value = 'cash';
    if (el.partySearchBox) el.partySearchBox.style.display = 'none';
    if (el.resultBox) {
      el.resultBox.classList.remove('active');
      el.resultBox.innerHTML = '';
    }
    if (el.printBtn) el.printBtn.disabled = true;

    setStatus('বারকোড স্ক্যান করলে আইটেম নিচের তালিকায় যোগ হবে।', '');

    renderItems();
    renderPayments();
    recalc();

    el.barcodeInput.focus();
  }

  function printInvoice() {
    if (!state.lastSale) {
      toast('আগে সেল সেভ করুন', 'err');
      return;
    }
    window.open('invoice_print.html', '_blank');
  }

  function bindEvents() {
    if (el.scanBtn) el.scanBtn.addEventListener('click', scanBarcode);

    if (el.clearBarcodeBtn) {
      el.clearBarcodeBtn.addEventListener('click', () => {
        el.barcodeInput.value = '';
        el.barcodeInput.focus();
      });
    }

    if (el.barcodeInput) {
      el.barcodeInput.addEventListener('keydown', e => {
        if (e.key === 'Enter') {
          e.preventDefault();
          scanBarcode();
        }
      });
    }

    if (el.customerType) {
      el.customerType.addEventListener('change', () => {
        const isParty = el.customerType.value === 'party';
        if (el.partySearchBox) el.partySearchBox.style.display = isParty ? 'flex' : 'none';

        if (!isParty) {
          if (el.partyId) el.partyId.value = '';
          if (el.partySearch) el.partySearch.value = '';
          if (el.partyResults) {
            el.partyResults.classList.remove('active');
            el.partyResults.innerHTML = '';
          }
        }
      });
    }

    if (el.partySearch) {
      el.partySearch.addEventListener('input', () => {
        clearTimeout(state.partyTimer);
        const q = el.partySearch.value.trim();
        state.partyTimer = setTimeout(() => searchParty(q), 300);
      });
    }

    document.addEventListener('click', e => {
      if (el.partySearchBox && !el.partySearchBox.contains(e.target)) {
        if (el.partyResults) el.partyResults.classList.remove('active');
      }
    });

    $$('.calc-input').forEach(input => input.addEventListener('input', recalc));

    if (el.addPaymentBtn) el.addPaymentBtn.addEventListener('click', () => addPayment(0));

    if (el.clearItemsBtn) {
      el.clearItemsBtn.addEventListener('click', () => {
        if (!state.items.length) return;
        if (!confirm('সব আইটেম মুছে ফেলবেন?')) return;
        state.items = [];
        renderItems();
        recalc();
      });
    }

    if (el.saleForm) el.saleForm.addEventListener('submit', saveSale);
    if (el.resetBtn) el.resetBtn.addEventListener('click', resetForm);
    if (el.printBtn) el.printBtn.addEventListener('click', printInvoice);
  }

  function init() {
    state.payments = [{ account_id: 1, account_name: 'Cash / Showroom', amount: 0 }];

    bindEvents();
    renderItems();
    renderPayments();
    recalc();
    loadAccounts();
    loadGoldRate();

    setStatus('বারকোড স্ক্যান করলে আইটেম নিচের তালিকায় যোগ হবে।', '');
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();