/* ============================================================
   reagents.jsx — reagent & QC-material lot register, linked to
   instruments. Lot no / expiry / QC pass-fail (ISO 15189 §6.6).
   ============================================================ */
const RG_MFR = ['Roche', 'Siemens', 'Bio-Rad', 'Abbott', 'Sysmex', 'Thermo Fisher', 'Beckman Coulter'];
const RG_NAMES = {
  AUT: ['ชุดน้ำยาตรวจวิเคราะห์', 'สารควบคุมคุณภาพระดับปกติ (QC Normal)', 'สารควบคุมคุณภาพระดับผิดปกติ (QC Abnormal)', 'น้ำยาสอบเทียบ (Calibrator)'],
  PCR: ['Master Mix สำหรับ PCR', 'Positive Control', 'Negative Control', 'ชุดสกัดสารพันธุกรรม'],
  ACE: ['น้ำยาแยกส่วนประกอบโลหิต', 'สารกันเลือดแข็ง (Anticoagulant)'],
  MBB: ['น้ำยาวัดบิลิรูบิน', 'QC บิลิรูบิน'],
  ESR: ['น้ำยา ESR', 'QC ESR'],
  TRB: ['สารมาตรฐานความขุ่น (McFarland)'],
  DEF: ['ชุดน้ำยาตรวจวิเคราะห์', 'สารควบคุมคุณภาพ (QC)', 'น้ำยาสอบเทียบ (Calibrator)'],
};
const RG_STORAGE = ['2–8°C', '2–8°C', '-20°C', 'อุณหภูมิห้อง (15–25°C)'];

function rgHash(s) { let h = 2166136261; for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 16777619); } return Math.abs(h); }
function rgAddDays(base, n) { const d = new Date(base); d.setDate(d.getDate() + n); return d.toISOString().slice(0, 10); }

/* seed demo lots for analyzer-type instruments */
function seedReagents(instruments) {
  const want = ['AUT', 'PCR', 'ACE', 'MBB', 'ESR', 'TRB'];
  const out = [];
  const todayIso = TODAY.toISOString().slice(0, 10);
  instruments.forEach(inst => {
    const ab = (inst.code || '').split('-')[2] || '';
    if (!want.includes(ab)) return;
    const h = rgHash(inst.code);
    const names = RG_NAMES[ab] || RG_NAMES.DEF;
    const nLots = 1 + (h % 2); // 1–2 lots each
    for (let k = 0; k < nLots; k++) {
      const hk = rgHash(inst.code + 'L' + k);
      const name = names[hk % names.length];
      const expOffset = (hk % 200) - 40;       // -40..160 days from today
      const expiry = rgAddDays(todayIso, expOffset);
      const received = rgAddDays(expiry, -(180 + hk % 180));
      const opened = rgAddDays(received, 5 + hk % 30);
      const qcRoll = hk % 10;
      const qcStatus = qcRoll === 0 ? 'fail' : qcRoll <= 1 ? 'warn' : qcRoll <= 2 ? 'pending' : 'pass';
      out.push({
        id: 'seed-' + inst.code + '-' + k,
        code: inst.code,
        name,
        lotNo: `${String.fromCharCode(65 + (hk % 26))}${(hk % 9000 + 1000)}`,
        manufacturer: RG_MFR[hk % RG_MFR.length],
        received, opened, expiry,
        storage: RG_STORAGE[hk % RG_STORAGE.length],
        qcStatus,
        qcDate: rgAddDays(todayIso, -(hk % 14)),
        notes: '',
      });
    }
  });
  return out;
}

/* reagent status from expiry + qc */
function reagentStatus(lot) {
  const dd = daysUntil(lot.expiry);
  if (dd != null && dd < 0) return { key: 'expired', label: 'หมดอายุ', tone: 'danger', days: dd };
  if (dd != null && dd <= 30) return { key: 'near', label: 'ใกล้หมดอายุ', tone: 'warn', days: dd };
  return { key: 'valid', label: 'ใช้งานได้', tone: 'ok', days: dd };
}
const QC_META = {
  pass: { label: 'ผ่าน QC', tone: 'ok' },
  warn: { label: 'QC เฝ้าระวัง', tone: 'warn' },
  fail: { label: 'QC ไม่ผ่าน', tone: 'danger' },
  pending: { label: 'รอผล QC', tone: 'none' },
};

