// Bills — professional commitments + receipts manager.
// Sortable columns, search, category/status filters, and an edit panel with a category picker.

function StatCard({ label, value, sub, icon, tint }) {
  return (
    <div className="card card-pad rise" style={{ flex: 1 }}>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start' }}>
        <span className="lbl" style={{ fontSize:13, color:'var(--fg-2)', fontWeight:500 }}>{label}</span>
        <span className="ic-chip" style={{ background: tintBg(tint), width:34, height:34, borderRadius:10, display:'grid', placeItems:'center' }}>
          <Icon name={icon} size={17} color={tintFg(tint)} />
        </span>
      </div>
      <div className="zd-stat" style={{ fontSize:27, margin:'12px 0 3px' }}>{value}</div>
      <div style={{ fontSize:12, color:'var(--fg-3)' }}>{sub}</div>
    </div>
  );
}

const STATUS_OPTS = [
  { value:'all',     label:'All statuses' },
  { value:'overdue', label:'Overdue',  tint:'red' },
  { value:'pending', label:'Pending',  tint:'gold' },
  { value:'paid',    label:'Paid',     tint:'green' },
];
const stCls = s => s === 'overdue' ? 'b-red' : s === 'paid' ? 'b-green' : 'b-gold';
const statusRank = { overdue:0, pending:1, paid:2 };

// ---------- Edit / detail drawer ----------
function fmtSize(b) { if (!b) return ''; return b >= 1048576 ? (b / 1048576).toFixed(1) + ' MB' : Math.max(1, Math.round(b / 1024)) + ' KB'; }
function attIcon(name) { const e = (name.split('.').pop() || '').toLowerCase(); if (['jpg','jpeg','png','gif','webp','heic'].includes(e)) return 'image'; if (e === 'pdf') return 'file-text'; return 'file'; }
function openAttachment(a) {
  if (a.url) { window.open(a.url, '_blank'); return; }
  const ext = (a.name.split('.').pop() || 'FILE').toUpperCase();
  const html = '<!doctype html><title>' + a.name + '</title><body style="margin:0;height:100vh;display:grid;place-items:center;background:#1c1b20;font-family:system-ui,sans-serif;color:#d3d1cc"><div style="text-align:center"><div style="font:700 20px/1 system-ui;letter-spacing:.1em;color:#c19a4b">' + ext + '</div><div style="margin-top:14px;font-size:15px">' + a.name + '</div><div style="margin-top:6px;font-size:12px;color:#7d7b79">Preview not available in this demo</div></div></body>';
  window.open(URL.createObjectURL(new Blob([html], { type:'text/html' })), '_blank');
}
function AttachmentList({ items, onRemove, onAdd }) {
  return (
    <div className="att-list">
      {(items || []).map(a => (
        <div className="att-row" key={a.id}>
          <span className="att-ic"><Icon name={attIcon(a.name)} size={16} color="var(--fg-3)" /></span>
          <div className="att-meta"><div className="an">{a.name}</div><div className="as">{fmtSize(a.size)}</div></div>
          <button className="iconbtn" title="View" onClick={() => openAttachment(a)}><Icon name="eye" size={16} /></button>
          {onRemove && <button className="iconbtn danger" title="Remove" onClick={() => onRemove(a.id)}><Icon name="x" size={15} /></button>}
        </div>
      ))}
      {onAdd && <button className="att-add" onClick={onAdd}><Icon name="paperclip" size={15} /> Attach a file</button>}
    </div>
  );
}

