// vendors.jsx — VENDORS (Nhà cung cấp) module + widget. Master riêng, mock-only.
const VEN_APP = APPS.find(a => a.id === 'vendors');

function VendorModule(){
  const p = usePortal();
  const { t } = useLang();
  const sub = p.route.sub || 'overview';
  const items = [
    { id:'overview', icon:'bi-pie-chart', label:t('c.overview') },
    { id:'list', icon:'bi-list-ul', label:t('c.list'), count:p.vendors.length },
    { id:'report', icon:'bi-bar-chart', label:t('c.report') },
    { id:'settings', icon:'bi-gear', label:t('c.settings') },
  ];
  const go = (id, extra) => p.navigate({ name:'module', module:'vendors', sub:id, ...extra });
  return (<>
    <ModuleSidebar app={VEN_APP} items={items} active={sub === 'detail' ? 'list' : sub} onNavigate={go} />
    <main className="main">
      {sub === 'overview' && <VenOverview go={go} />}
      {sub === 'list' && <VenList go={go} />}
      {sub === 'detail' && <VenDetail code={p.route.id} go={go} />}
      {sub === 'report' && <VenReport />}
      {sub === 'help' && <ModuleHelp moduleId="vendors" app={VEN_APP} />}
      {sub === 'settings' && <VenSettings />}
    </main>
  </>);
}

function venCountBy(arr, key){ const m = {}; arr.forEach(x => { const k = x[key]; m[k] = (m[k] || 0) + 1; }); return m; }
// Số HĐ mua + tổng giá trị đã mua từ 1 NCC (qua ContractStore).
function venPurchases(code){
  const all = (window.ContractStore ? ContractStore.all() : []).filter(c => contractDir(c) === 'buy' && c.customer === code);
  return { count:all.length, total:all.reduce((s, c) => s + contractTotals(c).total, 0) };
}

function VenOverview({ go }){
  const p = usePortal();
  const { t, lang } = useLang();
  const vs = p.vendors;
  const byField = venCountBy(vs, 'field');
  const colors = ['var(--primary)','var(--accent)','#7A5AF8','var(--warning)','var(--success)','var(--gray-400)'];
  const buys = (window.ContractStore ? ContractStore.all() : []).filter(c => contractDir(c) === 'buy');
  const totalBuy = buys.reduce((s, c) => s + contractTotals(c).total, 0);
  // Tương tác mới nhất: HĐ mua + timeline của liên hệ thuộc NCC (mới → cũ).
  const venByCode = {}; vs.forEach(v => { venByCode[v.code] = v; });
  const recent = [];
  buys.forEach(c => { const ven = venByCode[c.customer]; recent.push({ date:c.signDate, icon:'bi-file-earmark-text', color:'var(--accent)', title:(lang === 'vi' ? 'HĐ mua ' : 'Purchase ') + c.code, sub:(ven ? (ven.shortName || ven.name) : c.customer) + ' · ' + vndShort(contractTotals(c).total), onClick:() => p.navigate({ name:'module', module:'contracts', sub:'detail', id:c.code }) }); });
  (p.contacts || []).filter(ct => venByCode[ct.customer]).forEach(ct => (ct.tx || []).forEach(x => { const ty = TX_TYPES[x.type] || {}; const ven = venByCode[ct.customer]; recent.push({ date:x.date, icon:ty.icon, color:ty.color, title:x.title, sub:(ven.shortName || ven.name) + ' · ' + ct.name, onClick:() => go('detail', { id:ven.code }) }); }));
  recent.sort((a, b) => (a.date < b.date ? 1 : -1));
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{lang === 'vi' ? 'Nhà cung cấp' : 'Vendors'}</h1><div className="sub">{lang === 'vi' ? 'Tổng quan nhà cung cấp đầu vào.' : 'Vendor master-data overview.'}</div></div>
        <button className="btn btn-primary" onClick={() => p.quick('vendors')}><i className="bi bi-plus-lg"></i>{lang === 'vi' ? 'Thêm NCC' : 'New vendor'}</button></div>
      <div className="kpi-strip">
        <Kpi label={lang === 'vi' ? 'Nhà cung cấp' : 'Vendors'} value={vs.length} icon="bi-truck" />
        <Kpi label={t('st.active')} value={vs.filter(v => v.status === 'active').length} icon="bi-check-circle" />
        <Kpi label={lang === 'vi' ? 'Lĩnh vực' : 'Fields'} value={Object.keys(byField).length} icon="bi-tags" />
        <Kpi label={lang === 'vi' ? 'Tổng mua vào' : 'Total purchased'} value={vndShort(totalBuy)} icon="bi-cash-stack" />
      </div>
      <div className="dash-grid">
        <div className="card span2"><div className="card-head"><h3>{lang === 'vi' ? 'Phân bố theo lĩnh vực' : 'By field'}</h3></div><div className="card-body">
          <DistribBars rows={Object.entries(byField).sort((a, b) => b[1] - a[1]).map(([label, value], i) => ({ label, value, color:colors[i % colors.length] }))} />
        </div></div>
        <div className="card"><div className="card-head"><h3>{t('c.status')}</h3></div><div className="card-body">
          <DistribBars rows={['active','inactive'].map((s, i) => ({ label:t('st.' + s), value:vs.filter(v => v.status === s).length, color:s === 'active' ? 'var(--success)' : 'var(--gray-400)' }))} />
        </div></div>
      </div>
      <RecentInteractions items={recent} onViewAll={() => go('list')} />
    </div>
  );
}

