/* global React, Icon, MOCK, fmtRp */
const { useState: useStateOp, useEffect: useEffectOp, useMemo: useMemoOp } = React;

const SO_STATUS_META = {
  draft:       { label:'Draft',         chip:'chip' },
  in_progress: { label:'Berlangsung',   chip:'chip-blue' },
  review:      { label:'Review',        chip:'chip-amber' },
  approved:    { label:'Disetujui',     chip:'chip-green' },
  cancelled:   { label:'Dibatalkan',    chip:'chip-rose' },
};

function StockOpnamePage() {
  const [tab, setTab] = useStateOp('all');
  const [createOpen, setCreateOpen] = useStateOp(false);
  const [list, setList] = useStateOp(window.MOCK?.STOCK_OPNAME || []);
  const [openDetail, setOpenDetail] = useStateOp(null);
  const [from, setFrom] = useStateOp('');
  const [to, setTo] = useStateOp('');

  useEffectOp(() => { setList(window.MOCK?.STOCK_OPNAME || []); }, []);

  const dateFiltered = list.filter(o =>
    window.inRange(o.scheduledAt || o.createdAt, from, to)
  );
  const counts = dateFiltered.reduce((a, o) => { a[o.status] = (a[o.status]||0)+1; return a; }, {});
  const filtered = tab === 'all' ? dateFiltered : dateFiltered.filter(o => o.status === tab);

  const refresh = async () => {
    const r = await window.Api.get('/api/stock-opname');
    const data = r.data || [];
    if (window.MOCK) window.MOCK.STOCK_OPNAME = data;
    setList(data);
  };

  const totalAdjustment = useMemoOp(
    () => list
      .filter(s => s.status === 'approved')
      .reduce((s, o) => s + Math.abs(Number(o.totalVarianceValue || 0)), 0),
    [list]
  );

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Stock Opname</h1>
          <p className="page-sub">Audit fisik stok gudang. Sistem akan snapshot stok saat ini, tim hitung manual, lalu sistem terapkan koreksi.</p>
        </div>
        <div className="page-actions">
          <button className="btn btn-secondary"><Icon.download/> Ekspor</button>
          <button className="btn btn-primary" onClick={() => setCreateOpen(true)}>
            <Icon.plus/> Mulai Opname Baru
          </button>
        </div>
      </div>

      <div className="grid-4" style={{ marginBottom:18 }}>
        <OpStat label="Sesi Aktif" value={(counts.draft || 0) + (counts.in_progress || 0)}/>
        <OpStat label="Menunggu Review" value={counts.review || 0} tone="amber"/>
        <OpStat label="Sesi Disetujui" value={counts.approved || 0} tone="green"/>
        <OpStat label="Total Adjustment" value={fmtRp(totalAdjustment)} tone="brand"/>
      </div>

      <div style={{ marginBottom:14, display:'flex', justifyContent:'flex-end' }}>
        <window.DateRangeFilter
          from={from} to={to}
          onChange={({ from, to }) => { setFrom(from); setTo(to); }}
        />
      </div>

      <div className="tabs">
        <Tab active={tab==='all'} onClick={() => setTab('all')} label="Semua" count={dateFiltered.length}/>
        {Object.entries(SO_STATUS_META).map(([k, m]) => (
          <Tab key={k} active={tab===k} onClick={() => setTab(k)} label={m.label} count={counts[k] || 0}/>
        ))}
      </div>

      <div className="card" style={{ overflow:'hidden' }}>
        <table className="table">
          <thead>
            <tr>
              <th>ID</th>
              <th>Gudang</th>
              <th>Tanggal</th>
              <th style={{ textAlign:'right' }}>SKU</th>
              <th style={{ textAlign:'right' }}>Selisih (unit)</th>
              <th style={{ textAlign:'right' }}>Selisih (Rp)</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 && (
              <tr><td colSpan="8" style={{ padding:'40px 24px', textAlign:'center', color:'var(--ink-500)' }}>
                Belum ada sesi stock opname. Klik <strong>Mulai Opname Baru</strong>.
              </td></tr>
            )}
            {filtered.map(so => {
              const meta = SO_STATUS_META[so.status];
              const variance = so.totalVariance || 0;
              const varValue = Number(so.totalVarianceValue || 0);
              return (
                <tr key={so.id} style={{ cursor:'pointer' }} onClick={() => setOpenDetail(so.id)}>
                  <td><span className="mono" style={{ fontWeight:700 }}>{so.id}</span></td>
                  <td>
                    <span style={{ display:'inline-flex', alignItems:'center', gap:6 }}>
                      <Icon.box/> {so.warehouse?.name || '—'}
                    </span>
                  </td>
                  <td style={{ color:'var(--ink-500)', fontSize:13 }}>
                    {so.scheduledAt || (so.createdAt ? new Date(so.createdAt).toLocaleDateString('id-ID') : '—')}
                  </td>
                  <td style={{ textAlign:'right', fontWeight:600 }}>{so.totalSkus || 0}</td>
                  <td style={{
                    textAlign:'right',
                    fontWeight:700,
                    color: variance < 0 ? 'var(--rose)' : variance > 0 ? 'var(--blue)' : 'var(--ink-400)'
                  }}>{variance > 0 ? `+${variance}` : variance || '—'}</td>
                  <td style={{
                    textAlign:'right',
                    fontWeight:700,
                    color: varValue < 0 ? 'var(--rose)' : varValue > 0 ? 'var(--blue)' : 'var(--ink-400)'
                  }}>{varValue ? fmtRp(varValue) : '—'}</td>
                  <td><span className={`chip ${meta.chip}`}><span className="chip-dot"/>{meta.label}</span></td>
                  <td style={{ textAlign:'right' }}>
                    <button className="btn btn-secondary btn-sm" onClick={(e) => { e.stopPropagation(); setOpenDetail(so.id); }}>
                      Buka
                    </button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {createOpen && (
        <CreateOpnameModal onClose={() => setCreateOpen(false)} onCreated={async (id) => {
          await refresh();
          setOpenDetail(id);
        }}/>
      )}
      {openDetail && (
        <OpnameDetailModal
          opnameId={openDetail}
          onClose={() => setOpenDetail(null)}
          onChange={refresh}
        />
      )}
    </div>
  );
}

function CreateOpnameModal({ onClose, onCreated }) {
  const [warehouseId, setWarehouseId] = useStateOp('wh_sub');
  const [scheduledAt, setScheduledAt] = useStateOp(new Date().toISOString().slice(0, 10));
  const [notes, setNotes] = useStateOp('');
  const [busy, setBusy] = useStateOp(false);
  const [error, setError] = useStateOp('');

  const submit = async (e) => {
    e.preventDefault();
    setError('');
    setBusy(true);
    try {
      const r = await window.Api.post('/api/stock-opname', {
        warehouseId,
        scheduledAt,
        notes: notes || undefined,
      });
      onCreated(r.data.id);
      onClose();
    } catch (err) {
      setError(err.message || 'Gagal');
      setBusy(false);
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" style={{ maxWidth: 540 }} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--ink-500)' }}>
              Stock Opname Baru
            </div>
            <h2 style={{ margin:'4px 0 0', fontSize:20, fontWeight:800 }}>Mulai Audit Stok Fisik</h2>
          </div>
          <button className="tb-icon-btn" onClick={onClose}><Icon.x/></button>
        </div>
        <form onSubmit={submit} style={{ padding:'20px 22px', display:'flex', flexDirection:'column', gap:14 }}>
          {error && (
            <div style={{ padding:'10px 14px', background:'#fee2e2', color:'#991b1b', borderRadius:8, fontSize:13 }}>
              {error}
            </div>
          )}

          <OpField label="Pilih gudang">
            <div style={{ display:'flex', gap:8 }}>
              {[
                { id:'wh_sub', label:'Surabaya' },
                { id:'wh_dpk', label:'Depok' },
                { id:'wh_med', label:'Medan' },
              ].map(w => (
                <button
                  key={w.id}
                  type="button"
                  className={`pick ${warehouseId===w.id?'on':''}`}
                  onClick={() => setWarehouseId(w.id)}
                >
                  <Icon.box/> {w.label}
                </button>
              ))}
            </div>
          </OpField>

          <OpField label="Tanggal opname">
            <input className="input" type="date" value={scheduledAt} onChange={e=>setScheduledAt(e.target.value)} required/>
          </OpField>

          <OpField label="Catatan (opsional)">
            <textarea className="input" rows="3" value={notes} onChange={e=>setNotes(e.target.value)} placeholder="Mis. Audit bulanan rutin, fokus rak A1-A3"/>
          </OpField>

          <div style={{ padding:'10px 12px', background:'var(--blue-bg)', borderRadius:8, fontSize:12.5, color:'var(--blue)', display:'flex', gap:8 }}>
            <Icon.zap/>
            <div>
              Sistem akan <strong>snapshot semua SKU</strong> di gudang yang dipilih saat tombol Mulai diklik. Tim gudang lalu hitung fisik per SKU, sistem otomatis menghitung selisih.
            </div>
          </div>

          <div className="modal-foot" style={{ margin:'4px -22px -20px' }}>
            <button type="button" className="btn btn-secondary" onClick={onClose} disabled={busy}>Batal</button>
            <button type="submit" className="btn btn-primary" disabled={busy}>
              {busy ? 'Membuat snapshot…' : 'Mulai Opname'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

function OpnameDetailModal({ opnameId, onClose, onChange }) {
  const [data, setData] = useStateOp(null);
  const [error, setError] = useStateOp('');
  const [busy, setBusy] = useStateOp(false);
  const [search, setSearch] = useStateOp('');
  const role = window.__user?.role || 'owner';

  const load = async () => {
    try {
      const r = await window.Api.get(`/api/stock-opname/${encodeURIComponent(opnameId)}`);
      setData(r.data);
    } catch (e) { setError(e.message); }
  };
  useEffectOp(() => { load(); /* eslint-disable-next-line */ }, [opnameId]);

  const recordCount = async (item, counted, note) => {
    setBusy(true);
    try {
      await window.Api.patch(`/api/stock-opname/${encodeURIComponent(opnameId)}/items`, {
        itemId: item.id,
        counted: Number(counted),
        note,
      });
      await load();
      onChange?.();
    } catch (e) {
      alert('Gagal: ' + e.message);
    } finally { setBusy(false); }
  };

  const finish = async () => {
    if (!confirm('Tutup sesi opname dan kirim ke review?')) return;
    setBusy(true);
    try {
      await window.Api.post(`/api/stock-opname/${encodeURIComponent(opnameId)}/finish`);
      await load();
      onChange?.();
    } catch (e) { alert('Gagal: ' + e.message); }
    finally { setBusy(false); }
  };

  const approve = async () => {
    if (!confirm('Setujui opname? Stok di sistem akan disesuaikan ke hasil hitung fisik.')) return;
    setBusy(true);
    try {
      await window.Api.post(`/api/stock-opname/${encodeURIComponent(opnameId)}/approve`);
      await load();
      onChange?.();
    } catch (e) { alert('Gagal: ' + e.message); }
    finally { setBusy(false); }
  };

  const cancel = async () => {
    if (!confirm('Batalkan sesi opname ini?')) return;
    setBusy(true);
    try {
      await window.Api.post(`/api/stock-opname/${encodeURIComponent(opnameId)}/cancel`);
      await load();
      onChange?.();
      onClose();
    } catch (e) { alert('Gagal: ' + e.message); }
    finally { setBusy(false); }
  };

  if (!data) {
    return (
      <div className="modal-backdrop" onClick={onClose}>
        <div className="modal" style={{ maxWidth: 720, padding:40, textAlign:'center' }} onClick={e => e.stopPropagation()}>
          {error || 'Memuat…'}
        </div>
      </div>
    );
  }

  const meta = SO_STATUS_META[data.status];
  const editable = ['draft', 'in_progress'].includes(data.status);
  const items = (data.items || []).filter(it =>
    !search ||
    it.sku.toLowerCase().includes(search.toLowerCase()) ||
    it.name.toLowerCase().includes(search.toLowerCase())
  );
  const countedCount = data.items.filter(it => it.counted != null).length;

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" style={{ maxWidth: 920, maxHeight:'90vh', display:'flex', flexDirection:'column' }} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--ink-500)' }}>
              Stock Opname · {data.warehouse?.name || '—'}
            </div>
            <h2 style={{ margin:'4px 0 0', fontSize:20, fontWeight:800 }}>{data.id}</h2>
          </div>
          <div style={{ display:'flex', gap:10, alignItems:'center' }}>
            <span className={`chip ${meta.chip}`}><span className="chip-dot"/>{meta.label}</span>
            <button className="tb-icon-btn" onClick={onClose}><Icon.x/></button>
          </div>
        </div>

        <div style={{ padding:'16px 22px', display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:12, borderBottom:'1px solid var(--border)' }}>
          <DetailKpi label="Total SKU" value={data.totalSkus || 0}/>
          <DetailKpi label="Sudah Dihitung" value={`${countedCount} / ${data.totalSkus || 0}`}/>
          <DetailKpi label="Selisih (unit)" value={(data.totalVariance ?? 0).toString()} tone={data.totalVariance < 0 ? 'rose' : (data.totalVariance > 0 ? 'blue' : null)}/>
          <DetailKpi label="Selisih (Rp)" value={fmtRp(Number(data.totalVarianceValue || 0))} tone={Number(data.totalVarianceValue) < 0 ? 'rose' : (Number(data.totalVarianceValue) > 0 ? 'blue' : null)}/>
        </div>

        <div style={{ padding:'12px 22px', borderBottom:'1px solid var(--border)' }}>
          <div className="input" style={{ maxWidth: 340 }}>
            <Icon.search/>
            <input placeholder="Cari SKU atau nama produk…" value={search} onChange={e => setSearch(e.target.value)}/>
          </div>
        </div>

        <div style={{ overflow:'auto', flex:1 }}>
          <table className="table">
            <thead style={{ position:'sticky', top:0, background:'var(--surface)' }}>
              <tr>
                <th>SKU</th>
                <th>Produk</th>
                <th style={{ textAlign:'right' }}>Sistem</th>
                <th style={{ textAlign:'right' }}>Hitung Fisik</th>
                <th style={{ textAlign:'right' }}>Selisih</th>
                <th style={{ textAlign:'right' }}>Nilai</th>
                <th>Catatan</th>
              </tr>
            </thead>
            <tbody>
              {items.map(it => (
                <OpnameItemRow
                  key={it.id}
                  item={it}
                  editable={editable && !busy}
                  onSave={recordCount}
                />
              ))}
            </tbody>
          </table>
        </div>

        <div className="modal-foot" style={{ flexShrink:0 }}>
          <div style={{ flex:1, fontSize:12.5, color:'var(--ink-500)' }}>
            {editable && '💡 Ketik jumlah hasil hitung di kolom "Hitung Fisik", lalu tekan Enter atau klik Simpan.'}
            {data.status === 'review' && '⏳ Sesi siap di-approve. Setelah disetujui, stok di sistem akan disesuaikan ke hasil hitung.'}
            {data.status === 'approved' && '✓ Sudah diterapkan ke stok sistem.'}
          </div>
          <div style={{ display:'flex', gap:8 }}>
            {editable && <button className="btn btn-secondary" onClick={cancel} disabled={busy}>Batalkan Sesi</button>}
            {data.status === 'in_progress' && countedCount > 0 && (
              <button className="btn btn-primary" onClick={finish} disabled={busy}>
                {busy ? 'Memproses…' : 'Tutup & Kirim ke Review'}
              </button>
            )}
            {data.status === 'review' && role === 'owner' && (
              <button className="btn btn-primary" onClick={approve} disabled={busy}>
                {busy ? 'Menyimpan…' : 'Setujui & Terapkan'}
              </button>
            )}
            <button className="btn btn-secondary" onClick={onClose}>Tutup</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function OpnameItemRow({ item, editable, onSave }) {
  const [val, setVal] = useStateOp(item.counted == null ? '' : String(item.counted));
  const [note, setNote] = useStateOp(item.note || '');
  const [editing, setEditing] = useStateOp(false);

  useEffectOp(() => {
    setVal(item.counted == null ? '' : String(item.counted));
    setNote(item.note || '');
  }, [item.counted, item.note]);

  const variance = item.counted == null ? null : item.variance;
  const varValue = Number(item.varianceValue || 0);

  const save = async () => {
    if (val === '') return;
    await onSave(item, val, note);
    setEditing(false);
  };

  return (
    <tr>
      <td><span className="mono" style={{ fontSize:12, fontWeight:600 }}>{item.sku}</span></td>
      <td>
        <div style={{ fontSize:13 }}>{item.name}</div>
      </td>
      <td style={{ textAlign:'right', fontWeight:600 }}>{item.expected}</td>
      <td style={{ textAlign:'right' }}>
        {editable ? (
          <input
            type="number"
            min="0"
            className="input"
            style={{ width:90, textAlign:'right' }}
            value={val}
            onChange={e => { setVal(e.target.value); setEditing(true); }}
            onKeyDown={e => e.key === 'Enter' && save()}
            onBlur={() => editing && save()}
            placeholder="—"
          />
        ) : (
          <span style={{ fontWeight:600 }}>{item.counted ?? '—'}</span>
        )}
      </td>
      <td style={{
        textAlign:'right', fontWeight:700,
        color: variance == null ? 'var(--ink-400)' : variance < 0 ? 'var(--rose)' : variance > 0 ? 'var(--blue)' : 'var(--green)'
      }}>
        {variance == null ? '—' : (variance > 0 ? `+${variance}` : variance)}
      </td>
      <td style={{
        textAlign:'right', fontSize:12,
        color: varValue < 0 ? 'var(--rose)' : varValue > 0 ? 'var(--blue)' : 'var(--ink-400)'
      }}>
        {varValue ? fmtRp(varValue) : '—'}
      </td>
      <td>
        {editable ? (
          <input
            className="input"
            placeholder="Catatan…"
            value={note}
            onChange={e => { setNote(e.target.value); setEditing(true); }}
            onBlur={() => editing && save()}
            style={{ fontSize:12 }}
          />
        ) : (
          <span style={{ fontSize:12, color:'var(--ink-500)' }}>{item.note || ''}</span>
        )}
      </td>
    </tr>
  );
}

function Tab({ active, onClick, label, count }) {
  return (
    <button className={`tab ${active?'active':''}`} onClick={onClick}>
      {label}{count != null && <span className="count">{count}</span>}
    </button>
  );
}

function OpStat({ label, value, tone }) {
  const colors = { brand:'var(--brand-500)', green:'var(--green)', amber:'var(--amber)', rose:'var(--rose)' };
  return (
    <div className="metric">
      <div className="metric-label">{label}</div>
      <div className="metric-value" style={{ color: tone ? colors[tone] : undefined }}>{value}</div>
    </div>
  );
}

function DetailKpi({ label, value, tone }) {
  const colors = { brand:'var(--brand-500)', green:'var(--green)', amber:'var(--amber)', rose:'var(--rose)', blue:'var(--blue)' };
  return (
    <div>
      <div style={{ fontSize:11, fontWeight:600, color:'var(--ink-500)', textTransform:'uppercase', letterSpacing:'0.05em' }}>{label}</div>
      <div style={{ fontSize:20, fontWeight:800, marginTop:4, color: tone ? colors[tone] : undefined }}>{value}</div>
    </div>
  );
}

function OpField({ label, children }) {
  return (
    <label style={{ display:'flex', flexDirection:'column', gap:6 }}>
      <span style={{ fontSize:12, fontWeight:600, color:'var(--ink-700)' }}>{label}</span>
      {children}
    </label>
  );
}

window.StockOpnamePage = StockOpnamePage;
