/* global React, API, useApp */
const { useState, useEffect, useCallback, useRef } = React;

function AllocationManager({ invoiceId, companies }) {
  const [allocations, setAllocations] = useState([]);
  const [adding, setAdding] = useState(false);
  const [form, setForm] = useState({ company_id:'', allocation_type:'pct', allocation_value:'', margin_pct:'', description_override:'' });
  const { toast } = useApp();

  const load = useCallback(() => {
    API.get(`/inbound-allocations?invoice_id=${invoiceId}`).then(setAllocations).catch(()=>{});
  }, [invoiceId]);
  useEffect(() => { load(); }, [load]);

  const f = k => e => setForm(p => ({...p,[k]:e.target.value}));

  async function add() {
    if (!form.company_id || !form.allocation_value) { toast('Select customer and enter value','error'); return; }
    await API.post('/inbound-allocations', { inbound_invoice_id:invoiceId, company_id:form.company_id, allocation_type:form.allocation_type, allocation_value:Number(form.allocation_value), margin_pct:Number(form.margin_pct||0), description_override:form.description_override||null })
      .catch(e => toast(e.error||'Error','error'));
    setAdding(false); setForm({company_id:'',allocation_type:'pct',allocation_value:'',margin_pct:'',description_override:''}); load();
  }

  async function remove(id) {
    await API.del(`/inbound-allocations/${id}`).catch(e => toast(e.error||'Error','error'));
    load();
  }

  const customers = companies.filter(c => c.type !== 'supplier');

  return (
    <div>
      <div style={{fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',textTransform:'uppercase',letterSpacing:'0.08em',marginBottom:8}}>Pass-through billing</div>
      {allocations.length === 0 && <div style={{fontSize:12,color:'var(--fg-subtle)',marginBottom:6}}>No allocations — costs will not be passed through.</div>}
      {allocations.map(a => (
        <div key={a.id} style={{display:'flex',alignItems:'center',gap:8,padding:'5px 0',borderBottom:'1px solid var(--border)',fontSize:12}}>
          <span style={{flex:1,fontWeight:500}}>{a.company_name}</span>
          <span className="mono" style={{color:'var(--fg-subtle)',fontSize:11}}>
            {a.allocation_type==='pct'?`${a.allocation_value}%`:`€${Number(a.allocation_value).toFixed(2)}`}
            {Number(a.margin_pct)>0?` +${a.margin_pct}%`:''}
          </span>
          <span className={`status ${a.status==='billed'?'status--sent':'status--draft'}`} style={{fontSize:9}}>{a.status}</span>
          {a.status!=='billed' && <button className="btn btn--danger btn--sm" style={{padding:'1px 6px',fontSize:10}} onClick={()=>remove(a.id)}>×</button>}
        </div>
      ))}
      {adding && (
        <div style={{display:'grid',gridTemplateColumns:'1fr 72px 72px 60px auto auto',gap:5,marginTop:8,alignItems:'end'}}>
          <select className="field-select" style={{fontSize:11}} value={form.company_id} onChange={f('company_id')}>
            <option value="">— customer —</option>
            {customers.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}
          </select>
          <select className="field-select" style={{fontSize:11}} value={form.allocation_type} onChange={f('allocation_type')}>
            <option value="pct">% of total</option>
            <option value="amount">€ fixed</option>
          </select>
          <input className="field-input mono" style={{fontSize:11}} type="number" step="0.01" placeholder={form.allocation_type==='pct'?'% e.g. 50':'€ amount'} value={form.allocation_value} onChange={f('allocation_value')} />
          <input className="field-input mono" style={{fontSize:11}} type="number" step="0.5" placeholder="margin%" value={form.margin_pct} onChange={f('margin_pct')} />
          <button className="btn btn--primary btn--sm" onClick={add}>Add</button>
          <button className="btn btn--ghost btn--sm" onClick={()=>setAdding(false)}>✕</button>
        </div>
      )}
      {!adding && <button className="btn btn--ghost btn--sm" style={{marginTop:6,fontSize:11}} onClick={()=>setAdding(true)}>+ Add allocation</button>}
      {allocations.some(a=>a.status==='pending') && (
        <div style={{marginTop:6,fontSize:11,fontFamily:'var(--font-mono)',color:'var(--ember)'}}>Pending allocations will be invoiced Sunday 23:00 UTC</div>
      )}
    </div>
  );
}

const fmtEur    = v => v == null ? '—' : `€${Number(v).toLocaleString('nl-NL', { minimumFractionDigits:2, maximumFractionDigits:2 })}`;
const fmtDate   = v => v ? new Date(v).toLocaleDateString('nl-NL') : '—';
const fmtAmount = (v, cur) => v == null ? '—' : `${cur === 'EUR' ? '€' : ''}${Number(v).toLocaleString('nl-NL', { minimumFractionDigits:2, maximumFractionDigits:2 })}${cur && cur !== 'EUR' ? ' ' + cur : ''}`;

const DOCTYPE_LABEL = { invoice: 'invoice', receipt: 'receipt', credit_note: 'credit note', other: 'other' };
const DOCTYPE_COLOR = { receipt: 'var(--ember)', credit_note: 'var(--signal)', other: 'var(--fg-subtle)' };

const COST_CATS = ['hosting','software','professional','travel','office','marketing','hardware','subscriptions','other'];
const COST_CAT_LABEL = { hosting:'Hosting', software:'Software', professional:'Professional services', travel:'Travel', office:'Office', marketing:'Marketing', hardware:'Hardware', subscriptions:'Subscriptions', other:'Other' };


function LinkedDocRow({ doc }) {
  const label = DOCTYPE_LABEL[doc.document_type] || doc.document_type || 'file';
  const color = DOCTYPE_COLOR[doc.document_type];
  const filename = doc.notes?.match(/File: (.+)$/)?.[1] || doc.invoice_number || doc.id.slice(0,8);
  return (
    <div style={{ display:'flex', alignItems:'center', gap:10, padding:'6px 0', borderBottom:'1px solid var(--border)' }}>
      <span className="badge" style={{ color, flexShrink:0 }}>{label}</span>
      <span style={{ fontSize:12, color:'var(--fg-subtle)', fontFamily:'var(--font-mono)', flex:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
        {filename}
      </span>
      {doc.file_r2_key && (
        <a className="btn btn--ghost btn--sm" style={{fontSize:'0.7rem', flexShrink:0}}
          href={`/api/upload?key=${encodeURIComponent(doc.file_r2_key)}`} target="_blank">
          View ↗
        </a>
      )}
    </div>
  );
}

function ReviewModal({ invoiceId, companies, paymentMethods, onSave, onClose, onSuppliersChanged }) {
  const [invoice, setInvoice] = useState(null);
  const [form, setForm]       = useState(null);
  const [extracting, setExtracting] = useState(false);
  const [busy, setBusy]       = useState(false);
  const [uploadingProof, setUploadingProof] = useState(false);
  const proofRef = useRef(null);
  const { toast } = useApp();

  useEffect(() => {
    API.get(`/inbound/${invoiceId}`).then(data => {
      setInvoice(data);
      setForm({
        supplier_id:        data.supplier_id || '',
        invoice_number:     data.invoice_number || '',
        document_type:      data.document_type || 'invoice',
        po_number:          data.po_number || '',
        payment_reference:  data.payment_reference || '',
        invoice_date:       data.invoice_date || '',
        due_date:           data.due_date || '',
        subtotal:           data.subtotal || '',
        vat_rate:           data.vat_rate || 0.21,
        vat_amount:         data.vat_amount || '',
        total:              data.total || '',
        currency:           data.currency || 'EUR',
        notes:              data.notes || '',
        status:             data.status || 'pending',
        payment_method_id:  data.payment_method_id || '',
        payment_date:       data.payment_date || '',
        payment_proof_r2_key: data.payment_proof_r2_key || '',
        cost_category:      data.cost_category || 'other',
        business_pct:       data.business_pct ?? 100,
        passthrough_customer_id:  data.passthrough_customer_id || '',
        passthrough_margin_pct:   data.passthrough_margin_pct || 0,
        passthrough_status:       data.passthrough_status || 'none',
        passthrough_outbound_id:  data.passthrough_outbound_id || '',
        // computed — re-set after extract/save
        amount_eur:    data.amount_eur,
        vat_eur:       data.vat_eur,
        exchange_rate: data.exchange_rate,
        reverse_charge: data.reverse_charge,
        ai_extracted:  data.ai_extracted || 0,
      });
    }).catch(() => toast('Could not load invoice', 'error'));
  }, [invoiceId]);

  const f = k => e => setForm(p => ({ ...p, [k]: e.target.value }));

  async function extract() {
    setExtracting(true);
    try {
      const result = await API.post(`/inbound/extract`, { id: invoiceId });
      // Reload full record (children may have changed via consolidation)
      const fresh = await API.get(`/inbound/${invoiceId}`);
      setInvoice(fresh);
      setForm(p => ({
        ...p, ...result,
        supplier_id: result.supplier_id || fresh.supplier_id || p.supplier_id,
        payment_method_id: result.payment_method_id || p.payment_method_id,
        payment_date: result.payment_date || p.payment_date,
        status: fresh.status,
      }));
      // If a new supplier was created, reload the companies list so the dropdown updates
      if (result.auto_created_supplier) onSuppliersChanged?.();
      const extra = [
        result.reverse_charge && 'reverse charge detected',
        fresh.status === 'paid' && 'auto-marked paid',
        result.auto_created_supplier && `new supplier "${result.auto_created_supplier_name}" created — pending approval`,
      ].filter(Boolean).join(' · ');
      toast('AI extraction complete' + (extra ? ' — ' + extra : ''));
    } catch (e) { toast(e.error || 'Extraction failed', 'error'); }
    finally { setExtracting(false); }
  }

  async function uploadProof(file) {
    if (!file) return;
    setUploadingProof(true);
    try {
      const fd = new FormData();
      fd.append('file', file);
      const res = await fetch('/api/upload?type=payment_proof', { method:'POST', body:fd });
      const data = await res.json();
      if (!res.ok) throw data;
      setForm(p => ({ ...p, payment_proof_r2_key: data.key }));
      toast('Proof uploaded');
    } catch (e) { toast(e.error || 'Upload failed', 'error'); }
    finally { setUploadingProof(false); }
  }

  async function save(statusOverride) {
    setBusy(true);
    try {
      const payload = { ...form, status: statusOverride || form.status };
      if (statusOverride === 'paid' && !payload.payment_date) {
        payload.payment_date = new Date().toISOString().split('T')[0];
      }
      await API.put(`/inbound/${invoiceId}`, payload);
      toast(statusOverride === 'paid' ? 'Marked as paid' : 'Invoice updated');
      onSave();
    } catch (e) { toast(e.error || 'Error', 'error'); }
    finally { setBusy(false); }
  }

  if (!form) return (
    <div className="modal-overlay">
      <div className="modal" style={{display:'flex',alignItems:'center',justifyContent:'center',minHeight:120}}>
        <span className="text-muted text-mono" style={{fontSize:12}}>Loading…</span>
      </div>
    </div>
  );

  const children = invoice?.children || [];
  const supplierRecord = form.supplier_id ? companies.find(c => c.id === form.supplier_id) : null;
  const supplierPending = supplierRecord && !supplierRecord.approved;

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal modal--lg">
        <div className="modal-head">
          <span className="modal-title">
            Review · {DOCTYPE_LABEL[form.document_type] || form.document_type}
            {form.invoice_number ? ` · ${form.invoice_number}` : ''}
            {invoice?.ref_id && <span style={{marginLeft:10,fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',fontWeight:400,letterSpacing:'0.08em'}}>{invoice.ref_id}</span>}
          </span>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">

          {/* Pending supplier warning */}
          {supplierPending && (
            <div style={{
              display:'flex', alignItems:'center', gap:10,
              padding:'10px 14px', marginBottom:16, borderRadius:6,
              background:'rgba(255,168,107,0.10)', border:'1px solid rgba(255,168,107,0.35)',
            }}>
              <span style={{fontSize:15}}>⚠</span>
              <div style={{flex:1, fontSize:12, fontFamily:'var(--font-mono)', color:'var(--ember)'}}>
                <strong>{supplierRecord.name}</strong> was auto-created and is pending approval.
                Review in <strong>Relations</strong> before processing this invoice.
              </div>
            </div>
          )}

          {/* PDF actions */}
          {invoice?.file_r2_key && (
            <div style={{marginBottom:16,display:'flex',gap:8,alignItems:'center',flexWrap:'wrap'}}>
              <a className="btn btn--ghost btn--sm"
                href={`/api/upload?key=${encodeURIComponent(invoice.file_r2_key)}`} target="_blank">
                View PDF ↗
              </a>
              <button className="btn btn--ghost btn--sm" onClick={extract} disabled={extracting}>
                {extracting ? '⟳ Extracting…' : '✦ AI extract'}
              </button>
              {form.ai_extracted ? <span style={{fontSize:10,fontFamily:'var(--font-mono)',color:'var(--signal)'}}>AI-filled</span> : null}
            </div>
          )}

          {/* Multi-currency / RC info bar */}
          {form.currency && form.currency !== 'EUR' && (
            <div style={{display:'flex',gap:8,alignItems:'center',padding:'8px 12px',background:'rgba(111,227,209,0.07)',borderRadius:6,marginBottom:16,fontSize:12,fontFamily:'var(--font-mono)'}}>
              <span style={{color:'var(--signal)'}}>
                {form.currency} invoice
                {form.exchange_rate && form.exchange_rate !== 1 ? ` · 1 ${form.currency} = €${Number(form.exchange_rate).toFixed(4)}` : ''}
              </span>
              {form.amount_eur != null && <span style={{color:'var(--fg-subtle)'}}>· subtotal {fmtEur(form.amount_eur)} EUR</span>}
              {form.reverse_charge ? (
                <span style={{marginLeft:'auto',color:'var(--ember)',fontWeight:600}}>BTW VERLEGD · {fmtEur(form.vat_eur)} self-assessed @ 21%</span>
              ) : null}
            </div>
          )}

          {/* Invoice fields */}
          <div className="form-grid">
            <div className="field field--full">
              <label className="field-label">Supplier</label>
              <select className="field-select" value={form.supplier_id} onChange={e => {
                const id = e.target.value;
                const co = companies.find(c => c.id === id);
                setForm(p => ({
                  ...p,
                  supplier_id: id,
                  cost_category: (co?.default_cost_category && (p.cost_category === 'other' || !p.cost_category))
                    ? co.default_cost_category : p.cost_category,
                  payment_method_id: (co?.default_payment_method_id && !p.payment_method_id)
                    ? co.default_payment_method_id : p.payment_method_id,
                  business_pct: (co?.default_business_pct != null && p.business_pct === 100)
                    ? co.default_business_pct : p.business_pct,
                }));
              }}>
                <option value="">— unmatched —</option>
                {companies.filter(c => c.type !== 'customer').map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
            <div className="field">
              <label className="field-label">Document type</label>
              <select className="field-select" value={form.document_type} onChange={f('document_type')}>
                <option value="invoice">Invoice</option>
                <option value="receipt">Receipt</option>
                <option value="credit_note">Credit note</option>
                <option value="other">Other</option>
              </select>
            </div>
            <div className="field">
              <label className="field-label">Invoice / document number</label>
              <input className="field-input" value={form.invoice_number} onChange={f('invoice_number')} />
            </div>
            <div className="field">
              <label className="field-label">PO number</label>
              <input className="field-input" placeholder="Purchase order #" value={form.po_number} onChange={f('po_number')} />
            </div>
            <div className="field">
              <label className="field-label">Payment reference</label>
              <input className="field-input" placeholder="Bank / payment reference" value={form.payment_reference} onChange={f('payment_reference')} />
            </div>
            <div className="field">
              <label className="field-label">Currency</label>
              <select className="field-select" value={form.currency} onChange={f('currency')}>
                {['EUR','USD','GBP','CHF','SEK','NOK','DKK'].map(c => <option key={c} value={c}>{c}</option>)}
              </select>
            </div>
            <div className="field">
              <label className="field-label">Invoice date</label>
              <input className="field-input" type="date" value={form.invoice_date} onChange={f('invoice_date')} />
            </div>
            <div className="field">
              <label className="field-label">Due date</label>
              <input className="field-input" type="date" value={form.due_date} onChange={f('due_date')} />
            </div>
            <div className="field">
              <label className="field-label">Subtotal (excl. VAT)</label>
              <input className="field-input" type="number" step="0.01" value={form.subtotal} onChange={f('subtotal')} />
            </div>
            <div className="field">
              <label className="field-label">VAT rate</label>
              <select className="field-select" value={form.vat_rate} onChange={f('vat_rate')}>
                <option value="0.21">21%</option><option value="0.09">9%</option><option value="0.00">0% / reverse charge</option>
              </select>
            </div>
            <div className="field">
              <label className="field-label">VAT amount</label>
              <input className="field-input" type="number" step="0.01" value={form.vat_amount} onChange={f('vat_amount')} />
            </div>
            <div className="field">
              <label className="field-label">Total (incl. VAT)</label>
              <input className="field-input" type="number" step="0.01" value={form.total} onChange={f('total')} />
            </div>
            <div className="field">
              <label className="field-label">Cost category</label>
              <select className="field-select" value={form.cost_category} onChange={f('cost_category')}>
                {COST_CATS.map(c => <option key={c} value={c}>{COST_CAT_LABEL[c]}</option>)}
              </select>
            </div>
            <div className="field">
              <label className="field-label">Business use %</label>
              <input className="field-input" type="number" min="0" max="100" value={form.business_pct} onChange={f('business_pct')} />
            </div>
            <div className="field field--full">
              <label className="field-label">Notes</label>
              <textarea className="field-textarea" rows={2} value={form.notes} onChange={f('notes')} />
            </div>
          </div>

          {/* Payment section */}
          <div style={{marginTop:20,paddingTop:16,borderTop:'1px solid var(--border)'}}>
            <div style={{fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',textTransform:'uppercase',letterSpacing:'0.08em',marginBottom:10}}>Payment</div>
            <div className="form-grid">
              <div className="field">
                <label className="field-label">Payment method</label>
                <select className="field-select" value={form.payment_method_id} onChange={f('payment_method_id')}>
                  <option value="">— not set —</option>
                  {paymentMethods.map(m => (
                    <option key={m.id} value={m.id}>{m.name}{m.account_ref ? ` (${m.account_ref})` : ''}</option>
                  ))}
                </select>
              </div>
              <div className="field">
                <label className="field-label">Payment date</label>
                <div style={{position:'relative',display:'flex',alignItems:'center'}}>
                  <input className="field-input" type="date" value={form.payment_date} onChange={f('payment_date')} style={{paddingRight:'2rem'}} />
                  {form.invoice_date && (
                    <button
                      type="button"
                      title="Copy invoice date"
                      onClick={() => setForm(p => ({...p, payment_date: p.invoice_date}))}
                      style={{position:'absolute',right:'2rem',background:'none',border:'none',cursor:'pointer',color:'var(--accent)',fontSize:'1rem',lineHeight:1,padding:'0 4px',opacity:0.7}}
                      onMouseEnter={e=>e.currentTarget.style.opacity=1}
                      onMouseLeave={e=>e.currentTarget.style.opacity=0.7}
                    >+</button>
                  )}
                </div>
              </div>
              <div className="field" style={{display:'flex',flexDirection:'column',justifyContent:'flex-end'}}>
                <label className="field-label">Proof of payment</label>
                <div style={{display:'flex',gap:8,alignItems:'center'}}>
                  <input ref={proofRef} type="file" accept=".pdf,.jpg,.jpeg,.png" style={{display:'none'}}
                    onChange={e => uploadProof(e.target.files[0])} />
                  <button className="btn btn--ghost btn--sm" style={{fontSize:'0.72rem'}}
                    disabled={uploadingProof}
                    onClick={() => proofRef.current?.click()}>
                    {uploadingProof ? 'Uploading…' : form.payment_proof_r2_key ? 'Replace proof' : 'Upload proof'}
                  </button>
                  {form.payment_proof_r2_key && (
                    <a className="btn btn--ghost btn--sm" style={{fontSize:'0.72rem'}}
                      href={`/api/upload?key=${encodeURIComponent(form.payment_proof_r2_key)}`} target="_blank">
                      View ↗
                    </a>
                  )}
                </div>
              </div>
            </div>
          </div>

          {/* Pass-through billing */}
          <div style={{marginTop:20,paddingTop:16,borderTop:'1px solid var(--border)'}}>
            <AllocationManager invoiceId={invoiceId} companies={companies} />
          </div>

          {/* Linked documents (children) */}
          {children.length > 0 && (
            <div style={{marginTop:20,paddingTop:16,borderTop:'1px solid var(--border)'}}>
              <div style={{fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',textTransform:'uppercase',letterSpacing:'0.08em',marginBottom:8}}>
                Linked documents ({children.length})
              </div>
              {children.map(ch => <LinkedDocRow key={ch.id} doc={ch} />)}
            </div>
          )}

        </div>
        <div className="modal-foot">
          <button type="button" className="btn btn--ghost" onClick={onClose}>Cancel</button>
          <button type="button" className="btn btn--ghost" disabled={busy} onClick={() => save('approved')}>Approve</button>
          <button type="button" className="btn btn--primary" disabled={busy}
            style={{background: form.status === 'paid' ? 'rgba(111,227,209,0.15)' : ''}}
            onClick={() => save('paid')}>
            {form.status === 'paid' ? '✓ Paid' : 'Mark paid'}
          </button>
          <button type="button" className="btn btn--primary" disabled={busy} onClick={() => save()}>Save</button>
        </div>
      </div>
    </div>
  );
}

const TODAY    = new Date().toISOString().split('T')[0];
const PAGE_SIZES = [20, 50, 100, 250];

function SortTh({ col, label, sort, onSort, style }) {
  const active = sort.col === col;
  return (
    <th
      style={{ cursor: 'pointer', userSelect: 'none', whiteSpace: 'nowrap', ...style }}
      onClick={() => onSort(col)}
    >
      {label}
      <span style={{
        marginLeft: 4,
        fontSize: 9,
        opacity: active ? 1 : 0.25,
        color: active ? 'var(--signal)' : 'inherit',
        fontFamily: 'var(--font-mono)',
      }}>
        {active ? (sort.dir === 'asc' ? '▲' : '▼') : '▲▼'}
      </span>
    </th>
  );
}

function sortInvoices(list, sort, coMap) {
  const dir = sort.dir === 'asc' ? 1 : -1;
  return [...list].sort((a, b) => {
    let av, bv;
    switch (sort.col) {
      case 'supplier':
        av = coMap[a.supplier_id] || '';
        bv = coMap[b.supplier_id] || '';
        return dir * av.localeCompare(bv);
      case 'document_type':
        av = DOCTYPE_LABEL[a.document_type] || a.document_type || '';
        bv = DOCTYPE_LABEL[b.document_type] || b.document_type || '';
        return dir * av.localeCompare(bv);
      case 'invoice_number':
        av = a.invoice_number || '';
        bv = b.invoice_number || '';
        return dir * av.localeCompare(bv);
      case 'total':
        av = Number(a.amount_eur ?? a.total ?? 0);
        bv = Number(b.amount_eur ?? b.total ?? 0);
        return dir * (av - bv);
      case 'due_date':
        av = a.due_date || '9999';
        bv = b.due_date || '9999';
        return dir * av.localeCompare(bv);
      case 'status':
        av = a.status || '';
        bv = b.status || '';
        return dir * av.localeCompare(bv);
      case 'invoice_date':
      default:
        av = a.invoice_date || '';
        bv = b.invoice_date || '';
        return dir * av.localeCompare(bv);
    }
  });
}

function InboundInvoices() {
  const [invoices, setInvoices]         = useState([]);
  const [companies, setCompanies]       = useState([]);
  const [paymentMethods, setPayMethods] = useState([]);
  const [filter, setFilter]             = useState('all');
  const [sort, setSort]                 = useState({ col: 'invoice_date', dir: 'desc' });
  const [fSupplier, setFSupplier]       = useState('');
  const [fType, setFType]               = useState('');
  const [fCategory, setFCategory]       = useState('');
  const [pageSize, setPageSize]         = useState(50);
  const [page, setPage]                 = useState(1);
  const [modal, setModal]               = useState(null);
  const [uploading, setUploading]       = useState(false);
  const [drag, setDrag]                 = useState(false);
  const dropRef = useRef(null);
  const { toast } = useApp();

  const load = useCallback(() => {
    API.get('/inbound').then(setInvoices).catch(() => {});
  }, []);

  const loadCompanies = useCallback(() => {
    API.get('/companies').then(setCompanies).catch(() => {});
  }, []);

  useEffect(() => {
    load();
    loadCompanies();
    API.get('/payment_methods').then(setPayMethods).catch(() => {});
  }, [load, loadCompanies]);

  // Reset to page 1 whenever any filter/sort changes
  useEffect(() => { setPage(1); }, [filter, sort, fSupplier, fType, fCategory, pageSize]);

  function handleSort(col) {
    setSort(s => s.col === col
      ? { col, dir: s.dir === 'asc' ? 'desc' : 'asc' }
      : { col, dir: 'desc' }
    );
  }

  async function uploadFile(file) {
    if (!file || !file.type.includes('pdf')) { toast('PDF files only', 'error'); return; }
    setUploading(true);
    try {
      const form = new FormData();
      form.append('file', file);
      form.append('source', 'upload');
      await API.upload('/inbound', form);
      toast('Invoice uploaded — open to review');
      load();
    } catch (e) { toast(e.error || 'Upload failed', 'error'); }
    finally { setUploading(false); }
  }

  function onDrop(e) {
    e.preventDefault(); setDrag(false);
    uploadFile(e.dataTransfer.files[0]);
  }

  async function del(inv) {
    if (!confirm('Delete this invoice and all its linked documents?')) return;
    await API.del(`/inbound/${inv.id}`).catch(e => toast(e.error || 'Error', 'error'));
    toast('Invoice deleted'); load();
  }

  const coMap = Object.fromEntries(companies.map(c => [c.id, c.name]));
  const pmMap = Object.fromEntries(paymentMethods.map(m => [m.id, m.name]));

  const counts = {
    pending:  invoices.filter(i => i.status === 'pending').length,
    approved: invoices.filter(i => i.status === 'approved').length,
    paid:     invoices.filter(i => i.status === 'paid').length,
  };

  // Status filter → column filters → sort → paginate
  const afterStatus = invoices.filter(i => filter === 'all' || i.status === filter);
  const afterFilters = afterStatus.filter(i => {
    if (fSupplier   && i.supplier_id !== fSupplier)            return false;
    if (fType       && i.document_type !== fType)               return false;
    if (fCategory   && i.cost_category !== fCategory)           return false;
    return true;
  });
  const sorted   = sortInvoices(afterFilters, sort, coMap);
  const total    = sorted.length;
  const pages    = Math.max(1, Math.ceil(total / pageSize));
  const safePage = Math.min(page, pages);
  const visible  = sorted.slice((safePage - 1) * pageSize, safePage * pageSize);

  const activeFilters = [fSupplier, fType, fCategory].filter(Boolean).length;

  const TABS = [
    ['all',      'All'],
    ['pending',  `Pending${counts.pending  ? ` (${counts.pending})`  : ''}`],
    ['approved', `Approved${counts.approved ? ` (${counts.approved})` : ''}`],
    ['paid',     `Paid${counts.paid        ? ` (${counts.paid})`      : ''}`],
  ];

  // Unique suppliers that appear in the status-filtered list (for the filter dropdown)
  const supplierOptions = [...new Map(
    afterStatus
      .filter(i => i.supplier_id && coMap[i.supplier_id])
      .map(i => [i.supplier_id, coMap[i.supplier_id]])
  ).entries()].sort((a, b) => a[1].localeCompare(b[1]));

  const SH = ({ col, label, style }) => (
    <SortTh col={col} label={label} sort={sort} onSort={handleSort} style={style} />
  );

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Invoices — inbound</h1>
          <div className="page-subtitle">Supplier invoices · inbox: invoice@lake-project.com</div>
        </div>
      </div>

      <div
        ref={dropRef}
        className={`dropzone ${drag ? 'drag-over' : ''}`}
        style={{marginBottom:24}}
        onClick={() => { const inp = document.createElement('input'); inp.type='file'; inp.accept='.pdf'; inp.onchange = e => uploadFile(e.target.files[0]); inp.click(); }}
        onDragOver={e => { e.preventDefault(); setDrag(true); }}
        onDragLeave={() => setDrag(false)}
        onDrop={onDrop}
      >
        <div className="dropzone-icon">{uploading ? '⟳' : '↑'}</div>
        <div className="dropzone-text">{uploading ? 'Uploading…' : 'Drop a PDF here, or click to upload'}</div>
        <div className="dropzone-hint">Or forward supplier invoices to invoice@lake-project.com</div>
      </div>

      <div style={{display:'flex',alignItems:'center',gap:0,marginBottom:0,flexWrap:'wrap'}}>
        <div className="tabs" style={{flex:1,marginBottom:0}}>
          {TABS.map(([v, l]) => (
            <button key={v} className={`tab ${filter===v?'is-active':''}`}
              onClick={() => { setFilter(v); setFSupplier(''); setFType(''); setFCategory(''); }}>
              {l}
            </button>
          ))}
        </div>
      </div>

      {/* Filter bar */}
      <div style={{
        display:'flex', gap:8, alignItems:'center', flexWrap:'wrap',
        padding:'10px 0', marginBottom:12,
      }}>
        <select className="field-select" style={{flex:'1 1 160px',minWidth:0,maxWidth:220,fontSize:12}}
          value={fSupplier} onChange={e => setFSupplier(e.target.value)}>
          <option value="">All suppliers</option>
          {supplierOptions.map(([id, name]) => <option key={id} value={id}>{name}</option>)}
        </select>
        <select className="field-select" style={{flex:'1 1 120px',minWidth:0,maxWidth:160,fontSize:12}}
          value={fType} onChange={e => setFType(e.target.value)}>
          <option value="">All types</option>
          <option value="invoice">Invoice</option>
          <option value="receipt">Receipt</option>
          <option value="credit_note">Credit note</option>
          <option value="other">Other</option>
        </select>
        <select className="field-select" style={{flex:'1 1 140px',minWidth:0,maxWidth:200,fontSize:12}}
          value={fCategory} onChange={e => setFCategory(e.target.value)}>
          <option value="">All categories</option>
          {COST_CATS.map(c => <option key={c} value={c}>{COST_CAT_LABEL[c]}</option>)}
        </select>
        {activeFilters > 0 && (
          <button className="btn btn--ghost btn--sm" style={{fontSize:11,flexShrink:0}}
            onClick={() => { setFSupplier(''); setFType(''); setFCategory(''); }}>
            Clear filters ({activeFilters})
          </button>
        )}
        <div style={{marginLeft:'auto',display:'flex',alignItems:'center',gap:6,flexShrink:0}}>
          <span style={{fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)'}}>Rows</span>
          <select className="field-select" style={{width:72,fontSize:12,padding:'4px 6px'}}
            value={pageSize} onChange={e => setPageSize(Number(e.target.value))}>
            {PAGE_SIZES.map(n => <option key={n} value={n}>{n}</option>)}
          </select>
        </div>
      </div>

      <div className="card" style={{margin:0}}>
        <div className="table-wrap">
          <table className="data-table">
            <thead><tr>
              <SH col="supplier"       label="Supplier" />
              <SH col="invoice_number" label="Invoice #" />
              <SH col="invoice_date"   label="Date" />
              <SH col="due_date"       label="Due" />
              <SH col="total"          label="Amount" style={{textAlign:'right'}} />
              <th>EUR equiv.</th>
              <th>Payment</th>
              <SH col="status"         label="Status" />
              <th></th>
            </tr></thead>
            <tbody>
              {visible.length === 0 && (
                <tr><td colSpan={9}><div className="empty-state">No inbound invoices</div></td></tr>
              )}
              {visible.map(inv => {
                const unpaid  = inv.status === 'pending' || inv.status === 'approved';
                const overdue = unpaid && inv.due_date && inv.due_date < TODAY;
                return (
                  <tr key={inv.id} style={{cursor:'pointer'}} onClick={() => setModal(inv.id)}>
                    <td>
                      <div>{inv.supplier_id ? (coMap[inv.supplier_id] || '—') : <span className="muted">Unmatched</span>}</div>
                      {inv.child_count > 0 && (
                        <div style={{fontSize:10,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',marginTop:2}}>
                          +{inv.child_count} doc{inv.child_count !== 1 ? 's' : ''}
                        </div>
                      )}
                    </td>
                    <td>
                      <div className="mono" style={{fontSize:12}}>{inv.invoice_number || <span className="muted">—</span>}</div>
                      {inv.ref_id && <div style={{fontSize:10,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',marginTop:2,letterSpacing:'0.06em'}}>{inv.ref_id}</div>}
                    </td>
                    <td className="mono" style={{whiteSpace:'nowrap'}}>{fmtDate(inv.invoice_date)}</td>
                    <td style={{whiteSpace:'nowrap'}}>
                      {unpaid ? (
                        inv.due_date ? (
                          <div style={{display:'flex',alignItems:'center',gap:6}}>
                            <span className="mono" style={{fontSize:11}}>{fmtDate(inv.due_date)}</span>
                            {overdue && (
                              <span style={{
                                fontSize:9,fontFamily:'var(--font-mono)',fontWeight:700,
                                letterSpacing:'0.06em',textTransform:'uppercase',
                                padding:'2px 6px',borderRadius:10,
                                background:'rgba(255,60,60,0.18)',color:'#ff4444',
                                border:'1px solid rgba(255,60,60,0.35)',
                                flexShrink:0,
                              }}>overdue</span>
                            )}
                          </div>
                        ) : <span className="muted" style={{fontSize:11}}>—</span>
                      ) : <span className="muted" style={{fontSize:11}}>—</span>}
                    </td>
                    <td className="mono" style={{textAlign:'right'}}>
                      {fmtAmount(inv.total, inv.currency)}
                      {inv.reverse_charge ? <span title="BTW verlegd" style={{marginLeft:4,color:'var(--ember)',fontSize:10,fontFamily:'var(--font-mono)'}}>RC</span> : null}
                    </td>
                    <td className="mono" style={{color:'var(--fg-subtle)'}}>
                      {inv.currency && inv.currency !== 'EUR' && inv.amount_eur ? fmtEur(inv.amount_eur) : '—'}
                    </td>
                    <td>
                      {inv.payment_method_id && pmMap[inv.payment_method_id]
                        ? <span style={{fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)'}}>{pmMap[inv.payment_method_id]}</span>
                        : <span className="muted" style={{fontSize:11}}>—</span>}
                    </td>
                    <td><span className={`status status--${inv.status}`}>{inv.status}</span></td>
                    <td>
                      <div className="row-actions" onClick={e => e.stopPropagation()}>
                        <button className="btn btn--ghost btn--sm" onClick={() => setModal(inv.id)}>Review</button>
                        <button className="btn btn--danger btn--sm" onClick={() => del(inv)}>Del</button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* Pagination footer */}
        <div style={{
          display:'flex',alignItems:'center',justifyContent:'space-between',
          padding:'10px 16px',borderTop:'1px solid var(--border)',
          fontSize:11,fontFamily:'var(--font-mono)',color:'var(--fg-subtle)',
        }}>
          <span>
            {total === 0 ? 'No results' : `${(safePage - 1) * pageSize + 1}–${Math.min(safePage * pageSize, total)} of ${total}`}
          </span>
          <div style={{display:'flex',gap:4,alignItems:'center'}}>
            <button
              className="btn btn--ghost btn--sm"
              style={{padding:'2px 8px',fontSize:13}}
              disabled={safePage <= 1}
              onClick={() => setPage(p => Math.max(1, p - 1))}>
              ‹
            </button>
            <span style={{padding:'0 8px'}}>
              {safePage} / {pages}
            </span>
            <button
              className="btn btn--ghost btn--sm"
              style={{padding:'2px 8px',fontSize:13}}
              disabled={safePage >= pages}
              onClick={() => setPage(p => Math.min(pages, p + 1))}>
              ›
            </button>
          </div>
        </div>
      </div>

      {modal && (
        <ReviewModal
          invoiceId={modal}
          companies={companies}
          paymentMethods={paymentMethods}
          onSave={() => { load(); setModal(null); }}
          onClose={() => setModal(null)}
          onSuppliersChanged={loadCompanies}
        />
      )}
    </div>
  );
}
window.InboundInvoices = InboundInvoices;
