// Selling Expenses — same form pattern as General Information, but with custom expense categories.

// Generates next running Request No. in format SE-YYMM0000 (per month).
// Continues from the highest existing Request No. for the current month:
// scans both submitted/saved requests AND previously-issued numbers, then increments.
function genNextSeNo(){
  const now = new Date();
  const yy = String(now.getFullYear()).slice(2);
  const mm = String(now.getMonth()+1).padStart(2,'0');
  const prefix = `SE-${yy}${mm}`;

  // Find the highest existing running number across submitted requests for this month
  let maxN = -1;
  try {
    const saved = JSON.parse(localStorage.getItem('finx_se_requests_v1') || '{}');
    Object.keys(saved).forEach(k => {
      if (k.startsWith(prefix)){
        const n = parseInt(k.slice(prefix.length), 10);
        if (!isNaN(n) && n > maxN) maxN = n;
      }
    });
  } catch(_){}

  // Also include any number previously issued (but possibly not yet submitted)
  const issuedKey = 'finx_se_run_'+prefix;
  const issuedMax = parseInt(localStorage.getItem(issuedKey) || '-1', 10);
  if (!isNaN(issuedMax) && issuedMax > maxN) maxN = issuedMax;

  const next = maxN + 1;
  localStorage.setItem(issuedKey, String(next));   // remember this is now used
  return `${prefix}${String(next).padStart(4,'0')}`;
}
// Peek next number without incrementing — used in modals so we show the SAME number
function peekCurrentSeNo(currentReqNo){
  return currentReqNo;
}
const EXPENSE_CATS = [
  'ค่าเช่า - สาขาเก่า',
  'ค่าเช่า - สาขาใหม่',
  'ค่าก่อสร้าง - Renovate',
  'ค่าก่อสร้าง - Relocation',
  'ค่าก่อสร้าง - สาขาใหม่',
  'ค่าก่อสร้าง - อื่นๆ',
  'ค่าซ่อมแซม - สาขา',
  'ค่าเครื่องจักร และค่าผ่อน',
  'ค่ารถยนต์ ค่าผ่อน ประกัน',
  'เดินทางปฏิบัติงาน',
  'สินทรัพย์',
  'ค่าสินค้าทั่วไป',
  'ค่าสินค้านำเข้า',
  'ค่าสินค้า JS - OEM',
  'ขนส่ง',
  'บัตรน้ำมัน',
  'Supply Use',
  'Online',
  'เงินยืม',
  'Project',
  'ค่าซ่อมแซม - คลัง',
  'ปอศ. / มอก.',
  'ค่าเช่า - อุปกรณ์ดำเนินงาน',
  'ค่าระบบ',
  'ค่าสันทนาการ',
  'ค่าสาธารณูปโภค',
  'ค่าภาษี',
  'ค่าใช้จ่ายอื่นๆ - สาขา',
  'ค่าใช้จ่ายอื่นๆ - คลัง',
  'รับเงินคืน',
  'ฝึกอบรม',
];

// Sensible seed values so the page looks alive on first load (only ~10 are non-zero)
const SEED_VALUES = {
  'ค่าเช่า - สาขาเก่า': 120000,
  'ค่าเช่า - สาขาใหม่': 85000,
  'ค่าก่อสร้าง - Renovate': 320000,
  'ค่าซ่อมแซม - สาขา': 18500,
  'ค่ารถยนต์ ค่าผ่อน ประกัน': 42800,
  'เดินทางปฏิบัติงาน': 9800,
  'ค่าสินค้าทั่วไป': 245600,
  'ขนส่ง': 32400,
  'บัตรน้ำมัน': 14250,
  'ค่าสาธารณูปโภค': 28900,
  'ค่าภาษี': 65000,
};

// Default state: empty (all fields blank, including Request No.).
// Request No. is auto-generated only when user clicks Add Item for the first time.
// Branch is empty until a Responsible Person is selected.
const initialSelling = () => {
  const items = {};
  EXPENSE_CATS.forEach(c => items[c] = 0);
  return {
    reqNo: '',
    reqDate: '',
    currency: '',
    person: '',
    dept: '',                 // auto-fills from selected person
    fy: '',
    fm: '',
    branch: '',               // auto-fills to "สำนักงานใหญ่" once a person is selected
    items,
  };
};

// Fields cleared when Reset is clicked. ทุกช่องล้างเป็นค่าว่าง
const clearedGeneral = (reqNo) => ({
  reqNo,
  reqDate: '',
  currency: '',
  person: '',
  dept: '',
  branch: '',
  fy: '',
  fm: '',
});