function VenList({ go }){
  const p = usePortal();
  const { t, lang } = useLang();
  const [q, setQ] = React.useState('');
  const [status, setStatus] = React.useState('all');
  const srt = useTableSort();
  const list = srt.sortRows(p.vendors.filter(v =>
    (status === 'all' || v.status === status) &&
    (!q || (v.name + v.code + v.shortName + (v.field || '')).toLowerCase().includes(q.toLowerCase()))),
    { code:v => v.code, name:v => v.name, field:v => v.field, mst:v => v.mst, buy:v => venPurchases(v.code).total, owner:v => v.owner, status:v => v.status });
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('c.list')}</h1><div className="sub">{list.length} {lang === 'vi' ? 'nhà cung cấp' : 'vendors'}</div></div>
        <button className="btn btn-primary" onClick={() => p.quick('vendors')}><i className="bi bi-plus-lg"></i>{lang === 'vi' ? 'Thêm NCC' : 'New vendor'}</button></div>
      <div className="toolbar">
        <div className="topsearch" style={{ width:240, background:'var(--bg)', border:'1px solid var(--border-strong)' }}><i className="bi bi-search"></i>
          <input value={q} onChange={e => setQ(e.target.value)} placeholder={t('c.search')} style={{ border:'none', outline:'none', background:'transparent', flex:1 }} /></div>
        <div className="seg">
          {['all','active','inactive'].map(s => <button key={s} className={status === s ? 'is-active' : ''} onClick={() => setStatus(s)}><i className={'bi ' + ({ all:'bi-grid-1x2', active:'bi-check-circle', inactive:'bi-slash-circle' }[s])}></i>{s === 'all' ? t('c.all') : t('st.' + s)}</button>)}
        </div>
      </div>
      <div className="card"><div style={{ overflow:'auto' }}>
        <table className="tbl">
          <thead><tr><ThSort k="code" sort={srt}>{t('cust.code')}</ThSort><ThSort k="name" sort={srt}>{t('cust.name')}</ThSort><ThSort k="field" sort={srt}>{lang === 'vi' ? 'Lĩnh vực' : 'Field'}</ThSort><ThSort k="mst" sort={srt}>{t('cust.mst')}</ThSort><ThSort k="buy" sort={srt} className="num">{lang === 'vi' ? 'HĐ mua' : 'Purchases'}</ThSort><ThSort k="owner" sort={srt}>{t('c.owner')}</ThSort><ThSort k="status" sort={srt}>{t('c.status')}</ThSort></tr></thead>
          <tbody>
            {list.map(v => { const pu = venPurchases(v.code); return (
              <tr key={v.code} onClick={() => go('detail', { id:v.code })}>
                <td><span className="mono" style={{ fontWeight:600, color:'var(--primary)' }}>{v.code}</span></td>
                <td><span style={{ fontWeight:500 }}>{v.name}</span> <span className="subtle">· {v.shortName}</span></td>
                <td className="muted">{v.field}</td>
                <td className="mono" style={{ fontSize:'var(--fs-base)' }}>{v.mst}</td>
                <td className="num">{pu.count ? pu.count + ' · ' + vndShort(pu.total) : '—'}</td>
                <td>{v.owner}</td>
                <td><StatusBadge status={v.status} /></td>
              </tr>
            ); })}
          </tbody>
        </table>
        {list.length === 0 && <EmptyState text={t('c.empty')} />}
      </div></div>
    </div>
  );
}