function BillDrawer({ bill, editing, onClose, onSave, onEdit, onDelete, onIgnore, dismissed, creating }) {
  const D = window.ZD_DATA;
  const [form, setForm] = useState(bill);
  const fileRef = useRef(null);
  useEffect(() => { setForm(bill); }, [bill]);
  if (!bill) return null;

  const catOpts = D.billCategories.map(c => ({ value:c.id, label:c.label, icon:c.icon, tint:c.tint }));
  const ccyOpts = Object.keys(D.fx.rates).map(c => ({ value:c, label:c }));
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const atts = form.attachments || [];
  const addFiles = e => {
    const picked = [...e.target.files].map(f => ({ id:'at' + Date.now() + Math.random().toString(36).slice(2,5), name:f.name, size:f.size, url:URL.createObjectURL(f) }));
    set('attachments', [...atts, ...picked]); e.target.value = '';
  };
  const removeAtt = id => set('attachments', atts.filter(a => a.id !== id));
  const saveForm = () => {
    const cat = D.billCategories.find(c => c.id === form.catId) || {};
    onSave({ ...form, cat: cat.label || form.cat, catTint: cat.tint || form.catTint, icon: cat.icon || form.icon,
      ccy: form.ccy || 'USD', amountVal: parseFloat(String(form.amountVal).replace(/[^0-9.]/g, '')) || 0 });
  };

  return (
    <React.Fragment>
      <div className="scrim" onClick={onClose} />
      <div className="drawer zd-scroll">
        <div className="dhead">
          <IconChip icon={form.icon} tint={form.catTint} size={40} radius={12} />
          <div style={{ flex:1, minWidth:0 }}>
            <div style={{ fontFamily:'var(--font-display)', fontWeight:700, fontSize:18, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{form.merchant || (creating ? 'New bill' : '')}</div>
            <div style={{ fontSize:12.5, color:'var(--fg-3)' }}>{creating ? 'Add a bill' : editing ? 'Editing bill' : form.cat}</div>
          </div>
          <button className="iconbtn" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>

        {!editing ? (
          /* ---------- VIEW ---------- */
          <div className="dbody">
            <div className="field"><div className="k">Amount</div><Money amount={form.amountVal} ccy={form.ccy} align="left" size={30} primaryClass="zd-stat" /></div>
            {form.items && form.items.length > 0 && (
              <div className="field"><div className="k">Itemized · what you’re billed for</div><LineItems items={form.items} ccy={form.ccy} total={form.amountVal} /></div>
            )}
            <div className="drow">
              <div className="field" style={{ flex:1 }}><div className="k">Status</div><div className="v"><span className={`badge ${stCls(form.status)}`}>{form.status}</span></div></div>
              <div className="field" style={{ flex:1 }}><div className="k">Due date</div><div className="v">{form.due}, 2026</div></div>
            </div>
            <div className="field"><div className="k">Category</div>
              <div className="v" style={{ display:'flex', alignItems:'center', gap:8 }}>
                <span className="dd-dot" style={{ background: tintFg(form.catTint) }} />{form.cat}
              </div>
            </div>
            <div className="field"><div className="k">Account</div><div className="v zd-mono" style={{ fontSize:13.5 }}>{form.account}</div></div>
            {form.recurring && <div className="field"><div className="k">Billing</div><div className="v" style={{ display:'flex', alignItems:'center', gap:7 }}><Icon name="repeat" size={15} color="var(--gold-600)" /> Auto-renews monthly</div></div>}
            {atts.length > 0 && (
              <div className="field"><div className="k">Attachments</div><AttachmentList items={atts} /></div>
            )}
            <div className="field"><div className="k">Detected from</div><div className="v" style={{ display:'flex', alignItems:'center', gap:7, color:'var(--gold-600)', fontWeight:600, fontSize:14 }}><Icon name="mail" size={15} color="var(--gold-600)" /> Statement email · {form.merchant}</div></div>
            <div className="field"><div className="k">Source confidence</div>
              <div className="track" style={{ marginTop:8 }}><div className="fill" style={{ width:`${form.confidence}%` }} /></div>
              <div style={{ fontSize:11.5, color:'var(--fg-3)', marginTop:6 }}>{form.confidence}% — matched amount, due date and account</div>
            </div>
            <div className="drawer-foot" style={{ flexWrap:'wrap' }}>
              {form.payLink && form.status !== 'paid' && <button className="btn btn-primary" style={{ width:'100%', justifyContent:'center', marginBottom:4 }} onClick={() => openAttachment({ name:'Secure payment', url:form.payLink })}><Icon name="credit-card" size={16} /> Pay now — secure gateway</button>}
              <Btn variant="primary" icon="pencil" style={{ flex:1, justifyContent:'center' }} onClick={onEdit}>Edit details</Btn>
              <Btn variant="secondary" icon={dismissed ? 'rotate-ccw' : 'ban'} onClick={onIgnore}>{dismissed ? 'Un-ignore' : 'Ignore'}</Btn>
              <button className="iconbtn danger" onClick={() => onDelete(form.id)} title="Delete"><Icon name="trash-2" size={17} /></button>
            </div>
          </div>
        ) : (
          /* ---------- EDIT ---------- */
          <div className="dbody">
            <label className="fl">Merchant / service</label>
            <div className="finput"><Icon name="building-2" size={16} color="var(--fg-4)" /><input value={form.merchant} onChange={e => set('merchant', e.target.value)} placeholder="Who is this bill from?" /></div>

            <div className="drow">
              <div style={{ flex:1.4 }}>
                <label className="fl">Amount</label>
                <div className="finput"><span className="fpre">{(CCY_META[form.ccy] || CCY_META.USD).sym}</span><input value={String(form.amountVal ?? '')} onChange={e => set('amountVal', e.target.value)} inputMode="decimal" placeholder="0.00" /></div>
              </div>
              <div style={{ flex:1 }}>
                <label className="fl">Currency</label>
                <Dropdown value={form.ccy || 'USD'} options={ccyOpts} onChange={v => set('ccy', v)} minWidth={'100%'} />
              </div>
            </div>

            {form.ccy && form.ccy !== D.fx.home && (
              <div className="ccy-preview">
                <div className="k">Display preview · {D.fx.home}</div>
                <Money amount={parseFloat(String(form.amountVal).replace(/[^0-9.]/g,'')) || 0} ccy={form.ccy} align="left" size={22} primaryClass="zd-stat" />
              </div>
            )}

            <label className="fl">Due date</label>
            <div className="finput"><Icon name="calendar" size={16} color="var(--fg-4)" /><input type="date" value={form.dueISO} onChange={e => set('dueISO', e.target.value)} /></div>

            <label className="fl">Payment link <span className="fl-opt">optional</span></label>
            <div className="finput"><Icon name="link" size={16} color="var(--fg-4)" /><input value={form.payLink || ''} onChange={e => set('payLink', e.target.value)} placeholder="https://… secure pay gateway" /></div>

            <label className="fl">Category</label>
            <Dropdown value={form.catId} options={catOpts} onChange={v => set('catId', v)} minWidth={'100%'} />

            <div className="toggle-row">
              <div><div className="tr-t">Auto-renew</div><div className="tr-s">Recurring charge every month</div></div>
              <button className={`zswitch ${form.recurring ? 'on' : ''}`} role="switch" aria-checked={!!form.recurring} onClick={() => set('recurring', !form.recurring)}><span className="knob" /></button>
            </div>

            <label className="fl">Status</label>
            <div className="seg-full">
              {['overdue','pending','paid'].map(s => (
                <button key={s} className={form.status === s ? 'on' : ''} onClick={() => set('status', s)}>
                  <span className="dd-dot" style={{ background: s==='overdue'?'var(--red-500)':s==='paid'?'var(--green-500)':'var(--gold-500)' }} />
                  {s[0].toUpperCase()+s.slice(1)}
                </button>
              ))}
            </div>

            <label className="fl">Account reference</label>
            <div className="finput"><Icon name="hash" size={16} color="var(--fg-4)" /><input value={form.account} onChange={e => set('account', e.target.value)} /></div>

            <label className="fl">Attachments</label>
            <AttachmentList items={atts} onRemove={removeAtt} onAdd={() => fileRef.current && fileRef.current.click()} />
            <input ref={fileRef} type="file" multiple style={{ display:'none' }} onChange={addFiles} />

            <div className="drawer-foot">
              <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
              <Btn variant="primary" icon="check" style={{ flex:1, justifyContent:'center' }} onClick={saveForm}>{creating ? 'Add bill' : 'Save changes'}</Btn>
            </div>
          </div>
        )}
      </div>
    </React.Fragment>
  );
}

// ---------- Bills screen ----------
function Bills({ go }) {
  const D = window.ZD_DATA;
  const [bills, setBills] = useState(D.bills);
  const [tab, setTab] = useState('all');
  const [q, setQ] = useState('');
  const [catFilter, setCatFilter] = useState('all');
  const [sel, setSel] = useState(null);     // bill being viewed/edited
  const [editing, setEditing] = useState(false);
  const [creating, setCreating] = useState(false);
  const [dismissed, setDismissed] = useState(new Set());
  const [showDismissed, setShowDismissed] = useState(false);
  const toggleDismiss = id => setDismissed(prev => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
  const [page, setPage] = useState(1);
  const PAGE = 6;
  const sort = useSort('dueISO', 'asc');

  const newBill = () => {
    const c = D.billCategories[0];
    setSel({ id:'b' + Date.now(), merchant:'', cat:c.label, catId:c.id, catTint:c.tint, icon:c.icon,
      ccy:'USD', amountVal:0, due:'', dueISO:'', status:'pending', account:'', confidence:80, attachments:[], payLink:'', recurring:false, isNew:true });
    setEditing(true); setCreating(true);
  };
  useCreateShortcut(newBill);

  const counts = {
    all: bills.length,
    pending: bills.filter(b => b.status === 'pending').length,
    overdue: bills.filter(b => b.status === 'overdue').length,
    paid: bills.filter(b => b.status === 'paid').length,
  };

  const catOpts = [{ value:'all', label:'All categories' },
    ...D.billCategories.map(c => ({ value:c.id, label:c.label, tint:c.tint }))];

  let rows = bills.filter(b =>
    (tab === 'all' || b.status === tab) &&
    (catFilter === 'all' || b.catId === catFilter) &&
    (showDismissed || !dismissed.has(b.id)) &&
    (b.merchant.toLowerCase().includes(q.toLowerCase()) || b.cat.toLowerCase().includes(q.toLowerCase()))
  );
  rows = sort.apply(rows, {
    merchant: b => b.merchant.toLowerCase(),
    cat:      b => b.cat.toLowerCase(),
    amountVal:b => toHome(b.amountVal, b.ccy),
    dueISO:   b => b.dueISO,
    status:   b => statusRank[b.status],
  });

  // In the "All" view, keep paid bills at the very end so pending/overdue stay
  // front-and-centre — the active column sort still applies within each group.
  if (tab === 'all' && sort.sortKey !== 'status') {
    rows = [...rows].sort((a, b) => (a.status === 'paid' ? 1 : 0) - (b.status === 'paid' ? 1 : 0));
  }

  const filtered = q || catFilter !== 'all' || tab !== 'all';
  const total = rows.reduce((s, b) => s + toHome(b.amountVal, b.ccy), 0);
  const pageCount = Math.ceil(rows.length / PAGE) || 1;
  const pg = Math.min(page, pageCount);
  const paged = rows.slice((pg - 1) * PAGE, pg * PAGE);
  useEffect(() => { setPage(1); }, [q, catFilter, tab, sort.sortKey, sort.sortDir]);

  const saveBill = updated => {
    setBills(bs => bs.some(b => b.id === updated.id) ? bs.map(b => b.id === updated.id ? updated : b) : [{ ...updated, isNew:undefined }, ...bs]);
    setSel({ ...updated, isNew:undefined }); setEditing(false); setCreating(false);
  };
  const delBill  = id => { setBills(bs => bs.filter(b => b.id !== id)); setSel(null); setEditing(false); };

  return (
    <div className="screen-inner">
      <div className="statrow">
        <StatCard label="Total outstanding" value={fmtCcy(bills.filter(b=>b.status!=='paid').reduce((s,b)=>s+toHome(b.amountVal,b.ccy),0), D.fx.home)} sub={`${counts.pending+counts.overdue} active bills`} icon="dollar-sign" tint="gold" />
        <StatCard label="Overdue" value={counts.overdue} sub={counts.overdue ? 'Needs attention' : 'All current'} icon="alert-circle" tint={counts.overdue ? 'red' : 'green'} />
        <StatCard label="Next due" value="Jun 3" sub="Blue Cross — $210.00" icon="clock" tint="teal" />
      </div>

      <div className="card rise" style={{ marginBottom:18, overflow:'hidden' }}>
        <div className="card-pad" style={{ paddingBottom:0 }}>
          <SectionHeader title="All bills" sub="Financial obligations detected from your inbox"
            actionEl={<Btn variant="primary" icon="plus" kbd="C" title="New bill — press C" onClick={newBill}>New bill</Btn>} />

          {/* ---- Pro filter bar ---- */}
          <div className="filterbar">
            <div className="search" style={{ flex:'1 1 220px' }}><Icon name="search" size={17} /><input placeholder="Search recipient or category…" value={q} onChange={e => setQ(e.target.value)} />{q && <button className="x-clear" onClick={() => setQ('')}><Icon name="x" size={14} /></button>}</div>
            <Dropdown value={catFilter} options={catOpts} onChange={setCatFilter} icon="filter" minWidth={172} />
            <Dropdown value={tab} options={STATUS_OPTS} onChange={setTab} icon="circle-dot" minWidth={150} />
            <MobileSort sort={sort} options={[
              { value:'dueISO:asc',     label:'Due date (soonest)' },
              { value:'dueISO:desc',    label:'Due date (latest)' },
              { value:'amountVal:desc', label:'Amount (high → low)' },
              { value:'amountVal:asc',  label:'Amount (low → high)' },
              { value:'merchant:asc',   label:'Recipient (A → Z)' },
              { value:'status:asc',     label:'Status' },
            ]} />
          </div>

          {/* status quick-tabs + result count */}
          <div className="filtbar-2">
            <div className="tabs">
              {[['all','All'],['pending','Pending'],['overdue','Overdue'],['paid','Paid']].map(([id,lbl]) => (
                <button key={id} className={tab === id ? 'on' : ''} onClick={() => setTab(id)}>{lbl} <span className="tab-n">{counts[id]}</span></button>
              ))}
            </div>
            <div className="result-meta">
              <span>{rows.length} {rows.length === 1 ? 'bill' : 'bills'} · <b style={{color:'var(--fg-1)'}}>{fmtCcy(total, D.fx.home)}</b></span>
              {dismissed.size > 0 && <button className="viewall" onClick={() => setShowDismissed(s => !s)}>{showDismissed ? 'Hide' : 'Show'} {dismissed.size} ignored</button>}
              {filtered && <button className="viewall" onClick={() => { setQ(''); setCatFilter('all'); setTab('all'); }}>Clear filters</button>}
            </div>
          </div>
        </div>

        <table className="table sortable">
          <thead><tr>
            <SortTh label="Recipient" k="merchant" sort={sort} />
            <SortTh label="Category" k="cat" sort={sort} />
            <SortTh label="Amount" k="amountVal" sort={sort} align="right" />
            <SortTh label="Due date" k="dueISO" sort={sort} />
            <SortTh label="Status" k="status" sort={sort} />
            <th style={{ width:120, textAlign:'right' }}>Actions</th>
          </tr></thead>
          <tbody>
            {paged.map(b => (
              <tr key={b.id} onClick={() => { setSel(b); setEditing(false); }} style={{ cursor:'pointer' }}>
                <td className="cell-first"><div className="cellmain"><IconChip icon={b.icon} tint={b.catTint} /><div><div className="nm">{b.merchant}</div><div className="sub-acct">{b.account}<button className="src-pin" title="View source email" onClick={e => { e.stopPropagation(); openAttachment({ name:'Source email · ' + b.merchant }); }}><Icon name="mail" size={11} /></button>{b.attachments && b.attachments.length > 0 && <span className="att-pin" title={`${b.attachments.length} attachment${b.attachments.length===1?'':'s'}`} onClick={e => { e.stopPropagation(); openAttachment(b.attachments[0]); }} style={{ cursor:'pointer' }}><Icon name="paperclip" size={11} /> {b.attachments.length}</span>}{b.items && b.items.length > 0 && <span className="att-pin" title={`${b.items.length} line items — open to see the breakdown`}><Icon name="list" size={11} /> {b.items.length}</span>}<MailboxBadge addr={mailboxFor(b)} variant="mini" /></div></div></div></td>
                <td data-label="Category"><span className="cat-tag"><span className="dd-dot" style={{ background: tintFg(b.catTint) }} />{b.cat}</span></td>
                <td className="amt-cell" data-label="Amount" style={{ textAlign:'right' }}><Money amount={b.amountVal} ccy={b.ccy} /></td>
                <td className="muted" data-label="Due">{b.due}</td>
                <td data-label="Status"><span className={`badge ${stCls(b.status)}`}>{b.status}</span></td>
                <td data-label="Actions" style={{ textAlign:'right' }}>
                  <div className="row-acts" onClick={e => e.stopPropagation()}>
                    <button className="iconbtn" onClick={() => { setSel(b); setEditing(true); }} title="Edit"><Icon name="pencil" size={16} /></button>
                    <button className="iconbtn danger" onClick={() => delBill(b.id)} title="Delete"><Icon name="trash-2" size={16} /></button>
                  </div>
                </td>
              </tr>
            ))}
            {rows.length === 0 && <tr><td colSpan="6"><div className="table-empty"><Icon name="search-x" size={26} color="var(--fg-4)" /><span>No bills match your filters.</span><button className="viewall" onClick={() => { setQ(''); setCatFilter('all'); setTab('all'); }}>Clear filters</button></div></td></tr>}
          </tbody>
        </table>
        <Pager page={pg} pageCount={pageCount} total={rows.length} pageSize={PAGE} onPage={setPage} noun="bills" />
      </div>

      <Receipts />

      {sel && <BillDrawer bill={sel} editing={editing} onClose={() => { setSel(null); setEditing(false); setCreating(false); }}
        onEdit={() => setEditing(true)} onSave={saveBill} onDelete={delBill} creating={creating}
        dismissed={dismissed.has(sel.id)} onIgnore={() => { toggleDismiss(sel.id); setSel(null); setEditing(false); }} />}
    </div>
  );
}
Object.assign(window, { Bills, StatCard });