function SellingExpensesView({ onNav }){
  const clock = useSystemClock();
  const [form, setForm] = useState(()=> initialSelling());
  const [locked, setLocked] = useState(false);           // true once Request No. is issued or a saved record is loaded
  const [reqSearch, setReqSearch] = useState('');        // typed value while searching (before lock)
  const [expensesUnlocked, setExpensesUnlocked] = useState(false);  // true only after user clicks "Next: Expenses Details"

  // Seed a few past requests once so the search demo works out of the box
  useEffect(()=>{
    const KEY = 'finx_se_requests_v1';
    if (!localStorage.getItem(KEY)){
      const seed = {
        'SE-26040001': {
          reqNo:'SE-26040001', reqDate:'2026-04-12', currency:'THB',
          person:'ณัฐรดา เจริญสุข', dept:'Finance & Accounting',
          branch:'สำนักงานใหญ่', fy:'2026', fm:'April',
          items: EXPENSE_CATS.reduce((o,c)=>{o[c]=0;return o;}, {}),
        },
        'SE-26050000': {
          reqNo:'SE-26050000', reqDate:'2026-05-08', currency:'THB',
          person:'Pim Kanyarat', dept:'Cashier',
          branch:'สำนักงานใหญ่', fy:'2026', fm:'May',
          items: EXPENSE_CATS.reduce((o,c)=>{o[c]=0;return o;}, {}),
        },
      };
      // give the seeds a few amounts so the preview looks alive
      seed['SE-26040001'].items['ค่าเช่า - สาขาเก่า']      = 120000;
      seed['SE-26040001'].items['ค่าก่อสร้าง - Renovate']  = 320000;
      seed['SE-26040001'].items['ค่าสาธารณูปโภค']          = 28900;
      seed['SE-26050000'].items['ค่าสินค้าทั่วไป']         = 245600;
      seed['SE-26050000'].items['ขนส่ง']                  = 32400;
      localStorage.setItem(KEY, JSON.stringify(seed));
    }
  },[]);
  const [step, setStep] = useState(1);
  const [open1, setOpen1] = useState(true);
  const [open2, setOpen2] = useState(true);
  const [search, setSearch] = useState('');
  const dirtyRef = useRef(false);

  const set = (k,v) => { dirtyRef.current = true; setForm(f => ({...f, [k]:v})); };

  // Responsible Person change → auto-fill Department & Branch (default "สำนักงานใหญ่")
  const onPersonChange = (e) => {
    const name = e.target.value;
    const user = USERS.find(u => u.name === name);
    dirtyRef.current = true;
    setForm(f => ({
      ...f,
      person: name,
      dept:   user ? user.dept : '',
      branch: name ? 'สำนักงานใหญ่' : '',
    }));
  };

  // Search a previously-saved request by Request No.
  const onSearchReqNo = () => {
    const q = reqSearch.trim().toUpperCase();
    if (!q){ window.toast('กรอกเลขที่ Request No. ที่ต้องการค้นหา', {tone:'info'}); return; }
    const saved = JSON.parse(localStorage.getItem('finx_se_requests_v1') || '{}');
    if (saved[q]){
      const rec = saved[q];
      setForm({ ...rec, items: Object.fromEntries(EXPENSE_CATS.map(c=>[c, rec.items?.[c] || 0])) });
      setLocked(true);
      setExpensesUnlocked(true);  // a loaded record can be reviewed/edited in Expenses Details
      setReqSearch('');
      window.toast(`โหลดรายการ ${q} สำเร็จ`, {tone:'success', title:'พบข้อมูล'});
    } else {
      window.toast(`ไม่พบเลขที่ ${q} ในระบบ`, {tone:'warn', title:'ค้นหาไม่พบ'});
    }
  };
  const setItem = (cat, val) => {
    dirtyRef.current = true;
    setForm(f => ({...f, items:{...f.items, [cat]:val}}));
  };
  const clearItem = (cat) => setForm(f => ({...f, items:{...f.items, [cat]:0}}));

  // Live totals
  const total = Object.values(form.items).reduce((s,v)=>s+(v||0),0);
  const itemCount = Object.values(form.items).filter(v=>v>0).length;
  const top5 = Object.entries(form.items)
    .filter(([,v])=>v>0)
    .sort((a,b)=>b[1]-a[1])
    .slice(0,5);

  // General Information completeness — all fields must have a value
  const GENERAL_FIELDS = ['reqNo','reqDate','currency','person','dept','branch','fy','fm'];
  const missingFields = GENERAL_FIELDS.filter(k => !form[k] || String(form[k]).trim()==='');
  const isGeneralComplete = missingFields.length === 0;
  const fieldLabels = {
    reqNo:'Request No.', reqDate:'Request Date', currency:'Currency',
    person:'Responsible Person', dept:'Department', branch:'Branch / Location',
    fy:'Fiscal Year', fm:'Fiscal Month'
  };

  // Auto-save toast every 30s if dirty
  useEffect(()=>{
    const t = setInterval(()=>{
      if (dirtyRef.current){
        dirtyRef.current = false;
        window.toast('Draft auto-saved · '+new Date().toLocaleTimeString(), {tone:'info', ttl:1800});
      }
    }, 30000);
    return ()=>clearInterval(t);
  },[]);

  // Filtered list (search by Thai/English)
  const filteredCats = EXPENSE_CATS.filter(c =>
    !search || c.toLowerCase().includes(search.toLowerCase())
  );

  const onPreview = () => window.openModal({
    title:'Preview · '+form.reqNo, size:'lg',
    message: <SellingPreview form={form} total={total} itemCount={itemCount}/>,
    actions:[
      { label:'Close', kind:'ghost' },
      { label:'Submit now', kind:'primary', onClick:onSubmit }
    ]
  });
  const onExit = () => {
    if (!dirtyRef.current){
      onNav && onNav('dashboard'); return;
    }
    window.confirmDialog({
      title:'Exit without saving?',
      message:'You have unsaved changes. Leaving will discard your edits.',
      tone:'danger', okLabel:'Discard & exit',
      onOk: ()=>{ onNav && onNav('dashboard'); }
    });
  };
  const onSaveDraft = () => { dirtyRef.current = false; window.toast('Draft saved · '+form.reqNo, {tone:'success', title:'Saved'}); };
  const onSubmit = () => {
    if (total <= 0){ window.toast('Enter at least one expense before submitting', {tone:'warn'}); return; }
    if (!form.reqNo){ window.toast('กรุณากด Add Item เพื่อออกเลขที่ Request No. ก่อน', {tone:'warn'}); return; }
    window.confirmDialog({
      title:'Submit '+form.reqNo+'?',
      message:`${itemCount} items · total ${fmt(total)} THB will be submitted for approval. ระบบจะบันทึกข้อมูลลง Database และล้างฟอร์มกลับเป็นค่าเริ่มต้นโดยอัตโนมัติ`,
      okLabel:'Submit', tone:'primary',
      onOk: ()=>{
        // Persist to localStorage + Cloudflare D1
        const saved = JSON.parse(localStorage.getItem('finx_se_requests_v1') || '{}');
        saved[form.reqNo] = { ...form, submittedAt: new Date().toISOString() };
        localStorage.setItem('finx_se_requests_v1', JSON.stringify(saved));
        window.finxDB.saveSeRequest(form, 'Submitted').catch(() => {});
        const submittedNo = form.reqNo;

        // Reset all fields to defaults
        setForm(initialSelling());
        setLocked(false);
        setExpensesUnlocked(false);
        setStep(1);
        setReqSearch('');
        setOpen1(true);
        setOpen2(true);
        setSearch('');
        dirtyRef.current = false;

        window.toast(submittedNo+' submitted · ฟอร์มถูกล้างพร้อมสร้างรายการใหม่',
                     {tone:'success', title:'Submitted & saved', ttl:3800});
      }
    });
  };
  const onReset = () => {
    window.confirmDialog({
      title:'Reset General Information?',
      message:'ฟิลด์ทั้งหมดในส่วน General Information จะถูกล้างค่า (รวมถึง Request No.) ระบบจะออก Request No. ใหม่เมื่อกด Add Item ครั้งถัดไป',
      tone:'danger', okLabel:'Reset',
      onOk: ()=>{
        setForm(f => ({ ...f, ...clearedGeneral('') }));
        setLocked(false);
        setReqSearch('');
        setExpensesUnlocked(false);
        dirtyRef.current = false;
        window.toast('General Information reset', {tone:'success'});
      }
    });
  };
  const onAddItem = () => {
    if (locked){
      window.toast('Request No. already issued · '+form.reqNo, {tone:'info'});
      return;
    }
    const reqNo = genNextSeNo();
    setForm(f => ({...f, reqNo}));
    setLocked(true);
    setReqSearch('');
    window.toast('Request No. issued · '+reqNo, {tone:'success', title:'Add Item'});
  };
  const onClearAll = () => {
    window.confirmDialog({
      title:'Clear all amounts?', tone:'danger', okLabel:'Clear',
      message:'All expense amounts will be reset to 0.',
      onOk: ()=>{
        setForm(f => ({...f, items: Object.fromEntries(Object.keys(f.items).map(k=>[k,0]))}));
        window.toast('All amounts cleared');
      }
    });
  };
  const exportCSV = () => {
    const rows = [['Category','Amount (THB)']];
    Object.entries(form.items).forEach(([k,v]) => rows.push([k, v.toFixed(2)]));
    rows.push(['TOTAL', total.toFixed(2)]);
    window.downloadCSV(`selling_expenses_${form.reqNo}.csv`, rows);
    window.toast('Expenses exported',{tone:'success'});
  };

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-title">Selling Expenses</div>
          <div className="page-sub">บันทึกค่าใช้จ่ายในการขาย · {form.reqNo}</div>
        </div>
        <div className="row" style={{gap:8}}>
          <button className="btn" onClick={onPreview}><I.Eye size={14}/> Preview</button>
          <button className="btn" onClick={exportCSV}><I.Download size={14}/> Export</button>
          <button className="btn danger" onClick={onExit}><I.Logout size={14}/> Exit</button>
          <button className="btn success" onClick={onSaveDraft}><I.Save size={14}/> Save draft</button>
          <button className="btn primary" onClick={onSubmit}><I.Check size={14}/> Submit</button>
        </div>
      </div>

      {/* Stepper — 3 steps only (no Attachments) */}
      <div className="card" style={{padding:'16px 20px',marginBottom:18}}>
        <div className="row" style={{gap:8,alignItems:'center'}}>
          {['General','Expenses','Review'].map((s,i)=>{
            const idx = i+1, active = step===idx, done = step>idx;
            return (
              <React.Fragment key={i}>
                <div className="row" style={{gap:10,cursor:'pointer'}} onClick={()=>setStep(idx)}>
                  <div style={{
                    width:30,height:30,borderRadius:50,display:'grid',placeItems:'center',fontWeight:700,fontSize:13,
                    background:(active||done)?'linear-gradient(135deg,#2cb8b0,#1f2a8e)':'#eef1f8',
                    color:(active||done)?'#fff':'#7b87a8',
                    boxShadow:active?'0 0 0 4px rgba(31,42,142,.12)':'none',transition:'.2s'
                  }}>{done ? <I.Check size={14}/> : idx}</div>
                  <div>
                    <div style={{fontSize:11,color:'var(--muted)',letterSpacing:'.06em',textTransform:'uppercase'}}>Step {idx}</div>
                    <div style={{fontWeight:700,fontSize:13}}>{s}</div>
                  </div>
                </div>
                {i<2 && <div style={{flex:1,height:2,background:step>idx?'linear-gradient(90deg,#2cb8b0,#1f2a8e)':'#eef1f8',borderRadius:2,transition:'.3s'}}/>}
              </React.Fragment>
            );
          })}
        </div>
      </div>

      <div className="stack" style={{gap:18}}>
        {/* General Information pane — same as General Information page */}
        <Pane title="General Information" open={open1} onToggle={()=>setOpen1(!open1)} accent>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr auto',gap:14,alignItems:'flex-end'}}>
            <div className="field">
              <label>Request No. <span className="req">*</span> <span style={{color:'#7b87a8',fontWeight:500,fontSize:11,marginLeft:4}}>{locked ? '(locked)' : '(auto / search)'}</span></label>
              <div style={{position:'relative'}}>
                <input className="input mono"
                       value={locked ? form.reqNo : reqSearch}
                       readOnly={locked}
                       placeholder={locked ? '' : 'ค้นหา หรือกด Add Item'}
                       title={locked ? 'Request No. is auto-generated and cannot be edited' : 'พิมพ์เลข Request No. แล้วกด Enter เพื่อค้นหารายการเดิม'}
                       onChange={e => !locked && setReqSearch(e.target.value.toUpperCase())}
                       onKeyDown={e => { if (!locked && e.key === 'Enter'){ e.preventDefault(); onSearchReqNo(); } }}
                       onFocus={e => { if (!locked) e.target.placeholder = ''; }}
                       onBlur={e => { if (!locked) e.target.placeholder = 'ค้นหา หรือกด Add Item'; }}
                       style={{
                         background: locked ? 'linear-gradient(135deg,#eef1f8,#fff)' : '#fff',
                         color: locked ? '#1f2a8e' : 'var(--ink)',
                         fontWeight:700,letterSpacing:'.04em',
                         paddingRight: locked ? 36 : 12,
                         cursor: locked ? 'not-allowed' : 'text'
                       }}/>
                {locked && (
                  <I.Lock size={14} stroke="#7b87a8"
                    style={{position:'absolute',right:12,top:'50%',transform:'translateY(-50%)'}}/>
                )}
              </div>
            </div>
            <div className="field">
              <label>Request Date <span className="req">*</span></label>
              <div className="dateinput">
                <I.Cal size={14} stroke="#7b87a8"/>
                <input type="date" value={form.reqDate} onChange={e=>set('reqDate',e.target.value)}/>
              </div>
            </div>
            <div className="field">
              <label>Currency <span className="req">*</span></label>
              <select className="select" value={form.currency} onChange={e=>set('currency',e.target.value)}>
                <option value="">— Select —</option>
                <option>THB</option>
              </select>
            </div>
            <div className="row" style={{gap:8}}>
              <button className="btn success" onClick={onAddItem}><I.Plus size={14}/> Add Item</button>
              <button className="btn primary" onClick={onReset}><I.Reset size={14}/> Reset</button>
            </div>
          </div>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr 1fr',gap:14,marginTop:14}}>
            <div className="field">
              <label>Responsible Person <span className="req">*</span></label>
              <select className="select thai" value={form.person} onChange={onPersonChange}>
                <option value="">— Select —</option>
                {USERS.filter(u => u.status !== 'inactive').map(u => (
                  <option key={u.id} value={u.name}>{u.name}</option>
                ))}
              </select>
            </div>
            <div className="field">
              <label>Department <span className="req">*</span> <span style={{color:'#7b87a8',fontWeight:500,fontSize:11,marginLeft:4}}>(auto)</span></label>
              <div style={{position:'relative'}}>
                <input className="input thai" value={form.dept} readOnly
                       placeholder="— เลือก Responsible Person ก่อน —"
                       title="Auto-filled from Responsible Person"
                       style={{
                         background: form.dept ? 'linear-gradient(135deg,#eef1f8,#fff)' : '#fafbff',
                         color: form.dept ? 'var(--ink)' : '#9aa3c2',
                         fontWeight:600,paddingRight:32,cursor:'not-allowed'
                       }}/>
                <I.Lock size={14} stroke="#7b87a8"
                  style={{position:'absolute',right:12,top:'50%',transform:'translateY(-50%)'}}/>
              </div>
            </div>
            <div className="field">
              <label>Branch / Location <span style={{color:'#7b87a8',fontWeight:500,fontSize:11,marginLeft:4}}>(default)</span></label>
              <div style={{position:'relative'}}>
                <input className="input thai" value={form.branch} readOnly
                       title="Default — สำนักงานใหญ่"
                       style={{
                         background:'linear-gradient(135deg,#eef1f8,#fff)',
                         color:'var(--ink)',fontWeight:600,paddingRight:32,cursor:'not-allowed'
                       }}/>
                <I.Lock size={14} stroke="#7b87a8"
                  style={{position:'absolute',right:12,top:'50%',transform:'translateY(-50%)'}}/>
              </div>
            </div>
            <div className="field">
              <label>Fiscal Year <span className="req">*</span></label>
              <select className="select" value={form.fy} onChange={e=>set('fy',e.target.value)}>
                <option value="">— Select —</option>
                {['2026','2027','2028'].map(y=><option key={y}>{y}</option>)}
              </select>
            </div>
            <div className="field" style={{gridColumn:'span 4',maxWidth:280}}>
              <label>Fiscal Month <span className="req">*</span></label>
              <select className="select" value={form.fm} onChange={e=>set('fm',e.target.value)}>
                <option value="">— Select —</option>
                {['January','February','March','April','May','June','July','August','September','October','November','December'].map(m=><option key={m}>{m}</option>)}
              </select>
            </div>
          </div>
          <div style={{marginTop:18,display:'flex',justifyContent:'flex-end'}}>
            <button className="btn primary"
                    onClick={()=>{
                      if (!isGeneralComplete){
                        window.toast(
                          'ยังขาด: ' + missingFields.map(k=>fieldLabels[k]).join(', '),
                          { tone:'warn', title:'กรุณากรอกข้อมูลให้ครบทุกช่อง', ttl:4500 }
                        );
                        return;
                      }
                      setExpensesUnlocked(true);
                      setStep(2);
                      window.toast('Expenses Details ปลดล็อคแล้ว · เริ่มกรอกค่าใช้จ่ายได้', {tone:'success'});
                    }}>
              Next: Expenses Details <I.Chev size={12}/>
            </button>
          </div>
        </Pane>

        {/* Expenses Details pane — long list */}
        <Pane title="Expenses Details" open={open2} onToggle={()=>setOpen2(!open2)} accent>
          {/* Wrapper that grays out the entire details body until user clicks "Next: Expenses Details" */}
          <div style={{
            opacity: expensesUnlocked ? 1 : 0.45,
            filter:  expensesUnlocked ? 'none' : 'grayscale(.55)',
            pointerEvents: expensesUnlocked ? 'auto' : 'none',
            transition:'opacity .25s ease, filter .25s ease',
            position:'relative',
          }}>
          {/* Summary strip */}
          <div style={{
            display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:14,marginBottom:18
          }}>
            <SumBox label="Total Expenses" value={total} sub="THB" tone="#1f2a8e" big/>
            <SumBox label="Items entered"  value={itemCount} sub={`of ${EXPENSE_CATS.length} categories`} tone="#2cb8b0" raw/>
            <SumBox label="Avg / item"     value={itemCount? total/itemCount:0} sub="THB" tone="#16a34a"/>
            <SumBox label="Largest item"   value={top5[0]?.[1]||0} sub={top5[0]?.[0]||'—'} tone="#dc2626"/>
          </div>

          {/* Top spenders chart */}
          {top5.length>0 && (
            <div style={{
              padding:'14px 16px',background:'linear-gradient(180deg,#f7f8fc,#fff)',
              border:'1px solid var(--line)',borderRadius:12,marginBottom:18
            }}>
              <div className="row between" style={{marginBottom:10}}>
                <div style={{fontWeight:700,fontSize:13}}>Top expense categories</div>
                <span className="chip">Top {top5.length}</span>
              </div>
              {top5.map(([cat,v],i)=>{
                const pct = (v/top5[0][1])*100;
                const colors = ['#1f2a8e','#2cb8b0','#7c6eff','#f59e0b','#dc2626'];
                return (
                  <div key={cat} style={{margin:'6px 0'}}>
                    <div className="row between" style={{marginBottom:4}}>
                      <span className="thai" style={{fontSize:12.5,fontWeight:600}}>{cat}</span>
                      <span className="mono" style={{fontSize:12,fontWeight:700,color:colors[i]}}>{fmt(v)}</span>
                    </div>
                    <div style={{height:6,background:'#eef1f8',borderRadius:6,overflow:'hidden'}}>
                      <div style={{
                        width:pct+'%',height:'100%',transition:'width .6s ease',
                        background:`linear-gradient(90deg, ${colors[i]}, ${colors[i]}aa)`
                      }}/>
                    </div>
                  </div>
                );
              })}
            </div>
          )}

          {/* Action row */}
          <div className="row between" style={{marginBottom:12,flexWrap:'wrap',gap:10}}>
            <div className="search" style={{width:280}}>
              <I.Search size={14} stroke="#9aa3c2"/>
              <input placeholder="ค้นหารายการ…" value={search} onChange={e=>setSearch(e.target.value)}/>
            </div>
            <div className="row" style={{gap:8}}>
              <span className="chip">{filteredCats.length} of {EXPENSE_CATS.length} shown</span>
              <button className="btn sm" onClick={onClearAll}><I.Reset size={12}/> Clear all</button>
              <button className="btn sm" onClick={onAddItem}><I.Plus size={12}/> Add custom</button>
            </div>
          </div>

          {/* Two-column expense grid */}
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:10}}>
            {filteredCats.map((cat,i)=>(
              <ExpenseRow key={cat} index={i} cat={cat}
                          value={form.items[cat]||0}
                          onChange={(v)=>setItem(cat,v)}
                          onClear={()=>clearItem(cat)}/>
            ))}
            {filteredCats.length===0 && (
              <div style={{gridColumn:'1 / -1',textAlign:'center',padding:32,color:'var(--muted)',fontSize:13}}>
                No categories match "{search}"
              </div>
            )}
          </div>

          {/* Total bar */}
          <div style={{
            marginTop:18,padding:'14px 18px',
            background:'linear-gradient(135deg,#1f2a8e,#2e3bbf)',color:'#fff',
            borderRadius:12,display:'flex',justifyContent:'space-between',alignItems:'center',
            boxShadow:'0 12px 30px -16px rgba(31,42,142,.6)'
          }}>
            <div>
              <div style={{fontSize:11,letterSpacing:'.1em',textTransform:'uppercase',opacity:.7}}>Grand Total Selling Expenses</div>
              <div className="mono" style={{fontSize:30,fontWeight:800,marginTop:2}}>{fmt(total)} <span style={{fontSize:14,opacity:.7}}>THB</span></div>
            </div>
            <div style={{textAlign:'right'}}>
              <div style={{fontSize:11,opacity:.7}}>Items</div>
              <div className="mono" style={{fontSize:24,fontWeight:800}}>{itemCount} <span style={{fontSize:12,opacity:.7}}>/ {EXPENSE_CATS.length}</span></div>
            </div>
          </div>

          <div style={{marginTop:18,display:'flex',justifyContent:'space-between'}}>
            <button className="btn" onClick={()=>setStep(1)}>← Back</button>
            <button className="btn primary" onClick={()=>{ setStep(3); onPreview(); }}>Review <I.Chev size={12}/></button>
          </div>
          </div>{/* /lock wrapper */}
        </Pane>
      </div>

      <div style={{marginTop:18,display:'flex',justifyContent:'space-between',color:'var(--muted)',fontSize:12,fontStyle:'italic'}}>
        <span>{dirtyRef.current ? 'Unsaved changes…' : 'All changes saved'}</span>
        <span>{clock}</span>
      </div>
    </div>
  );
}