function VenDetail({ code, go }){
  const p = usePortal();
  const { t, lang } = useLang();
  const toast = useToast();
  const confirm = useConfirm();
  const [editing, setEditing] = React.useState(false);
  const v = p.vendors.find(x => x.code === code);
  if (!v) return <div className="page"><EmptyState text={t('c.empty')} /></div>;
  const buys = (window.ContractStore ? ContractStore.all() : []).filter(c => contractDir(c) === 'buy' && c.customer === v.code);
  const totalBuy = buys.reduce((s, c) => s + contractTotals(c).total, 0);
  // Thanh toán mua vào: cộng các đợt đã trả trên lịch thanh toán của mọi HĐ mua.
  const paidBuy = buys.reduce((s, c) => s + (c.schedule || []).filter(x => x.paid).reduce((a, x) => a + x.amount, 0), 0);
  const schAll = buys.flatMap(c => c.schedule || []);
  const paidN = schAll.filter(x => x.paid).length;
  const vContacts = (p.contacts || []).filter(c => c.customer === v.code);
  // Phiếu nhập kho từ NCC này (gắn trực tiếp vendor hoặc qua HĐ mua).
  const buyCodes = new Set(buys.map(c => c.code));
  const vReceipts = (p.receipts || []).filter(r => r.vendor === v.code || (r.buyContract && buyCodes.has(r.buyContract)));
  // Email đã gửi tới NCC (email công ty + email các liên hệ thuộc NCC).
  const vMails = new Set([v.email, ...vContacts.map(c => c.email)].filter(Boolean));
  const emailCount = (p.sentEmails || []).filter(e => [...vMails].some(m => (e.to || []).includes(m))).length;
  const remove = async () => {
    if (!(await confirm({ message:(lang === 'vi' ? 'Xóa nhà cung cấp ' : 'Delete vendor ') + v.name + '?', confirmLabel:lang === 'vi' ? 'Xóa' : 'Delete' }))) return;
    p.deleteVendor(v.code); toast((lang === 'vi' ? 'Đã xóa ' : 'Deleted ') + v.code, 'success'); go('list');
  };
  return (
    <div className="page pagefade">
      <div className="page-head">
        <div className="flex g12 items-center">
          <button className="btn btn-ghost btn-icon" onClick={() => go('list')}><i className="bi bi-arrow-left"></i></button>
          <Avatar name={v.shortName} size={40} square color="var(--accent)" />
          <div><h1 style={{ fontSize:'var(--fs-2xl)' }}>{v.name}</h1><div className="sub flex g8 items-center"><span className="mono" style={{ color:'var(--primary)', fontWeight:600 }}>{v.code}</span> · {v.shortName} · <StatusBadge status={v.status} /></div></div>
        </div>
        <div className="flex g8 wrap">
          <button className="btn" onClick={() => p.quick('contacts', { customer:v.code, type:'vendor' })}><i className="bi bi-person-plus"></i>{lang === 'vi' ? 'Thêm liên hệ' : 'Add contact'}</button>
          <button className="btn" onClick={() => p.quick('contracts', { customer:v.code, direction:'buy' })}><i className="bi bi-file-earmark-text"></i>{lang === 'vi' ? 'Tạo HĐ mua' : 'New purchase'}</button>
          <button className="btn" onClick={() => setEditing(true)}><i className="bi bi-pencil"></i>{t('c.edit')}</button>
          <button className="btn btn-icon" title={t('c.delete')} onClick={remove}><i className="bi bi-trash"></i></button>
        </div>
      </div>
      {editing && <NewVendorModal editing={v} onClose={() => setEditing(false)} />}
      <div className="split">
        <div className="col g12">
          <div className="card"><div className="card-head"><h3>{lang === 'vi' ? 'Thông tin chi tiết' : 'Details'}</h3></div><div className="card-body">
            <div className="det-row"><span className="dk">{t('cust.name')}</span><span className="dv">{v.name}</span></div>
            <div className="det-row"><span className="dk">{t('cust.short')}</span><span className="dv">{v.shortName}</span></div>
            <div className="det-row"><span className="dk">{t('cust.mst')}</span><span className="dv mono">{v.mst}</span></div>
            <div className="det-row"><span className="dk">{lang === 'vi' ? 'Lĩnh vực' : 'Field'}</span><span className="dv">{v.field}</span></div>
            {v.address && <div className="det-row"><span className="dk">{t('hd.address')}</span><span className="dv">{v.address}</span></div>}
            <div className="det-row"><span className="dk">{lang === 'vi' ? 'Điện thoại' : 'Phone'}</span><span className="dv mono">{v.phone || '—'}</span></div>
            <div className="det-row"><span className="dk">Email</span><span className="dv mono">{v.email || '—'}</span></div>
            <div className="det-row"><span className="dk">{t('c.owner')}</span><span className="dv">{v.owner}</span></div>
          </div></div>
          <div className="card"><div className="card-head"><h3 style={{ fontSize:'var(--fs-md)' }}>{lang === 'vi' ? 'Mua hàng & thanh toán' : 'Purchases & payments'}</h3></div><div className="card-body">
            <div className="det-row"><span className="dk">{lang === 'vi' ? 'Tổng HĐ mua' : 'Purchase contracts'}</span><span className="dv">{buys.length}</span></div>
            <div className="det-row"><span className="dk">{lang === 'vi' ? 'Tổng giá trị' : 'Total value'}</span><span className="dv mono" style={{ fontWeight:600 }}>{vnd(totalBuy)}</span></div>
            <div className="det-row"><span className="dk">{lang === 'vi' ? 'Đã thanh toán' : 'Paid'}</span><span className="dv mono" style={{ fontWeight:600, color:'var(--success)' }}>{vnd(paidBuy)}{schAll.length > 0 && <span className="subtle" style={{ fontWeight:400, marginLeft:6 }}>({paidN}/{schAll.length} {lang === 'vi' ? 'đợt' : 'paid'})</span>}</span></div>
            <div className="det-row"><span className="dk">{lang === 'vi' ? 'Còn phải trả' : 'Outstanding'}</span><span className="dv mono" style={{ fontWeight:600, color:totalBuy - paidBuy > 0 ? 'var(--warning)' : 'var(--text-muted)' }}>{vnd(Math.max(0, totalBuy - paidBuy))}</span></div>
          </div></div>
          {buys.length > 0 && (
            <div className="card"><div className="card-head"><h3 style={{ fontSize:'var(--fs-md)' }}>{lang === 'vi' ? 'Hợp đồng mua liên quan' : 'Linked purchases'}</h3><span className="subtle" style={{ fontSize:'var(--fs-sm)' }}>{vndShort(totalBuy)}</span></div><div className="card-body col g4">
              {buys.map(lc => {
                const sch = lc.schedule || []; const pn = sch.filter(s => s.paid).length;
                const term = lc.termType === 'term' && lc.endDate ? (fmtDate(lc.startDate) + ' → ' + fmtDate(lc.endDate)) : (lang === 'vi' ? 'Một lần' : 'One-time');
                return (
                <div key={lc.code} className="col g4" style={{ cursor:'pointer', padding:'8px 6px', borderRadius:'var(--r-sm)' }} onClick={() => p.navigate({ name:'module', module:'contracts', sub:'detail', id:lc.code })}>
                  <div className="flex g8 items-center">
                    <span className="mono" style={{ fontWeight:600, color:'var(--primary)', fontSize:'var(--fs-base)' }}>{lc.code}</span>
                    <span className="grow"></span>
                    <span className="mono" style={{ fontWeight:600 }}>{vndShort(contractTotals(lc).total)}</span>
                    <HdStatusBadge c={lc} />
                  </div>
                  <div className="flex g10 items-center subtle wrap" style={{ fontSize:'var(--fs-sm)' }}>
                    <span><i className="bi bi-folder2" style={{ marginRight:4 }}></i>{catLabel(lc.category, lang)}</span>
                    <span><i className="bi bi-pen" style={{ marginRight:4 }}></i>{lang === 'vi' ? 'Ký ' : 'Signed '}{fmtDate(lc.signDate)}</span>
                    {sch.length > 0 && <span style={{ color:pn === sch.length ? 'var(--success)' : 'inherit' }}><i className="bi bi-cash-coin" style={{ marginRight:4 }}></i>{pn}/{sch.length} {lang === 'vi' ? 'đợt' : 'paid'}</span>}
                  </div>
                  <div className="truncate" style={{ fontSize:'var(--fs-sm)', color:'var(--text-muted)' }}><i className="bi bi-calendar-range" style={{ marginRight:4 }}></i>{term}</div>
                </div>
              ); })}
            </div></div>
          )}
        </div>
        <div className="col g12">
          <div className="card"><div className="card-head"><h3 style={{ fontSize:'var(--fs-md)' }}>{t('cust.links')}</h3></div><div className="card-body col g8">
            <div className="flex g8 wrap">
              <span className="linkcount"><i className="bi bi-person-vcard"></i><b>{vContacts.length}</b> {lang === 'vi' ? 'liên hệ' : 'contacts'}</span>
              <span className="linkcount"><i className="bi bi-file-earmark-text"></i><b>{buys.length}</b> {lang === 'vi' ? 'HĐ mua' : 'purchases'}</span>
              <span className="linkcount"><i className="bi bi-box-arrow-in-down"></i><b>{vReceipts.length}</b> {lang === 'vi' ? 'phiếu nhập' : 'receipts'}</span>
              <span className="linkcount"><i className="bi bi-envelope"></i><b>{emailCount}</b> email</span>
            </div>
          </div></div>
          <div className="card"><div className="card-head"><h3 style={{ fontSize:'var(--fs-md)' }}>{lang === 'vi' ? 'Liên hệ liên quan' : 'Linked contacts'}</h3>
            <button className="btn btn-ghost btn-sm" onClick={() => p.quick('contacts', { customer:v.code, type:'vendor' })}><i className="bi bi-person-plus"></i>{lang === 'vi' ? 'Thêm' : 'Add'}</button></div>
            <div className="card-body">
              {vContacts.length ? vContacts.map(c => (
                <div key={c.code} className="list-row" style={{ cursor:'pointer' }} onClick={() => p.navigate({ name:'module', module:'contacts', sub:'detail', id:c.code })}>
                  <Avatar name={c.name} size={24} color="var(--gray-400)" /><span className="grow" style={{ fontWeight:500 }}>{c.name}</span><span className="subtle">{c.title}</span>
                </div>
              )) : <div className="subtle" style={{ fontSize:'var(--fs-base)' }}>{lang === 'vi' ? 'Chưa có liên hệ' : 'No contacts'}</div>}
            </div>
          </div>
          {vReceipts.length > 0 && (
            <div className="card"><div className="card-head"><h3 style={{ fontSize:'var(--fs-md)' }}><i className="bi bi-box-arrow-in-down" style={{ marginRight:6, color:'var(--success)' }}></i>{lang === 'vi' ? 'Phiếu nhập kho' : 'Stock receipts'}</h3></div><div className="card-body">
              {vReceipts.map(r => (
                <div key={r.code} className="list-row" style={{ cursor:'pointer' }} onClick={() => p.navigate({ name:'module', module:'inventory', sub:'stock' })}>
                  <span className="mono" style={{ fontWeight:600, color:'var(--success)', fontSize:'var(--fs-base)', width:104 }}>{r.code}</span>
                  <span className="grow truncate subtle" style={{ fontSize:'var(--fs-sm)' }}>{(r.lines || []).length} {lang === 'vi' ? 'dòng hàng' : 'lines'}{r.note ? ' · ' + r.note : ''}</span>
                  <span className="mono subtle" style={{ fontSize:'var(--fs-sm)' }}>{fmtDate(r.date)}</span>
                </div>
              ))}
            </div></div>
          )}
        </div>
      </div>
    </div>
  );
}

