// quote-new.jsx — interactive "create quote" modal (quick-action target for Quotes).
function NewQuoteModal({ onClose, prefill, editing }){
  const p = usePortal();
  const { t, lang } = useLang();
  const showCost = canViewCost(p);
  const stockMap = React.useMemo(() => (window.stockQtyMap ? stockQtyMap(p.moves) : {}), [p.moves]);
  const toast = useToast();
  // Chiều báo giá: 'sell' (gửi KH) | 'buy' (nhận từ NCC) — chốt lúc mở form, không đổi giữa chừng.
  const dir = editing ? quoteDir(editing) : ((prefill && prefill.direction) === 'buy' ? 'buy' : 'sell');
  const [f, setF] = React.useState(editing
    ? { customer:editing.customer, rep:editing.rep || '', issueDate:editing.issueDate, validDays:+editing.validDays || 30, discountPct:+editing.discountPct || 0, notes:editing.notes || '' }
    : { customer:(prefill && prefill.customer) || (dir === 'buy' ? '' : (p.customers[0] ? p.customers[0].code : '')), rep:'', issueDate:TODAY, validDays:+(p.appSettings.quoteValidDays) || 30, discountPct:+(p.appSettings.quoteDiscount) || 0, notes:'' });
  const [items, setItems] = React.useState(editing && editing.items && editing.items.length
    ? editing.items.map(it => ({ name:it.name, unit:it.unit, qty:it.qty, price:it.price, vat:it.vat, detail:it.detail || '', showDetail:!!it.showDetail }))
    : (prefill && prefill.items && prefill.items.length ? prefill.items : [{ name:'', unit:'gói', qty:1, price:0, vat:8, detail:'', showDetail:false }]));
  const set = (k, v) => setF(s => ({ ...s, [k]:v }));
  const products = p.products || [];
  const [addProdOpen, setAddProdOpen] = React.useState(false);   // mở form Sản phẩm đầy đủ ngay trong form báo giá

  const cust = (dir === 'buy' ? (p.vendors || []) : p.customers).find(c => c.code === f.customer) || {};
  // Mã báo giá: khi sửa giữ nguyên mã cũ; khi tạo mới sinh theo định dạng + đối tác + ngày.
  // Chiều MUA đổi tiền tố BG- → BGM- để phân biệt hai luồng (format tùy chỉnh không bắt đầu BG- thì giữ nguyên).
  const rawCode = editing ? editing.code : genQuoteCode(p.quotes, cust.shortName || cust.name || '', f.issueDate);
  const code = (!editing && dir === 'buy') ? rawCode.replace(/^BG-/, 'BGM-') : rawCode;
  const reps = p.contacts.filter(c => c.customer === f.customer);
  const validUntil = addDays(f.issueDate, +f.validDays || 0);

  const discPct = +f.discountPct || 0;
  const tot = items.reduce((acc, it) => { const line = (+it.qty || 0) * (+it.price || 0); acc.sub += line; acc.vat += line * (1 - discPct / 100) * (+it.vat || 0) / 100; return acc; }, { sub:0, vat:0 });
  const discount = tot.sub * discPct / 100;
  const total = tot.sub - discount + tot.vat;
  // Lãi gộp NỘI BỘ — chỉ tính item khớp sản phẩm có giá vốn; KHÔNG bao giờ in ra báo giá gửi khách.
  const costInfo = items.reduce((a, it) => {
    const prod = products.find(pr => pr.name === it.name);
    const cost = prod ? productCost(prod) : 0;
    if (cost > 0) { const qty = +it.qty || 0; a.cost += cost * qty; a.rev += (+it.price || 0) * qty; a.known = true; }
    return a;
  }, { cost:0, rev:0, known:false });
  const gross = costInfo.rev - costInfo.cost;
  const grossPct = costInfo.rev ? Math.round(gross / costInfo.rev * 100) : 0;

  const upItem = (i, k, v) => setItems(s => s.map((it, j) => j === i ? { ...it, [k]:v } : it));
  // Giá tự điền theo chiều: bán → giá bán mới nhất; mua → giá vốn (nếu có) làm mốc, user sửa theo giá NCC chào.
  const priceOf = (prod) => dir === 'buy' ? (productCost(prod) || 0) : productPrice(prod);
  const onName = (i, v) => {
    const prod = products.find(pr => pr.name === v);
    // chọn từ danh mục → tự điền ĐVT, giá, VAT; nạp sẵn "chi tiết" (mô tả SP) để khi tích ô là hiện.
    if (prod) setItems(s => s.map((it, j) => j === i ? { ...it, name:v, unit:prod.unit, price:priceOf(prod), vat:prod.vat, detail:prod.desc || it.detail || '' } : it));
    else upItem(i, 'name', v);
  };
  // Tích "Hiển thị chi tiết" → bật hiện; nếu chưa có nội dung thì tự nạp từ mô tả sản phẩm (sửa được sau).
  const toggleDetail = (i) => setItems(s => s.map((it, j) => {
    if (j !== i) return it;
    const show = !it.showDetail; let detail = it.detail || '';
    if (show && !detail) { const prod = products.find(pr => pr.name === it.name); detail = (prod && prod.desc) || ''; }
    return { ...it, showDetail:show, detail };
  }));
  const addItem = () => setItems(s => [...s, { name:'', unit:'gói', qty:1, price:0, vat:8, detail:'', showDetail:false }]);
  const rmItem = (i) => setItems(s => s.length > 1 ? s.filter((_, j) => j !== i) : s);
  // Tạo SP mới ngay trong form báo giá (nút "Tạo SP mới") → điền vào dòng trống cuối, hoặc thêm dòng mới.
  const addItemFromProduct = (prod) => {
    const line = { name:prod.name, unit:prod.unit || 'gói', qty:1, price:priceOf(prod), vat:(prod.vat != null ? prod.vat : 8), detail:prod.desc || '', showDetail:false };
    setItems(s => {
      const last = s[s.length - 1];
      if (last && !(last.name || '').trim()) return s.map((it, j) => j === s.length - 1 ? line : it);
      return [...s, line];
    });
  };

  const build = () => {
    if (!f.customer) { toast(dir === 'buy' ? (lang === 'vi' ? 'Chọn nhà cung cấp' : 'Select a vendor') : (lang === 'vi' ? 'Chọn khách hàng' : 'Select a customer'), 'error'); return null; }
    if (!items.some(it => it.name.trim())) { toast(lang === 'vi' ? 'Thêm ít nhất 1 hạng mục' : 'Add at least one item', 'error'); return null; }
    return {
      code, direction:dir, customer:f.customer, rep:f.rep || null, owner:(editing && editing.owner) || p.me.name,
      issueDate:f.issueDate, validDays:+f.validDays || 30, validUntil,
      // khi sửa: giữ nguyên trạng thái & dữ liệu gửi/chuyển; khi tạo mới: nháp.
      status:editing ? editing.status : 'draft', discountPct:discPct, notes:f.notes,
      items:items.filter(it => it.name.trim()).map(it => ({ name:it.name, unit:it.unit, qty:+it.qty || 0, price:+it.price || 0, vat:+it.vat || 0, detail:(it.detail || '').trim(), showDetail:!!it.showDetail })),
      sentDate:editing ? (editing.sentDate || null) : null, sentTo:editing ? (editing.sentTo || []) : [], convertedTo:editing ? (editing.convertedTo || null) : null,
      // giữ lịch sử khi sửa; tạo mới → ghi sự kiện "tạo".
      history:editing ? (editing.history || []) : [qEvt('create', lang === 'vi' ? 'Tạo báo giá' : 'Quote created', p.me.name)],
    };
  };
  const create = (thenSend) => {
    const rec = build(); if (!rec) return;
    if (editing) p.patchQuote(editing.code, qWithHist(rec, qEvt('edit', lang === 'vi' ? 'Cập nhật báo giá' : 'Quote updated', p.me.name))); else p.saveQuote(rec);
    // Chỉ chiều BÁN mới tự bổ sung sản phẩm từ báo giá — giá trong báo giá MUA là giá NCC chào, không phải giá bán.
    if (dir === 'sell') p.reconcileProductsFromQuote(rec.items, code);
    toast((editing ? (lang === 'vi' ? 'Đã lưu báo giá ' : 'Saved ') : (lang === 'vi' ? 'Đã tạo báo giá ' : 'Created ')) + code, 'success');
    onClose();
    if (thenSend) p.sendQuote(rec);
    else p.navigate({ name:'module', module:'quotes', sub:'detail', id:code });
  };

  const cellInput = { height:26, padding:'0 6px', border:'1px solid var(--border-strong)', borderRadius:'var(--r-sm)', width:'100%', fontSize:'var(--fs-base)', background:'var(--bg)' };
  // Ô đầu (tên SP) cao hơn (input + checkbox + meta) → .tbl td mặc định middle làm các ô khác
  // lệch dòng. Canh ĐỈNH cả hàng để mọi control nằm thẳng 1 đường với input tên.
  const cellTop = { verticalAlign:'top', paddingTop:5, paddingBottom:5 };

  return (
    <>
    <Modal staticBackdrop title={editing
        ? (dir === 'buy' ? (lang === 'vi' ? 'Sửa báo giá mua · ' : 'Edit purchase quote · ') : (lang === 'vi' ? 'Sửa báo giá · ' : 'Edit quote · ')) + editing.code
        : (dir === 'buy' ? (lang === 'vi' ? 'Ghi nhận báo giá mua (từ NCC)' : 'Record purchase quote') : t('bg.new'))} width={860} onClose={onClose}
      footer={<><div className="grow flex g8 items-center"><span className="subtle">{t('hd.total')}:</span><span className="mono" style={{ fontWeight:700, color:'var(--primary)', fontSize:'var(--fs-lg)' }}>{vnd(total)}</span></div>
        <button className="btn" onClick={onClose}>{t('c.cancel')}</button>
        <button className={'btn' + (dir === 'buy' ? ' btn-primary' : '')} onClick={() => create(false)}><i className="bi bi-save"></i>{editing || dir === 'buy' ? (lang === 'vi' ? 'Lưu' : 'Save') : (lang === 'vi' ? 'Lưu nháp' : 'Save draft')}</button>
        {dir !== 'buy' && <button className="btn btn-primary" onClick={() => create(true)}><i className="bi bi-send"></i>{lang === 'vi' ? 'Lưu & gửi' : 'Save & send'}</button>}</>}>
      <div className="col g16">
        {/* header */}
        <div className="flex g12 items-center wrap" style={{ padding:'2px 0' }}>
          <span className="subtle">{t('bg.code')}:</span><span className="mono" style={{ fontWeight:600, color:'var(--primary)' }}>{code}</span><span className="badge badge-neutral">{lang === 'vi' ? 'tự sinh' : 'auto'}</span>
          <span className="grow"></span>
          <span className="subtle">{t('bg.validUntil')}:</span><span className="mono" style={{ fontWeight:600 }}>{fmtDate(validUntil)}</span>
        </div>
        <div className="flex g12 wrap">
          <div style={{ flex:'1 1 140px' }}><Field label={t('bg.issueDate')}><DateInput value={f.issueDate} onChange={v => set('issueDate', v)} /></Field></div>
          <div style={{ flex:'1 1 120px' }}><Field label={t('bg.validDays')}><input type="number" className="input" value={f.validDays} onChange={e => set('validDays', e.target.value)} /></Field></div>
          <div style={{ flex:'1 1 120px' }}><Field label={t('bg.discount') + ' (%)'}><input type="number" className="input" value={f.discountPct} onChange={e => set('discountPct', e.target.value)} /></Field></div>
        </div>

        {/* parties — chiều mua chọn NCC (cùng pattern form hợp đồng), chiều bán giữ PartyFields */}
        <div className="hr"></div>
        <div style={{ fontWeight:600, fontSize:'var(--fs-md)' }}>{dir === 'buy' ? t('hd.vendor') : (lang === 'vi' ? 'Khách hàng' : 'Customer')}</div>
        {dir === 'buy' ? (
          <div className="flex g12 wrap items-start">
            <div style={{ flex:'1 1 260px' }}><Field label={t('hd.vendor')}>
              <select className="select" value={f.customer} onChange={e => { set('customer', e.target.value); set('rep', ''); }}>
                <option value="">— {lang === 'vi' ? 'chọn nhà cung cấp' : 'select vendor'} —</option>
                {(p.vendors || []).map(v => <option key={v.code} value={v.code}>{v.code} · {v.name}</option>)}
              </select>
            </Field></div>
            <div style={{ flex:'1 1 220px' }}><Field label={lang === 'vi' ? 'Người liên hệ NCC' : 'Vendor contact'}>
              <select className="select" value={f.rep} onChange={e => set('rep', e.target.value)}>
                <option value="">—</option>
                {reps.map(r => <option key={r.code} value={r.code}>{r.name}{r.title ? ' · ' + r.title : ''}</option>)}
              </select>
            </Field></div>
          </div>
        ) : (
          <PartyFields customer={f.customer} rep={f.rep} onCustomer={v => set('customer', v)} onRep={v => set('rep', v)} showEmail={true} />
        )}

        {/* items */}
        <div className="hr"></div>
        <div className="flex justify-between items-center"><div style={{ fontWeight:600, fontSize:'var(--fs-md)' }}>{t('hd.items')}</div>
          <div className="flex g8 items-center">
            <button className="btn btn-sm btn-ghost" onClick={() => setAddProdOpen(true)}><i className="bi bi-box-seam"></i>{lang === 'vi' ? 'Tạo SP mới' : 'New product'}</button>
            <button className="btn btn-sm btn-subtle" onClick={addItem}><i className="bi bi-plus-lg"></i>{t('hd.addItem')}</button>
          </div>
        </div>
        <div className="subtle" style={{ fontSize:'var(--fs-sm)', marginTop:-6 }}><i className="bi bi-magic" style={{ marginRight:4 }}></i>{lang === 'vi' ? 'Chọn từ Danh mục SP để tự điền giá mới nhất — gõ tên mới sẽ tự thêm khi lưu, hoặc bấm "Tạo SP mới" để khai báo đầy đủ.' : 'Pick from the catalog to autofill the latest price — typed new names are auto-added on save, or click "New product" for full details.'}</div>
        <datalist id="qn-products">{products.map(pr => <option key={pr.code} value={pr.name}>{vnd(priceOf(pr))} · {pr.code}</option>)}</datalist>
        <div style={{ overflow:'auto' }}>
          <table className="tbl" style={{ minWidth:640 }}>
            <thead><tr><th>{t('hd.items')}</th><th style={{ width:64 }}>{t('hd.unit')}</th><th style={{ width:84 }} className="num">{t('hd.qty')}</th><th style={{ width:120 }} className="num">{t('hd.price')}</th><th style={{ width:64 }} className="num">{t('hd.vat')}%</th><th style={{ width:110 }} className="num">{t('hd.total')}</th><th style={{ width:30 }}></th></tr></thead>
            <tbody>
              {items.map((it, i) => { const line = (+it.qty || 0) * (+it.price || 0); const tt = line * (1 - discPct / 100) * (1 + (+it.vat || 0) / 100);
                const uCost = (products.find(pr => pr.name === it.name) || {}).cost || 0; const uMargin = (+it.price || 0) - uCost; const uPct = (+it.price || 0) ? Math.round(uMargin / (+it.price || 0) * 100) : 0; return (
                <tr key={i} style={{ cursor:'default' }}>
                  <td style={cellTop}>
                    {/* onFocus select-all: đã chọn SP rồi vẫn đổi được — gõ là thay toàn bộ, danh sách gợi ý mở lại */}
                    <input style={cellInput} list="qn-products" value={it.name} placeholder={lang === 'vi' ? 'Tên sản phẩm / dịch vụ' : 'Item name'} onChange={e => onName(i, e.target.value)} onFocus={e => e.target.select()} />
                    <label className="flex g4 items-center" style={{ fontSize:'var(--fs-sm)', color:'var(--text-muted)', marginTop:4, cursor:'pointer' }}>
                      <input type="checkbox" checked={!!it.showDetail} onChange={() => toggleDetail(i)} />{lang === 'vi' ? 'Hiển thị chi tiết' : 'Show detail'}
                    </label>
                    {it.showDetail && <textarea rows={2} style={{ ...cellInput, height:'auto', marginTop:4, fontSize:'var(--fs-sm)', resize:'vertical', padding:'4px 6px' }} value={it.detail || ''} placeholder={lang === 'vi' ? 'Chi tiết (sửa được)' : 'Detail (editable)'} onChange={e => upItem(i, 'detail', e.target.value)} />}
                    {showCost && dir === 'sell' && uCost > 0 && <div className="flex g4 items-center" style={{ fontSize:'var(--fs-sm)', color:'var(--text-muted)', marginTop:4 }} title={lang === 'vi' ? 'Chỉ hiện nội bộ — không in cho khách' : 'Internal only — not printed'}>
                      <i className="bi bi-lock" style={{ fontSize:10 }}></i>{lang === 'vi' ? 'Vốn' : 'Cost'} {vnd(uCost)} · {lang === 'vi' ? 'lãi' : 'margin'} <span style={{ color:uMargin >= 0 ? 'var(--success)' : 'var(--error)', fontWeight:600 }}>{uMargin >= 0 ? '+' : '−'}{vnd(Math.abs(uMargin))}</span> ({uPct}%)
                    </div>}
                    {(() => { const sk = window.stockOfName && stockOfName(it.name, p.products, stockMap); if (!sk) return null; const short = (+it.qty || 0) > sk.qty; const warn = short || sk.status !== 'ok'; return (
                      <div className="flex g4 items-center" style={{ fontSize:'var(--fs-sm)', color:warn ? 'var(--warning)' : 'var(--text-muted)', marginTop:4 }} title={lang === 'vi' ? 'Đối chiếu tồn kho' : 'Stock check'}>
                        <i className="bi bi-box-seam" style={{ fontSize:10 }}></i>{lang === 'vi' ? 'Tồn' : 'Stock'} {sk.qty} {sk.item.unit}{short ? (lang === 'vi' ? ' · không đủ' : ' · short') : sk.status === 'out' ? (lang === 'vi' ? ' · hết' : ' · out') : sk.status === 'low' ? (lang === 'vi' ? ' · dưới định mức' : ' · low') : ''}</div>
                    ); })()}
                  </td>
                  <td style={cellTop}><input style={cellInput} value={it.unit} onChange={e => upItem(i, 'unit', e.target.value)} /></td>
                  <td style={cellTop}><input className="no-spin" style={{ ...cellInput, textAlign:'right' }} type="number" value={it.qty} onChange={e => upItem(i, 'qty', e.target.value)} /></td>
                  <td style={cellTop}><MoneyInput className="" style={{ ...cellInput, textAlign:'right' }} value={it.price} onChange={v => upItem(i, 'price', v)} /></td>
                  <td style={cellTop}><input className="no-spin" style={{ ...cellInput, textAlign:'right' }} type="number" value={it.vat} onChange={e => upItem(i, 'vat', e.target.value)} /></td>
                  <td className="num mono" style={{ ...cellTop, fontWeight:600, lineHeight:'26px' }}>{vnd(tt)}</td>
                  <td style={{ ...cellTop, textAlign:'center' }}><button className="iconbtn" style={{ width:22, height:22, marginTop:2 }} onClick={() => rmItem(i)}><i className="bi bi-trash" style={{ fontSize:12 }}></i></button></td>
                </tr>
              ); })}
            </tbody>
            <tfoot>
              <tr style={{ cursor:'default' }}><td colSpan="4"></td><td className="num muted">{t('hd.subtotal')}</td><td className="num mono">{vnd(tot.sub)}</td><td></td></tr>
              {discount > 0 && <tr style={{ cursor:'default' }}><td colSpan="4"></td><td className="num muted">{t('bg.discount')} {discPct}%</td><td className="num mono" style={{ color:'var(--error)' }}>- {vnd(discount)}</td><td></td></tr>}
              <tr style={{ cursor:'default' }}><td colSpan="4"></td><td className="num muted">{t('hd.vatTotal')}</td><td className="num mono">{vnd(tot.vat)}</td><td></td></tr>
              <tr style={{ cursor:'default', background:'var(--bg-subtle)' }}><td colSpan="4"></td><td className="num" style={{ fontWeight:700 }}>{t('hd.total')}</td><td className="num mono" style={{ fontWeight:700, color:'var(--primary)' }}>{vnd(total)}</td><td></td></tr>
            </tfoot>
          </table>
        </div>
        {showCost && dir === 'sell' && costInfo.known && (
          <div className="flex g8 items-center wrap" style={{ fontSize:'var(--fs-base)', background:'var(--bg-subtle)', padding:'8px 12px', borderRadius:'var(--r-md)', marginTop:-6 }}>
            <i className="bi bi-lock" style={{ color:'var(--accent)' }}></i>
            <span className="subtle">{lang === 'vi' ? 'Lãi gộp dự kiến (nội bộ):' : 'Est. gross (internal):'}</span>
            <span className="mono" style={{ fontWeight:700, color:gross >= 0 ? 'var(--success)' : 'var(--error)' }}>{gross >= 0 ? '+' : '−'}{vnd(Math.abs(gross))}</span>
            <span className="subtle">· {lang === 'vi' ? 'Biên' : 'Margin'} {grossPct}%</span>
            <span className="subtle" style={{ fontSize:'var(--fs-sm)' }}>· {lang === 'vi' ? 'trước chiết khấu · không in cho khách' : 'pre-discount · not printed'}</span>
          </div>
        )}

        {/* notes */}
        <div className="hr"></div>
        <Field label={t('bg.notes')}><textarea className="textarea" rows={2} value={f.notes} onChange={e => set('notes', e.target.value)} placeholder={lang === 'vi' ? 'Ghi chú / điều khoản riêng cho báo giá này…' : 'Notes / special terms for this quote…'} /></Field>
      </div>
    </Modal>
    {addProdOpen && <NewProductModal onClose={() => setAddProdOpen(false)} onCreated={addItemFromProduct} />}
    </>
  );
}

Object.assign(window, { NewQuoteModal });