/* ---- per-instrument reagent card (used on detail page) ---- */
function ReagentLotsCard({ code, go }) {
  const [, bump] = useState(0);
  useEffect(() => Reagents.subscribe(() => bump(x => x + 1)), []);
  const lots = Reagents.forCode(code);
  if (!lots.length) return null;
  return (
    <SectionCard icon={I.flask} title="น้ำยา & สารควบคุมคุณภาพ" sub={`${lots.length} ล็อตที่ผูกกับเครื่องนี้`}
      right={<span className="chip" onClick={() => go('reagents', { code })}>จัดการน้ำยา <I.chevR size={14} /></span>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {lots.map(lot => {
          const st = reagentStatus(lot), qc = QC_META[lot.qcStatus];
          return (
            <div key={lot.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 12px', background: 'var(--surface-2)', borderRadius: 10 }}>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{lot.name}</div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>Lot <span className="code">{lot.lotNo}</span> · {lot.manufacturer} · หมดอายุ {fmtDate(lot.expiry)}</div>
              </div>
              <span className={`pill ${qc.tone}`} style={{ fontSize: 11 }}><span className="dot"></span>{qc.label}</span>
              <span className={`pill ${st.tone}`} style={{ fontSize: 11 }}><span className="dot"></span>{st.label}</span>
            </div>
          );
        })}
      </div>
    </SectionCard>
  );
}

/* ---- lot add/edit drawer ---- */
function ReagentDrawer({ lot, instruments, onClose, onSave }) {
  const blank = { id: '', code: instruments[0] ? instruments[0].code : '', name: '', lotNo: '', manufacturer: '', received: '', opened: '', expiry: '', storage: '2–8°C', qcStatus: 'pass', qcDate: TODAY.toISOString().slice(0,10), notes: '' };
  const [f, setF] = useState(lot ? { ...blank, ...lot } : blank);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = () => {
    if (!f.name.trim() || !f.lotNo.trim()) { alert('กรุณากรอกชื่อน้ำยาและหมายเลข Lot'); return; }
    onSave({ ...f, id: f.id || ('lot-' + Date.now()) }, !f.id);
    onClose();
  };
  return (
    <>
      <div className="scrim" onClick={onClose} />
      <div className="drawer">
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '18px 22px', borderBottom: '1px solid var(--line)' }}>
          <span style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--accent-soft)', color: 'var(--accent-strong)', display: 'grid', placeItems: 'center' }}><I.flask size={18} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontWeight: 600, fontSize: 16 }}>{lot ? 'แก้ไขล็อตน้ำยา' : 'เพิ่มล็อตน้ำยา / QC'}</div>
            <div className="page-sub">ทะเบียนน้ำยาและสารควบคุมคุณภาพ</div>
          </div>
          <button className="btn btn-icon btn-ghost" onClick={onClose}><I.close size={18} /></button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '16px 22px 22px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          <div style={{ gridColumn: '1 / -1' }}>
            <label className="field-label">เครื่องมือที่ผูก</label>
            <select className="input" value={f.code} onChange={e => set('code', e.target.value)}>
              {instruments.map(i => <option key={i.code} value={i.code}>{i.code} · {i.type}</option>)}
            </select>
          </div>
          <div style={{ gridColumn: '1 / -1' }}><label className="field-label">ชื่อน้ำยา / สารควบคุม</label><input className="input" value={f.name} onChange={e => set('name', e.target.value)} placeholder="เช่น สารควบคุมคุณภาพระดับปกติ" /></div>
          <div><label className="field-label">หมายเลข Lot</label><input className="input" value={f.lotNo} onChange={e => set('lotNo', e.target.value)} /></div>
          <div><label className="field-label">ผู้ผลิต</label><input className="input" value={f.manufacturer} onChange={e => set('manufacturer', e.target.value)} /></div>
          <div><label className="field-label">วันรับเข้า</label><input type="date" className="input" value={f.received} onChange={e => set('received', e.target.value)} /></div>
          <div><label className="field-label">วันเปิดใช้</label><input type="date" className="input" value={f.opened} onChange={e => set('opened', e.target.value)} /></div>
          <div><label className="field-label">วันหมดอายุ</label><input type="date" className="input" value={f.expiry} onChange={e => set('expiry', e.target.value)} /></div>
          <div>
            <label className="field-label">การจัดเก็บ</label>
            <select className="input" value={f.storage} onChange={e => set('storage', e.target.value)}>
              {['2–8°C', '-20°C', '-70°C', 'อุณหภูมิห้อง (15–25°C)'].map(o => <option key={o} value={o}>{o}</option>)}
            </select>
          </div>
          <div style={{ gridColumn: '1 / -1' }}>
            <label className="field-label">ผลการควบคุมคุณภาพ (QC)</label>
            <div className="seg" style={{ display: 'flex' }}>
              {[['pass', 'ผ่าน'], ['warn', 'เฝ้าระวัง'], ['fail', 'ไม่ผ่าน'], ['pending', 'รอผล']].map(([k, l]) =>
                <button key={k} className={f.qcStatus === k ? 'on' : ''} style={{ flex: 1 }} onClick={() => set('qcStatus', k)}>{l}</button>)}
            </div>
          </div>
          <div><label className="field-label">วันตรวจ QC ล่าสุด</label><input type="date" className="input" value={f.qcDate} onChange={e => set('qcDate', e.target.value)} /></div>
          <div style={{ gridColumn: '1 / -1' }}><label className="field-label">หมายเหตุ</label><input className="input" value={f.notes} onChange={e => set('notes', e.target.value)} /></div>
        </div>
        <div style={{ display: 'flex', gap: 10, padding: '14px 22px', borderTop: '1px solid var(--line)' }}>
          <button className="btn" style={{ flex: 1 }} onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary" style={{ flex: 1 }} onClick={save}><I.check size={17} /> บันทึก</button>
        </div>
      </div>
    </>
  );
}