function VenReport(){
  const p = usePortal();
  const { t, lang } = useLang();
  const vs = p.vendors;
  const byOwner = venCountBy(vs, 'owner');
  // tổng mua vào theo NCC
  const spend = vs.map(v => ({ v, ...venPurchases(v.code) })).filter(x => x.total > 0).sort((a, b) => b.total - a.total);
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('c.report')}</h1><div className="sub">{lang === 'vi' ? 'Thống kê nhà cung cấp & chi mua vào.' : 'Vendor & purchase statistics.'}</div></div></div>
      <div className="dash-grid">
        <div className="card span2"><div className="card-head"><h3>{lang === 'vi' ? 'Mua vào theo NCC' : 'Spend by vendor'}</h3></div><div style={{ overflow:'auto' }}>
          <table className="tbl"><thead><tr><th>{t('cust.name')}</th><th className="num">{lang === 'vi' ? 'Số HĐ' : 'Contracts'}</th><th className="num">{lang === 'vi' ? 'Giá trị' : 'Value'}</th></tr></thead>
            <tbody>{spend.length ? spend.map(x => (
              <tr key={x.v.code} style={{ cursor:'default' }}><td><span className="flex g8 items-center"><Avatar name={x.v.shortName} size={22} square color="var(--accent)" />{x.v.shortName}</span></td><td className="num">{x.count}</td><td className="num mono" style={{ fontWeight:600 }}>{vnd(x.total)}</td></tr>
            )) : <tr style={{ cursor:'default' }}><td colSpan="3" className="muted">{t('c.empty')}</td></tr>}</tbody></table>
        </div></div>
        <div className="card"><div className="card-head"><h3>{lang === 'vi' ? 'Theo người phụ trách' : 'By owner'}</h3></div><div className="card-body">
          <DistribBars rows={Object.entries(byOwner).sort((a, b) => b[1] - a[1]).map(([o, n], i) => ({ label:o, value:n, color:'var(--primary)' }))} />
        </div></div>
      </div>
    </div>
  );
}

