// daygig-receipts.js — Receipt parser: drag-drop, AI parse, post expense, import materials

// ── Receipt Parser (standalone panel) ────────────────────────────────────

  let _rcpStoredFilename = null;
  let _rcpParsed         = null;
  let _rcpLineItems      = [];   // editable copy of parsed line items

  async function _rcpLoadAccounts() {
    if (_rcpAccounts.length) return;
    try {
      const res  = await fetch('/api/accounts');
      const data = await res.json();
      _rcpAccounts = Array.isArray(data) ? data : (data.accounts || []);
    } catch(e) { console.warn('rcpLoadAccounts', e); }
  }

  function rcpDragOver(e)  { e.preventDefault(); document.getElementById('rcp-drop-zone').style.borderColor = 'var(--accent)'; document.getElementById('rcp-drop-zone').style.background = 'var(--accent-bg)'; }
  function rcpDragLeave(e) { document.getElementById('rcp-drop-zone').style.borderColor = 'var(--border-hi)'; document.getElementById('rcp-drop-zone').style.background = ''; }
  function rcpDrop(e) {
    e.preventDefault(); rcpDragLeave(e);
    const file = e.dataTransfer.files[0];
    if (file) rcpProcess(file);
  }
  function rcpFileSelected(input) { if (input.files[0]) rcpProcess(input.files[0]); }

  function rcpReset() {
    _rcpStoredFilename = null; _rcpParsed = null; _rcpLineItems = [];
    const fi = document.getElementById('rcp-file-input'); if (fi) fi.value = '';
    document.getElementById('rcp-drop-card').style.display = 'block';
    document.getElementById('rcp-result-card').style.display = 'none';
    document.getElementById('rcp-status').style.display = 'none';
    const actionMsg = document.getElementById('rcp-action-msg');
    actionMsg.style.display = 'none';
    actionMsg.dataset.posted = '';
    document.getElementById('rcp-mat-summary').style.display = 'none';
    document.getElementById('rcp-drop-zone').style.borderColor = 'var(--border-hi)';
    document.getElementById('rcp-drop-zone').style.background = '';
    // Re-enable Post button in case it was disabled after a successful post
    const postBtn = document.querySelector('[onclick="rcpPostExpense()"]');
    if (postBtn) { postBtn.disabled = false; postBtn.style.opacity = ''; }
  }

  async function rcpProcess(file) {
    const status  = document.getElementById('rcp-status');
    const dropZone = document.getElementById('rcp-drop-zone');
    status.style.display = 'block';
    status.textContent   = '⬆ Uploading…';
    dropZone.style.opacity = '.4';
    dropZone.style.pointerEvents = 'none';

    // Read + upload
    const b64 = await new Promise((res, rej) => {
      const r = new FileReader();
      r.onload  = () => res(r.result.split(',')[1]);
      r.onerror = () => rej(new Error('File read failed'));
      r.readAsDataURL(file);
    });

    try {
      const upRes  = await fetch('/api/receipts/upload', {
        method: 'POST', headers: {'Content-Type':'application/json'},
        body: JSON.stringify({ filename: file.name, file_b64: b64 }),
      });
      const upData = await upRes.json();
      if (!upData.ok) { status.textContent = '✕ Upload failed: ' + (upData.error || 'Unknown'); rcpResetDrop(); return; }
      _rcpStoredFilename = upData.stored_filename;
    } catch(e) { status.textContent = '✕ Upload error: ' + e.message; rcpResetDrop(); return; }

    // Parse
    status.textContent = 'Reading the receipt\u2026 (a few seconds)';
    try {
      const parseRes  = await fetch('/api/receipts/parse', {
        method: 'POST', headers: {'Content-Type':'application/json'},
        body: JSON.stringify({ stored_filename: _rcpStoredFilename, amount_cents: 0 }),
      });
      const parseData = await parseRes.json();
      if (!parseData.ok) { status.textContent = '✕ Parse error: ' + (parseData.error || 'Unknown'); rcpResetDrop(); return; }
      _rcpParsed    = parseData.receipt;
      _rcpLineItems = (_rcpParsed.line_items || []).map(l => ({...l}));
      await _rcpLoadAccounts();
      rcpShowResult();
      status.style.display = 'none';
    } catch(e) { status.textContent = '✕ Parse error: ' + e.message; rcpResetDrop(); }
  }

  function rcpResetDrop() {
    const dz = document.getElementById('rcp-drop-zone');
    dz.style.opacity = '1'; dz.style.pointerEvents = '';
  }

  function rcpShowResult() {
    const r = _rcpParsed;
    document.getElementById('rcp-drop-card').style.display = 'none';
    document.getElementById('rcp-result-card').style.display = 'block';

    document.getElementById('rcp-vendor').textContent    = r.vendor || 'Unknown Vendor';
    document.getElementById('rcp-date-total').textContent = (r.date || '—') + '  ·  ' + dgMoney(r.total || 0);
    document.getElementById('rcp-subtotal').textContent  = dgMoney(r.subtotal || 0);
    document.getElementById('rcp-tax').textContent       = dgMoney(r.tax || 0);
    document.getElementById('rcp-total').textContent     = dgMoney(r.total || 0);
    document.getElementById('rcp-payment').textContent   = r.payment_method || '—';

    // Pre-select the payment method dropdown from AI-parsed data
    const pmRaw = (r.payment_method || '').toLowerCase();
    const pmMap = { cash:'cash', card:'bank', credit:'bank', check:'check', paypal:'paypal', venmo:'venmo', stripe:'stripe', square:'square' };
    const pmSel = document.getElementById('rcp-payment-method');
    if (pmSel) pmSel.value = pmMap[pmRaw] || 'other';

    // Amount match badge
    const badge = document.getElementById('rcp-match-badge');
    if (r.amount_match) {
      badge.textContent = '✓ Matches bank amount'; badge.style.display = 'inline';
      badge.style.background = 'var(--accent-bg)'; badge.style.color = 'var(--accent)';
      badge.style.border = '1px solid var(--accent-ring)';
    } else { badge.style.display = 'none'; }

    // Use tax warning
    document.getElementById('rcp-usetax-badge').style.display = r.suggest_use_tax ? 'inline' : 'none';

    rcpRenderLines();
  }

  function rcpRenderLines() {
    const container  = document.getElementById('rcp-line-items');
    const matCount   = document.getElementById('rcp-mat-count');
    const importBtn  = document.getElementById('rcp-import-mat-btn');
    const matLines   = _rcpLineItems.filter(l => l.is_material);

    // Show import button only if there are material lines
    importBtn.style.display = matLines.length ? 'inline-flex' : 'none';
    matCount.textContent    = matLines.length ? `${matLines.length} material${matLines.length > 1 ? 's' : ''} detected` : '';

    // Build account select options grouped by type
    const acctOpts = () => {
      const groups = ['expense','income','liability','asset'];
      return groups.map(type => {
        const accts = _rcpAccounts.filter(a => a.account_type === type);
        if (!accts.length) return '';
        return `<optgroup label="${type.charAt(0).toUpperCase()+type.slice(1)}">${
          accts.map(a => `<option value="${a.id}">${a.name}</option>`).join('')
        }</optgroup>`;
      }).join('');
    };

    if (!_rcpLineItems.length) {
      container.innerHTML = '<div style="font-size:13px;color:var(--text-dim);padding:8px 0;">No line items detected.</div>';
      return;
    }

    container.innerHTML = _rcpLineItems.map((ln, i) => {
      const isMat  = ln.is_material;
      const recoded = ln.shipping_recoded;
      const matBadge = isMat
        ? `<span style="font-family:var(--mono);font-size:9px;background:var(--accent-bg);color:var(--accent);border:1px solid var(--accent-ring);border-radius:8px;padding:1px 6px;margin-left:6px;">material</span>`
        : '';
      const recodeBadge = recoded
        ? `<span style="font-family:var(--mono);font-size:9px;background:var(--surface2);color:var(--text-dim);border:1px solid var(--border);border-radius:8px;padding:1px 6px;margin-left:4px;">shipping recoded</span>`
        : '';
      return `<div style="display:grid;grid-template-columns:1fr 200px 80px;gap:8px;align-items:center;padding:7px 0;border-bottom:1px solid var(--border);">
        <div>
          <span style="font-size:13px;color:var(--text);">${ln.description || '—'}</span>
          ${matBadge}${recodeBadge}
          ${ln.qty && ln.qty !== 1 ? `<span style="font-family:var(--mono);font-size:10px;color:var(--text-dim);margin-left:6px;">×${ln.qty}</span>` : ''}
        </div>
        <select onchange="_rcpLineItems[${i}].account_id=parseInt(this.value);_rcpLineItems[${i}].is_material=(this.options[this.selectedIndex].text.includes('Raw Material')||this.options[this.selectedIndex].text.includes('Finished Goods'));rcpRenderLines();"
          style="background:var(--surface2);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:11px;padding:5px 8px;outline:none;width:100%;">
          ${acctOpts().replace(`value="${ln.account_id}"`, `value="${ln.account_id}" selected`)}
        </select>
        <div style="text-align:right;font-family:var(--mono);font-size:13px;color:var(--text);">${dgMoney(ln.amount||0)}</div>
      </div>`;
    }).join('');
  }

  async function rcpPostExpense() {
    const r   = _rcpParsed;
    const msg = document.getElementById('rcp-action-msg');
    if (!r || !_rcpStoredFilename) return;

    // Guard: don't double-post if already successful
    if (msg.dataset.posted === '1') return;

    msg.style.display = 'block';
    msg.style.background = 'var(--surface2)'; msg.style.color = 'var(--text-soft)';
    msg.textContent = 'Posting to ledger…';

    // Payment method from the dropdown (user may have corrected AI's guess)
    const pmSel = document.getElementById('rcp-payment-method');
    const paymentMethod = pmSel ? pmSel.value : 'other';

    // Build line_items for the new /api/receipts/post-as-expense route.
    // Sales tax paid on purchases is part of the purchase cost. It should not
    // credit a sales-tax liability account, so allocate parsed tax across the
    // selected expense/material lines.
    let lineItems = _rcpLineItems
      .filter(ln => ln.account_id && (ln.amount || 0) > 0)
      .map(ln => ({
        description: ln.description || r.vendor || 'Receipt item',
        amount:      parseFloat((ln.amount || 0).toFixed(4)),
        account_id:  ln.account_id,
      }));

    const purchaseTax = parseFloat(r.tax || 0);
    if (purchaseTax > 0 && lineItems.length) {
      const subtotal = lineItems.reduce((sum, ln) => sum + (parseFloat(ln.amount) || 0), 0);
      let allocated = 0;
      lineItems = lineItems.map((ln, idx) => {
        let share = 0;
        if (idx === lineItems.length - 1) {
          share = purchaseTax - allocated;
        } else {
          share = subtotal > 0 ? purchaseTax * ((parseFloat(ln.amount) || 0) / subtotal) : purchaseTax / lineItems.length;
          share = Math.round(share * 10000) / 10000;
          allocated += share;
        }
        return {
          ...ln,
          amount: parseFloat(((parseFloat(ln.amount) || 0) + share).toFixed(4)),
        };
      });
    }

    const liabilityLine = lineItems.find(ln => {
      const acct = _rcpAccounts.find(a => a.id === ln.account_id);
      return acct && acct.account_type === 'liability';
    });
    if (liabilityLine) {
      msg.style.background = 'var(--warn-bg)'; msg.style.color = 'var(--warn)';
      msg.textContent = 'Choose an expense or material account for purchases, not a tax liability account.';
      return;
      }

    if (!lineItems.length) {
      msg.style.background = 'var(--warn-bg)'; msg.style.color = 'var(--warn)';
      msg.textContent = 'No line items with amounts to post. Check account assignments above.';
      return;
    }

    try {
      const res  = await fetch('/api/receipts/post-as-expense', {
        method: 'POST', headers: {'Content-Type':'application/json'},
        body: JSON.stringify({
          stored_filename: _rcpStoredFilename,
          vendor:          r.vendor  || '',
          date:            r.date    || new Date().toISOString().slice(0,10),
          payment_method:  paymentMethod,
          line_items:      lineItems,
          notes:           r.notes   || null,
        }),
      });
      const data = await res.json();
      if (data.ok) {
        msg.style.background = 'var(--accent-bg)'; msg.style.color = 'var(--accent)';
        msg.textContent = `✓ Posted to ledger — txn #${data.transaction_id}`;
        msg.dataset.posted = '1';
        // Disable the Post button to prevent double-posting
        const postBtn = document.querySelector('[onclick="rcpPostExpense()"]');
        if (postBtn) { postBtn.disabled = true; postBtn.style.opacity = '.5'; }
      } else {
        msg.style.background = 'var(--err-bg)'; msg.style.color = 'var(--err)';
        msg.textContent = data.error || 'Error posting expense.';
      }
    } catch(e) {
      msg.style.background = 'var(--err-bg)'; msg.style.color = 'var(--err)';
      msg.textContent = 'Network error: ' + e.message;
    }
  }

  async function rcpImportMaterials() {
    const matLines = _rcpLineItems.filter(l => l.is_material);
    if (!matLines.length) return;

    const msg = document.getElementById('rcp-action-msg');
    msg.style.display = 'block';
    msg.style.background = 'var(--surface2)'; msg.style.color = 'var(--text-soft)';
    msg.textContent = `Importing ${matLines.length} material${matLines.length > 1 ? 's' : ''}…`;

    const results = [];
    const vendor = _rcpParsed?.vendor || '';

    for (const ln of matLines) {
      const desc    = (ln.description || '').trim();
      const amount  = parseFloat(ln.amount || 0);
      const qty     = parseFloat(ln.qty || 1);
      const unitCost = qty > 0 ? round4(amount / qty) : amount;
      // Generate a code from description: uppercase, spaces→dashes, strip specials
      const code = desc.toUpperCase().replace(/[^A-Z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 30)
                 + (vendor ? '-' + vendor.toUpperCase().replace(/[^A-Z0-9]+/g, '').slice(0,8) : '');
      try {
        const res  = await fetch('/api/materials', {
          method: 'POST', headers: {'Content-Type':'application/json'},
          body: JSON.stringify({
            name: desc,
            code: code,
            default_unit_cost: unitCost,
            quantity_on_hand: qty,
            unit_of_measure: 'each',
            vendor: vendor || null,
            notes: `Imported from receipt — ${_rcpParsed?.date || 'unknown date'}`,
            is_active: true,
          }),
        });
        const data = await res.json();
        results.push({ desc, code, unitCost, ok: !!(data.id || data.ok), error: data.error || null });
      } catch(e) {
        results.push({ desc, code, unitCost, ok: false, error: e.message });
      }
    }

    const ok  = results.filter(r => r.ok);
    const err = results.filter(r => !r.ok);

    msg.style.background = ok.length ? 'var(--accent-bg)' : 'var(--err-bg)';
    msg.style.color      = ok.length ? 'var(--accent)'    : 'var(--err)';
    msg.textContent = ok.length
      ? `✓ ${ok.length} material${ok.length > 1 ? 's' : ''} imported.${err.length ? ' ' + err.length + ' already exist (skipped).' : ''}`
      : 'Import failed: ' + (err[0]?.error || 'Unknown error');

    if (ok.length) {
      document.getElementById('rcp-mat-summary').style.display = 'block';
      document.getElementById('rcp-mat-list').innerHTML = results.map(r =>
        `<div style="display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--accent-ring);font-size:12px;">
          <span style="color:var(--text);">${r.desc}</span>
          <span style="font-family:var(--mono);color:${r.ok ? 'var(--accent)' : 'var(--warn)'};">
            ${r.ok ? '✓ ' + r.code : dgIcon('warning', 12) + ' ' + (r.error || 'skipped')}
          </span>
        </div>`
      ).join('');
      _allMaterials = []; // bust BOM cache
    }
  }

  function round4(n) { return Math.round(n * 10000) / 10000; }

  // Hook receipts into showTab
  // (tab load handled via showTab below — just need the panel to exist)