/* ---- main reagent & QC view ---- */
function ReagentsView({ instruments, go, initial, admin }) {
  const [, bump] = useState(0);
  useEffect(() => Reagents.subscribe(() => bump(x => x + 1)), []);
  const [q, setQ] = useState('');
  const [stat, setStat] = useState('all');
  const [qc, setQc] = useState('all');
  const [editing, setEditing] = useState(null); // lot object or {} for new
  const codeName = useCallback((code) => { const i = instruments.find(x => x.code === code); return i ? i.type : code; }, [instruments]);

  const lots = Reagents.all();
  const counts = useMemo(() => {
    const c = { all: lots.length, valid: 0, near: 0, expired: 0, qcfail: 0 };
    lots.forEach(l => { const s = reagentStatus(l); c[s.key]++; if (l.qcStatus === 'fail') c.qcfail++; });
    return c;
  }, [lots]);

  const filtered = useMemo(() => {
    const ql = q.trim().toLowerCase();
    return lots.filter(l => {
      if (stat !== 'all' && reagentStatus(l).key !== stat) return false;
      if (qc !== 'all' && l.qcStatus !== qc) return false;
      if (initial && initial.code && l.code !== initial.code) return false;
      if (ql) { const hay = `${l.name} ${l.lotNo} ${l.manufacturer} ${l.code} ${codeName(l.code)}`.toLowerCase(); if (!hay.includes(ql)) return false; }
      return true;
    }).sort((a, b) => (reagentStatus(a).days ?? 9999) - (reagentStatus(b).days ?? 9999));
  }, [lots, q, stat, qc, initial, codeName]);

  const saveLot = (lot, isNew) => {
    Reagents.upsert(lot);
    window.Audit && window.Audit.add({ action: isNew ? 'reagent_add' : 'reagent_edit', code: lot.code, target: `${lot.name} (Lot ${lot.lotNo})`, detail: isNew ? 'เพิ่มล็อตน้ำยา/QC' : 'แก้ไขล็อตน้ำยา/QC' });
  };
  const delLot = (lot) => {
    if (!window.confirm(`ลบล็อต ${lot.name} (Lot ${lot.lotNo})?`)) return;
    Reagents.remove(lot.id);
    window.Audit && window.Audit.add({ action: 'reagent_delete', code: lot.code, target: `${lot.name} (Lot ${lot.lotNo})`, detail: 'ลบล็อตน้ำยา/QC' });
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {initial && initial.code && (
        <button className="btn btn-ghost btn-sm" style={{ alignSelf: 'flex-start' }} onClick={() => go('detail', { code: initial.code })}><I.arrowL size={16} /> กลับไปบัตรเครื่องมือ {initial.code}</button>
      )}
      {/* summary tiles */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 14 }}>
        {[['ทั้งหมด', counts.all, 'accent', I.flask], ['ใกล้หมดอายุ', counts.near, 'warn', I.clock], ['หมดอายุ', counts.expired, 'danger', I.warning], ['QC ไม่ผ่าน', counts.qcfail, 'danger', I.shield]].map(([l, v, tone, Ico]) => (
          <div key={l} className="card card-pad" style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <span style={{ width: 38, height: 38, borderRadius: 10, flex: 'none', display: 'grid', placeItems: 'center', background: tone === 'accent' ? 'var(--accent-soft)' : `var(--${tone}-soft)`, color: tone === 'accent' ? 'var(--accent-strong)' : `var(--${tone})` }}><Ico size={19} /></span>
            <div><div className="figure" style={{ fontSize: 26 }}>{v}</div><div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{l}</div></div>
          </div>
        ))}
      </div>

      {/* toolbar */}
      <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
        <div className="search" style={{ flex: '1 1 260px', maxWidth: 420 }}>
          <I.search className="ico" size={17} />
          <input placeholder="ค้นหา ชื่อน้ำยา / Lot / ผู้ผลิต / เครื่อง…" value={q} onChange={e => setQ(e.target.value)} />
        </div>
        <div style={{ flex: 1 }} />
        <button className="btn btn-primary" onClick={() => setEditing({})}><I.plus size={17} /> เพิ่มล็อตน้ำยา</button>
      </div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
        {[['all', 'ทั้งหมด'], ['valid', 'ใช้งานได้'], ['near', 'ใกล้หมดอายุ'], ['expired', 'หมดอายุ']].map(([k, l]) =>
          <button key={k} className={`chip ${stat === k ? 'on' : ''}`} onClick={() => setStat(k)}>{l}{k !== 'all' && <span className="tnum" style={{ opacity: .6, marginLeft: 3 }}>{counts[k]}</span>}</button>)}
        <span style={{ width: 1, height: 20, background: 'var(--line)', margin: '0 4px' }} />
        {[['all', 'QC ทั้งหมด'], ['pass', 'ผ่าน'], ['fail', 'ไม่ผ่าน'], ['pending', 'รอผล']].map(([k, l]) =>
          <button key={k} className={`chip ${qc === k ? 'on' : ''}`} onClick={() => setQc(k)}>{l}</button>)}
      </div>

      {/* table */}
      {filtered.length === 0 ? (
        <div className="card"><EmptyState icon={I.flask} title="ยังไม่มีล็อตน้ำยา" sub="กดเพิ่มล็อตน้ำยาเพื่อเริ่มทะเบียน" /></div>
      ) : (
        <div className="card tbl-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th>น้ำยา / สารควบคุม</th>
                <th style={{ width: 110 }}>Lot No.</th>
                <th>เครื่องที่ผูก</th>
                <th style={{ width: 120 }}>หมดอายุ</th>
                <th style={{ width: 130 }}>QC</th>
                <th style={{ width: 130 }}>สถานะ</th>
                <th style={{ width: 70 }}></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(lot => {
                const st = reagentStatus(lot), qcm = QC_META[lot.qcStatus];
                return (
                  <tr key={lot.id} onClick={() => setEditing(lot)}>
                    <td>
                      <div style={{ fontWeight: 600, fontSize: 13.5 }}>{lot.name}</div>
                      <div style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{lot.manufacturer} · เก็บ {lot.storage}</div>
                    </td>
                    <td><span className="code" style={{ fontWeight: 600 }}>{lot.lotNo}</span></td>
                    <td>
                      <div style={{ fontSize: 12.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 180 }}>{codeName(lot.code)}</div>
                      <span className="code" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{lot.code}</span>
                    </td>
                    <td className="tnum"><span style={{ fontSize: 13 }}>{fmtDate(lot.expiry)}</span>{st.days != null && st.key !== 'valid' && <div style={{ fontSize: 10.5, color: st.tone === 'danger' ? 'var(--danger)' : 'var(--warn)' }}>{st.days < 0 ? `เกิน ${Math.abs(st.days)} ว.` : `อีก ${st.days} ว.`}</div>}</td>
                    <td><span className={`pill ${qcm.tone}`}><span className="dot"></span>{qcm.label}</span></td>
                    <td><span className={`pill ${st.tone}`}><span className="dot"></span>{st.label}</span></td>
                    <td onClick={e => e.stopPropagation()}>
                      <button className="btn-icon btn-ghost" title="ลบ" style={{ color: 'var(--ink-4)' }} onClick={() => delLot(lot)}><I.close size={15} /></button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {editing !== null && <ReagentDrawer lot={editing.id ? editing : null} instruments={instruments} onClose={() => setEditing(null)} onSave={saveLot} />}
    </div>
  );
}

Object.assign(window, { seedReagents, reagentStatus, QC_META, ReagentLotsCard, ReagentsView });