function VenSettings(){
  const { t, lang } = useLang();
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('c.settings')}</h1><div className="sub">{lang === 'vi' ? 'Danh mục lĩnh vực cung cấp.' : 'Vendor field categories.'}</div></div></div>
      <CatalogEditor catalogKey="vendorFields" title={lang === 'vi' ? 'Lĩnh vực cung cấp' : 'Supply fields'} stringMode={true} />
    </div>
  );
}

/* New/Edit vendor modal (quick-action target) */
function NewVendorModal({ onClose, editing }){
  const p = usePortal();
  const { t, lang } = useLang();
  const toast = useToast();
  const [f, setF] = React.useState(editing
    ? { name:editing.name, shortName:editing.shortName, mst:editing.mst, field:editing.field, phone:editing.phone || '', email:editing.email || '', address:editing.address || '', owner:editing.owner, status:editing.status }
    : { name:'', shortName:'', mst:'', field:VENDOR_FIELDS[0], phone:'', email:'', address:'', owner:p.me.name, status:'active' });
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const [looking, setLooking] = React.useState(false);
  const lookupMst = async () => {
    const mst = (f.mst || '').trim();
    if (!mst) { toast(lang === 'vi' ? 'Nhập mã số thuế trước' : 'Enter tax ID first', 'error'); return; }
    setLooking(true);
    try {
      const r = await fetch('https://api.vietqr.io/v2/business/' + encodeURIComponent(mst));
      const j = await r.json().catch(() => null);
      if (j && j.code === '00' && j.data && j.data.name) { setF(s => ({ ...s, name:j.data.name, address:j.data.address || s.address })); toast(lang === 'vi' ? 'Đã lấy thông tin doanh nghiệp' : 'Company info fetched', 'success'); }
      else toast(lang === 'vi' ? 'Không tìm thấy doanh nghiệp với MST này' : 'No business found', 'error');
    } catch (e){ toast((lang === 'vi' ? 'Tra cứu thất bại: ' : 'Lookup failed: ') + (e.message || e), 'error'); }
    finally { setLooking(false); }
  };
  const create = () => {
    if (!f.name.trim()) { toast(lang === 'vi' ? 'Nhập tên nhà cung cấp' : 'Enter a vendor name', 'error'); return; }
    if (editing) { p.updateVendor(editing.code, { ...editing, ...f, shortName:f.shortName || f.name.split(' ')[0] }); toast(lang === 'vi' ? 'Đã lưu' : 'Saved', 'success'); onClose(); return; }
    const code = genVendorCode(p.vendors);
    p.addVendor({ code, ...f, shortName:f.shortName || f.name.split(' ')[0] });
    toast((lang === 'vi' ? 'Đã thêm NCC ' : 'Added ') + code, 'success'); onClose();
    p.navigate({ name:'module', module:'vendors', sub:'detail', id:code });
  };
  return (
    <Modal title={editing ? (lang === 'vi' ? 'Sửa nhà cung cấp' : 'Edit vendor') : (lang === 'vi' ? 'Thêm nhà cung cấp' : 'New vendor')} width={600} onClose={onClose}
      footer={<><button className="btn" onClick={onClose}>{t('c.cancel')}</button><button className="btn btn-primary" onClick={create}>{editing ? t('c.save') : t('c.create')}</button></>}>
      <div className="col g16">
        <Field label={t('cust.name')}><input className="input" autoFocus value={f.name} onChange={e => set('name', e.target.value)} placeholder={lang === 'vi' ? 'VD: Công ty TNHH ABC' : 'e.g. ABC Company Ltd'} /></Field>
        <div className="flex g12">
          <div style={{ flex:1 }}><Field label={t('cust.short')}><input className="input" value={f.shortName} onChange={e => set('shortName', e.target.value)} placeholder={f.name.split(' ')[0]} /></Field></div>
          <div style={{ flex:1 }}><Field label={lang === 'vi' ? 'Lĩnh vực' : 'Field'}><select className="select" value={f.field} onChange={e => set('field', e.target.value)}>{(p.catalogs.vendorFields || []).map(x => <option key={x}>{x}</option>)}</select></Field></div>
        </div>
        <div className="flex g12">
          <div style={{ flex:1 }}><Field label={t('cust.mst')} hint={lang === 'vi' ? 'Nhập MST rồi tra cứu để tự điền' : 'Look up to autofill'}>
            <div className="flex g8 items-center">
              <input className="input mono" value={f.mst} onChange={e => set('mst', e.target.value)} placeholder="0300000000" />
              <button className="btn btn-sm" onClick={lookupMst} disabled={looking} title={t('cust.lookup')}>{looking ? <i className="bi bi-arrow-repeat spin"></i> : <i className="bi bi-search"></i>}</button>
            </div>
          </Field></div>
          <div style={{ flex:1 }}><Field label={t('c.status')}><select className="select" value={f.status} onChange={e => set('status', e.target.value)}>{['active','inactive'].map(s => <option key={s} value={s}>{t('st.' + s)}</option>)}</select></Field></div>
        </div>
        <Field label={t('hd.address')}><input className="input" value={f.address} onChange={e => set('address', e.target.value)} placeholder={lang === 'vi' ? 'Địa chỉ trụ sở' : 'Head office address'} /></Field>
        <div className="flex g12">
          <div style={{ flex:1 }}><Field label={lang === 'vi' ? 'Điện thoại' : 'Phone'}><input className="input mono" value={f.phone} onChange={e => set('phone', e.target.value)} placeholder="028 …" /></Field></div>
          <div style={{ flex:1 }}><Field label="Email"><input className="input mono" value={f.email} onChange={e => set('email', e.target.value)} placeholder="sales@vendor.vn" /></Field></div>
        </div>
        <Field label={t('c.owner')}><select className="select" value={f.owner} onChange={e => set('owner', e.target.value)}>{p.users.map(u => <option key={u.id}>{u.name}</option>)}</select></Field>
      </div>
    </Modal>
  );
}