function ExpenseRow({ cat, value, onChange, onClear, index }){
  const has = value > 0;
  const [draft, setDraft] = useState('');
  const [focused, setFocused] = useState(false);

  // Display: while focused show raw draft, otherwise show formatted
  const display = focused
    ? draft
    : (value===0 ? '' : fmt(value));

  return (
    <div style={{
      display:'flex',alignItems:'center',gap:10,padding:'8px 12px',
      background: has ? 'linear-gradient(90deg,#eef0ff,#f7f8fc)' : '#fff',
      border:'1px solid '+(has?'#d8def5':'var(--line)'),
      borderRadius:10,transition:'.18s',
      animation:`fadein .25s ${Math.min(index,30)*15}ms both`,
    }}>
      <div style={{
        width:28,height:28,borderRadius:8,flex:'none',display:'grid',placeItems:'center',
        background: has ? 'linear-gradient(135deg,#2cb8b0,#1f2a8e)' : '#f1f3fa',
        color: has ? '#fff' : '#7b87a8',fontWeight:700,fontSize:11,
      }}>{index+1}</div>
      <div className="thai" style={{flex:1,fontSize:13,fontWeight:600,color:'var(--ink)',minWidth:0,
        whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{cat}</div>
      <input className="input mono expense-input"
        type="text" inputMode="decimal"
        style={{
          height:34,width:140,textAlign:'right',padding:'0 10px',
          fontWeight:700,color: has?'#1f2a8e':'#9aa3c2',
          background: has ? '#fff' : 'transparent',
        }}
        value={display}
        placeholder={focused ? '' : '0.00'}
        onFocus={(e)=>{
          setDraft(value === 0 ? '' : String(value));
          setFocused(true);
          setTimeout(()=> e.target.select(), 0);
        }}
        onChange={(e)=>{
          // Allow digits, single dot, and optional leading minus
          const raw = e.target.value.replace(/[^\d.\-]/g,'');
          // keep only first dot
          const parts = raw.split('.');
          const cleaned = parts.length > 1
            ? parts[0] + '.' + parts.slice(1).join('').slice(0,2)
            : raw;
          setDraft(cleaned);
          const n = parseFloat(cleaned);
          onChange(isNaN(n) ? 0 : n);
        }}
        onKeyDown={(e)=>{
          if (e.key === 'Enter'){
            e.preventDefault();
            // commit + format
            const n = parseFloat(draft);
            const final = isNaN(n) ? 0 : Math.round(n * 100) / 100;
            onChange(final);
            setFocused(false);   // shows formatted "1,234.56"
            e.target.blur();
            // jump to next expense input
            setTimeout(()=>{
              const inputs = Array.from(document.querySelectorAll('.expense-input'));
              const idx = inputs.indexOf(e.target);
              if (idx >= 0 && inputs[idx+1]) inputs[idx+1].focus();
            }, 0);
          }
        }}
        onBlur={()=>{
          setFocused(false);
          // commit: round to 2 decimals
          const n = parseFloat(draft);
          onChange(isNaN(n) ? 0 : Math.round(n * 100) / 100);
        }}/>
      <span style={{fontSize:11,color:'var(--muted)',fontWeight:600,width:24}}>THB</span>
      <button className="icon-btn" style={{width:28,height:28,opacity:has?1:0.3}}
              disabled={!has} onClick={onClear} title="Clear">
        <I.Reset size={12}/>
      </button>
    </div>
  );
}

function SumBox({ label, value, sub, tone, big, raw }){
  return (
    <div style={{
      background:'#fff',border:'1px solid var(--line)',borderRadius:12,padding:'12px 14px',
      borderLeft:`4px solid ${tone}`
    }}>
      <div style={{fontSize:11.5,color:'var(--muted)',fontWeight:600,marginBottom:4}}>{label}</div>
      <div className="mono" style={{fontSize:big?22:18,fontWeight:800,color:tone,letterSpacing:'-.01em'}}>
        {raw ? value : fmt(value)}
      </div>
      <div className="thai" style={{fontSize:11,color:'var(--muted)',marginTop:2,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{sub}</div>
    </div>
  );
}

function AddItemForm({ reqNo, categories, currentItems, onSubmit }){
  const [mode, setMode] = useState('existing');         // 'existing' | 'custom'
  const [category, setCategory] = useState(categories[0]);
  const [customName, setCustomName] = useState('');
  const [amount, setAmount] = useState('');

  // Validation
  const isCustom = mode === 'custom';
  const finalCat = isCustom ? customName.trim() : category;
  const allCats = Object.keys(currentItems);
  const dupCustom = isCustom && allCats.includes(customName.trim());
  const amt = parseFloat(String(amount).replace(/,/g,'')) || 0;
  const ok = finalCat && amt > 0 && !dupCustom;

  // Currently-used count
  const usedCount = Object.values(currentItems).filter(v=>v>0).length;

  return (
    <div style={{display:'grid',gap:12}}>
      {/* Auto-generated Request No. */}
      <div className="field">
        <label>Request No. <span className="req">*</span> <span style={{color:'#7b87a8',fontWeight:500,fontSize:11,marginLeft:4}}>(auto-generated)</span></label>
        <div style={{position:'relative'}}>
          <input className="input mono" value={reqNo} readOnly
                 title="Request No. is auto-generated · SE-YYMM-running"
                 style={{
                   background:'linear-gradient(135deg,#eef1f8,#fff)',
                   color:'#1f2a8e',fontWeight:700,letterSpacing:'.04em',
                   paddingRight:36,cursor:'not-allowed'
                 }}/>
          <I.Lock size={14} stroke="#7b87a8"
            style={{position:'absolute',right:12,top:'50%',transform:'translateY(-50%)'}}/>
        </div>
        <div style={{fontSize:11,color:'var(--muted)',marginTop:4}}>
          Format: SE-YYMM + 4-digit running. ระบบสร้างเลขที่อัตโนมัติ ไม่สามารถแก้ไขเองได้
        </div>
      </div>

      {/* Mode toggle */}
      <div className="seg" style={{width:'100%'}}>
        <button className={mode==='existing'?'on':''} onClick={()=>setMode('existing')} style={{flex:1}}>
          From list ({categories.length})
        </button>
        <button className={mode==='custom'?'on':''} onClick={()=>setMode('custom')} style={{flex:1}}>
          Custom category
        </button>
      </div>

      {/* Category picker */}
      {mode==='existing' ? (
        <div className="field">
          <label>Category <span className="req">*</span></label>
          <select className="select thai" value={category} onChange={e=>setCategory(e.target.value)}>
            {categories.map(c => {
              const v = currentItems[c] || 0;
              return <option key={c} value={c}>{c}{v>0?` — currently ${fmt(v)} THB`:''}</option>;
            })}
          </select>
          {currentItems[category] > 0 && (
            <div style={{fontSize:11,color:'#d97706',marginTop:4}}>
              ⚠ This category already has {fmt(currentItems[category])} THB — will be replaced
            </div>
          )}
        </div>
      ) : (
        <div className="field">
          <label>Custom category name <span className="req">*</span></label>
          <input className="input thai" value={customName} onChange={e=>setCustomName(e.target.value)}
                 placeholder="เช่น ค่าใช้จ่ายอื่นๆ - งานแสดงสินค้า"/>
          {dupCustom && <div style={{fontSize:11,color:'#dc2626',marginTop:4}}>Category already exists</div>}
        </div>
      )}

      {/* Amount */}
      <div className="field">
        <label>Amount <span className="req">*</span></label>
        <div className="input-group">
          <input className="input mono lg" type="text" inputMode="decimal"
                 value={amount} onChange={e=>{
                   const raw = e.target.value.replace(/[^\d.\-]/g,'');
                   const parts = raw.split('.');
                   setAmount(parts.length>1 ? parts[0]+'.'+parts.slice(1).join('').slice(0,2) : raw);
                 }}
                 placeholder="0.00"
                 style={{textAlign:'right',fontWeight:700,color:'#1f2a8e'}}/>
          <span className="suffix">THB</span>
        </div>
      </div>

      {/* Summary chip */}
      <div className="row" style={{gap:6,flexWrap:'wrap'}}>
        <span className="chip">Items in this request: <b style={{marginLeft:4}}>{usedCount}</b></span>
        {amt>0 && finalCat && (
          <span className="chip green">Adding: <b className="thai" style={{margin:'0 4px'}}>{finalCat}</b> · {fmt(amt)} THB</span>
        )}
      </div>

      <button className="btn primary" disabled={!ok} style={{justifyContent:'center'}}
              onClick={()=>{ onSubmit({category:finalCat, amount:amt, isCustom}); window.closeModal(); }}>
        <I.Plus size={14}/> Add to request
      </button>
    </div>
  );
}

function SellingPreview({ form, total, itemCount }){
  const meta = [
    ['Request No.', form.reqNo],
    ['Date', form.reqDate],
    ['Currency', form.currency],
    ['Responsible', form.person],
    ['Department', form.dept],
    ['Branch', form.branch],
    ['Period', form.fm+' '+form.fy],
  ];
  const items = Object.entries(form.items).filter(([,v])=>v>0).sort((a,b)=>b[1]-a[1]);
  return (
    <div>
      <div style={{
        background:'linear-gradient(135deg,#1f2a8e,#2e3bbf)',color:'#fff',
        padding:18,borderRadius:14,marginBottom:18,display:'flex',justifyContent:'space-between'
      }}>
        <div>
          <div style={{fontSize:11,letterSpacing:'.1em',textTransform:'uppercase',opacity:.7}}>Total Selling Expenses</div>
          <div className="mono" style={{fontSize:32,fontWeight:800,marginTop:4}}>{fmt(total)} <span style={{fontSize:14,opacity:.7}}>THB</span></div>
        </div>
        <div style={{textAlign:'right'}}>
          <div style={{fontSize:11,opacity:.7}}>Items</div>
          <div className="mono" style={{fontSize:22,fontWeight:800}}>{itemCount}</div>
        </div>
      </div>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:6,marginBottom:14}}>
        {meta.map(([k,v],i)=>(
          <div key={i} style={{display:'flex',justifyContent:'space-between',padding:'8px 12px',background:i%2?'#f7f8fc':'transparent',borderRadius:6,fontSize:13}}>
            <span style={{color:'var(--muted)'}}>{k}</span>
            <span className="thai" style={{fontWeight:600}}>{v}</span>
          </div>
        ))}
      </div>
      <div style={{fontWeight:700,fontSize:13,marginBottom:6}}>Expenses breakdown</div>
      <div style={{maxHeight:240,overflow:'auto',border:'1px solid var(--line)',borderRadius:8}}>
        {items.length===0 && <div style={{padding:18,textAlign:'center',color:'var(--muted)',fontSize:13}}>No expenses entered</div>}
        {items.map(([k,v],i)=>(
          <div key={k} style={{display:'flex',justifyContent:'space-between',padding:'8px 12px',background:i%2?'#f7f8fc':'#fff',fontSize:13}}>
            <span className="thai">{k}</span>
            <span className="mono" style={{fontWeight:700}}>{fmt(v)}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

window.SellingExpensesView = SellingExpensesView;