/* Dashboard widget */
function VendorWidget(){
  const p = usePortal();
  const { lang } = useLang();
  const { t } = useLang();
  const top = p.vendors.slice(0, 4);
  return (
    <WidgetShell wid="vendors" icon="bi-truck" iconColor="var(--accent)" title={lang === 'vi' ? 'Nhà cung cấp' : 'Vendors'}
      onViewAll={() => p.openApp(VEN_APP)} onNew={() => p.quick('vendors')} newLabel={lang === 'vi' ? 'Thêm NCC' : 'New vendor'}>
        <div className="flex g16" style={{ marginBottom:8 }}>
          <div><div className="k-val" style={{ fontSize:'var(--fs-2xl)', fontWeight:700 }}>{p.vendors.length}</div><div className="subtle" style={{ fontSize:'var(--fs-sm)' }}>{lang === 'vi' ? 'nhà cung cấp' : 'vendors'}</div></div>
          <div><div className="k-val" style={{ fontSize:'var(--fs-2xl)', fontWeight:700, color:'var(--success)' }}>{p.vendors.filter(v => v.status === 'active').length}</div><div className="subtle" style={{ fontSize:'var(--fs-sm)' }}>{t('st.active')}</div></div>
        </div>
        {top.map(v => (
          <div key={v.code} className="list-row" style={{ cursor:'pointer' }} onClick={() => p.navigate({ name:'module', module:'vendors', sub:'detail', id:v.code })}>
            <span className="mono" style={{ fontWeight:600, color:'var(--primary)', fontSize:'var(--fs-base)', width:72 }}>{v.code}</span><span className="grow truncate">{v.shortName}</span><StatusBadge status={v.status} />
          </div>
        ))}
    </WidgetShell>
  );
}

Object.assign(window, { VendorModule, NewVendorModal, VendorWidget });
