/* ============================================================
   calreview.jsx — "ทบทวนผลสอบเทียบ & รับรองความเหมาะสมการใช้งาน"
   (Calibration result review & fitness-for-use record).

   ISO 15189:2022 §6.4 / §6.5: when a calibration certificate comes
   back the lab must REVIEW the results against pre-set acceptance
   criteria (MPE), decide pass/fail, conclude fitness for use, and
   have it signed off through the responsible chain. Filing the cert
   alone is a non-conformity. This module captures that review per
   instrument per calibration cycle, persists it (CalReviews tab),
   and prints a formal A4 form for the auditor.
   ============================================================ */

// fixed sign-off chain (titles fixed; names are configurable defaults, editable per record)
const CAL_SIGN_ROLES = [
  { key: 'instMgr',   title: 'ผู้จัดการเครื่องมือทางห้องปฏิบัติการ', verb: 'ทบทวน' },
  { key: 'qmr',       title: 'ผู้จัดการคุณภาพ',                      verb: 'สอบทาน' },
  { key: 'groupHead', title: 'หัวหน้ากลุ่มงาน',                      verb: 'อนุมัติ' },
];

const CAL_CONCL = [
  { key: 'fit',         label: 'เหมาะสมกับการใช้งาน',        en: 'Fit for use',  tone: 'ok' },
  { key: 'conditional', label: 'ใช้งานได้โดยมีเงื่อนไข',     en: 'Conditional',  tone: 'warn' },
  { key: 'unfit',       label: 'ไม่เหมาะสมกับการใช้งาน',     en: 'Unfit',        tone: 'danger' },
];
function calConcl(key) { return CAL_CONCL.find(c => c.key === key) || CAL_CONCL[0]; }
function calToneVars(tone) {
  return tone === 'danger' ? ['var(--danger)', 'var(--danger-soft)']
    : tone === 'warn' ? ['var(--warn)', 'var(--warn-soft)']
    : ['var(--ok)', 'var(--ok-soft)'];
}

// parse configured default signer names from Config (calSigners JSON)
function calSignersFrom(config) {
  let s = {};
  try { s = JSON.parse((config && config.calSigners) || '{}') || {}; } catch (e) { s = {}; }
  return { instMgr: s.instMgr || '', qmr: s.qmr || '', groupHead: s.groupHead || '' };
}

/* ---------- review form modal (create / edit) ---------- */
function CalReviewModal({ inst, review, currentUser, onClose, onSaved }) {
  const editing = !!review;
  const [calDate, setCalDate]   = useState((review && review.calDate) || inst.cal || window.TODAY_ISO);
  const [nextDue, setNextDue]   = useState((review && review.nextDue) || inst.exp || '');
  const [certNo, setCertNo]     = useState((review && review.certNo) || inst.certNo || '');
  const [provider, setProvider] = useState((review && review.provider) || inst.provider || '');
  const [purpose, setPurpose]   = useState((review && review.purpose) || '');
  const [params, setParams]     = useState(
    (review && review.params && review.params.length)
      ? review.params.map(p => ({ ...p }))
      : [{ name: '', nominal: '', measured: '', mpe: inst.mpe || '', pass: true }]
  );
  const [conclusion, setConclusion] = useState((review && review.conclusion) || 'fit');
  const [recommendation, setRecommendation] = useState((review && review.recommendation) || '');

  const setParam = (idx, key, val) => setParams(ps => ps.map((p, i) => i === idx ? { ...p, [key]: val } : p));
  const addParam = () => setParams(ps => [...ps, { name: '', nominal: '', measured: '', mpe: '', pass: true }]);
  const rmParam  = (idx) => setParams(ps => ps.length > 1 ? ps.filter((_, i) => i !== idx) : ps);

  const save = () => {
    const id = editing ? review.id
      : 'CR-' + inst.code + '-' + String(calDate || window.TODAY_ISO).replace(/-/g, '') + '-' + Date.now().toString(36).slice(-4).toUpperCase();
    const cleanParams = params
      .filter(p => (p.name || p.measured || p.mpe || p.nominal))
      .map(p => ({ name: (p.name || '').trim(), nominal: (p.nominal || '').trim(), measured: (p.measured || '').trim(), mpe: (p.mpe || '').trim(), pass: !!p.pass }));
    const rev = {
      id, code: inst.code, instType: inst.type || '', dept: inst.dept || '',
      calDate, nextDue, certNo: certNo.trim(), provider: provider.trim(),
      purpose: purpose.trim(), params: cleanParams,
      conclusion, recommendation: recommendation.trim(),
      signs: editing ? (review.signs || {}) : { instMgr: null, qmr: null, groupHead: null },
      createdBy: editing ? review.createdBy : (currentUser || ''),
      createdAt: editing ? review.createdAt : new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    window.CalReviews.upsert(rev);
    if (window.Audit) window.Audit.add({ action: editing ? 'calreview_edit' : 'calreview_add', code: inst.code, target: inst.type || inst.code, detail: 'ทบทวนผลสอบเทียบ · ' + calConcl(conclusion).label });
    onSaved && onSaved(rev);
  };

  const cellInput = { ...cjInput, padding: '7px 9px', fontSize: 12.5 };

  const footer = (
    <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end', flexWrap: 'wrap' }}>
      <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
      <button className="btn btn-primary" onClick={save}><I.check size={15} /> {editing ? 'บันทึกการแก้ไข' : 'บันทึกการทบทวน'}</button>
    </div>
  );

  return (
    <CJModal wide title={editing ? 'แก้ไขบันทึกทบทวนผลสอบเทียบ' : 'ทบทวนผลสอบเทียบ & รับรองความเหมาะสม'} sub={inst.code + ' · ' + inst.type} icon={I.shield} onClose={onClose} footer={footer}>
      {/* cycle context */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0 16px' }}>
        <CJField label="วันที่สอบเทียบ (ตามใบรับรอง)"><input type="date" value={calDate} onChange={e => setCalDate(e.target.value)} style={cjInput} /></CJField>
        <CJField label="ครบกำหนดสอบเทียบครั้งถัดไป"><input type="date" value={nextDue} onChange={e => setNextDue(e.target.value)} style={cjInput} /></CJField>
        <CJField label="เลขที่ใบรับรอง (Certificate No.)"><input value={certNo} onChange={e => setCertNo(e.target.value)} placeholder="เช่น NC_00/25/0898" style={cjInput} /></CJField>
        <CJField label="หน่วยงานผู้สอบเทียบ"><input value={provider} onChange={e => setProvider(e.target.value)} placeholder="เช่น Dr.calibration" style={cjInput} /></CJField>
      </div>

      {/* 1. purpose & cal point */}
      <CJField label="1. วัตถุประสงค์การใช้งาน & จุด/เงื่อนไขที่สอบเทียบ" hint="เครื่องนี้ใช้ทำอะไร + จุดที่สอบเทียบ เช่น “ปั่นเพื่อให้ได้ตะกอนปัสสาวะ · จุดสอบเทียบ 1800 rpm นาน 5 นาที”">
        <textarea value={purpose} onChange={e => setPurpose(e.target.value)} rows={3} placeholder={inst.calPoint ? ('จุดสอบเทียบในระบบ: ' + inst.calPoint) : 'ระบุวัตถุประสงค์และจุดสอบเทียบ'} style={{ ...cjInput, resize: 'vertical' }} />
      </CJField>

      {/* 2. parameter result table */}
      <CJField label="2. ผลการสอบเทียบเทียบกับเกณฑ์ยอมรับ (MPE)" hint="กรอกแต่ละพารามิเตอร์/จุดที่วัด พร้อมเกณฑ์ MPE และตัดสินผ่าน/ไม่ผ่าน">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {params.map((p, idx) => {
            const [pcol, psoft] = calToneVars(p.pass ? 'ok' : 'danger');
            return (
              <div key={idx} style={{ border: '1px solid var(--line)', borderRadius: 10, padding: 10, background: 'var(--surface-2)' }}>
                <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 8 }}>
                  <input value={p.name} onChange={e => setParam(idx, 'name', e.target.value)} placeholder="พารามิเตอร์ / จุด (เช่น รอบหมุน)" style={cellInput} />
                  <input value={p.nominal} onChange={e => setParam(idx, 'nominal', e.target.value)} placeholder="ค่ากำหนด (เช่น 1800 rpm)" style={cellInput} />
                  <input value={p.measured} onChange={e => setParam(idx, 'measured', e.target.value)} placeholder="ผลที่วัดได้ (เช่น 1798 rpm)" style={cellInput} />
                  <input value={p.mpe} onChange={e => setParam(idx, 'mpe', e.target.value)} placeholder="เกณฑ์ MPE (เช่น ±5%)" style={cellInput} />
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
                  <button type="button" onClick={() => setParam(idx, 'pass', !p.pass)}
                    style={{ padding: '5px 12px', borderRadius: 8, fontSize: 12.5, fontWeight: 700, cursor: 'pointer', border: '1px solid ' + pcol, background: psoft, color: pcol }}>
                    {p.pass ? '✓ ผ่านเกณฑ์' : '✕ ไม่ผ่านเกณฑ์'}
                  </button>
                  <div style={{ flex: 1 }} />
                  {params.length > 1 && <button type="button" className="btn btn-icon btn-ghost" title="ลบแถวนี้" onClick={() => rmParam(idx)} style={{ color: 'var(--danger)' }}><I.trash size={14} /></button>}
                </div>
              </div>
            );
          })}
          <button type="button" className="btn btn-sm" onClick={addParam} style={{ alignSelf: 'flex-start' }}><I.plus size={14} /> เพิ่มพารามิเตอร์</button>
        </div>
      </CJField>

      {/* 3. fitness-for-use conclusion */}
      <CJField label="3. สรุปความเหมาะสมในการใช้งาน">
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          {CAL_CONCL.map(c => {
            const on = conclusion === c.key;
            const [col, soft] = calToneVars(c.tone);
            return (
              <button key={c.key} type="button" onClick={() => setConclusion(c.key)}
                style={{ padding: '8px 14px', borderRadius: 9, fontSize: 13, fontWeight: 600, cursor: 'pointer', border: '1px solid ' + (on ? col : 'var(--line)'), background: on ? soft : 'var(--surface)', color: on ? col : 'var(--ink-2)' }}>
                {c.label}
              </button>
            );
          })}
        </div>
      </CJField>
      <CJField label="ข้อเสนอแนะ / เงื่อนไขการใช้งาน (ถ้ามี)">
        <textarea value={recommendation} onChange={e => setRecommendation(e.target.value)} rows={2} placeholder="เช่น ใช้งานได้ปกติ / ให้ติดตามค่าทุก 6 เดือน / ส่งซ่อมก่อนใช้งาน" style={{ ...cjInput, resize: 'vertical' }} />
      </CJField>

      <div style={{ background: 'var(--accent-soft)', borderRadius: 10, padding: '10px 13px', fontSize: 12.5, color: 'var(--ink-2)', display: 'flex', gap: 8, alignItems: 'flex-start' }}>
        <I.shield size={15} style={{ flex: 'none', marginTop: 1, color: 'var(--accent-strong)' }} />
        <span>หลังบันทึก ให้ลงนามรับทราบตามลำดับ (ผู้จัดการเครื่องมือ → ผู้จัดการคุณภาพ → หัวหน้ากลุ่มงาน) ที่การ์ดบันทึก แล้วสั่งพิมพ์ฟอร์มยื่น auditor ได้</span>
      </div>
    </CJModal>
  );
}
window.CalReviewModal = CalReviewModal;

/* ---------- sign-off capture modal ---------- */
function CalSignModal({ role, defaultName, currentUser, onClose, onSign }) {
  const [name, setName] = useState(defaultName || currentUser || '');
  const [date, setDate] = useState(window.TODAY_ISO);
  const footer = (
    <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
      <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
      <button className="btn btn-primary" disabled={!name.trim()} onClick={() => onSign({ name: name.trim(), date, by: currentUser || '' })}><I.check size={15} /> ลงนาม{role.verb}</button>
    </div>
  );
  return (
    <CJModal title={'ลงนาม' + role.verb} sub={role.title} icon={I.check} onClose={onClose} footer={footer}>
      <CJField label="ชื่อผู้ลงนาม"><input value={name} onChange={e => setName(e.target.value)} placeholder="ชื่อ-นามสกุล" style={cjInput} autoFocus /></CJField>
      <CJField label="วันที่ลงนาม"><input type="date" value={date} onChange={e => setDate(e.target.value)} style={cjInput} /></CJField>
      <div style={{ fontSize: 12, color: 'var(--ink-3)', lineHeight: 1.5 }}>การลงนามเป็นการรับทราบผลการทบทวนและรับรองความเหมาะสมตามลำดับชั้น · บันทึกผู้ลงนามในระบบ (Audit)</div>
    </CJModal>
  );
}

/* ---------- admin: default signer names ---------- */
function CalSignersModal({ signers, onClose, onSave }) {
  const [s, setS] = useState({ ...signers });
  const [busy, setBusy] = useState(false);
  const save = async () => { setBusy(true); await onSave(s); setBusy(false); onClose(); };
  const footer = (
    <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
      <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
      <button className="btn btn-primary" disabled={busy} onClick={save}><I.check size={15} /> {busy ? 'กำลังบันทึก…' : 'บันทึก'}</button>
    </div>
  );
  return (
    <CJModal title="ตั้งชื่อผู้ลงนามเริ่มต้น" sub="ใช้เติมอัตโนมัติเมื่อลงนาม (แก้ไขรายใบได้)" icon={I.user} onClose={onClose} footer={footer}>
      {CAL_SIGN_ROLES.map(role => (
        <CJField key={role.key} label={role.title}>
          <input value={s[role.key] || ''} onChange={e => setS(v => ({ ...v, [role.key]: e.target.value }))} placeholder="ชื่อ-นามสกุล" style={cjInput} />
        </CJField>
      ))}
    </CJModal>
  );
}

/* ---------- the Detail-page section ---------- */
function CalReviewSection({ inst, admin, readOnly, currentUser, config, onSaveSigners }) {
  const [, bump] = useState(0);
  useEffect(() => window.CalReviews && window.CalReviews.subscribe(() => bump(x => x + 1)), []);
  const [editTarget, setEditTarget] = useState(null);   // 'new' | review object | null
  const [signTarget, setSignTarget] = useState(null);   // { review, role } | null
  const [signersOpen, setSignersOpen] = useState(false);

  const signers = calSignersFrom(config);
  const list = (window.CalReviews ? window.CalReviews.forCode(inst.code) : [])
    .slice().sort((a, b) => String(b.calDate || '').localeCompare(String(a.calDate || '')));

  const doSign = (review, role, sig) => {
    const next = { ...review, signs: { ...(review.signs || {}), [role.key]: sig }, updatedAt: new Date().toISOString() };
    window.CalReviews.upsert(next);
    if (window.Audit) window.Audit.add({ action: 'calreview_sign', code: inst.code, target: inst.type || inst.code, detail: 'ลงนาม' + role.verb + ' (' + role.title + ') · ' + sig.name });
    setSignTarget(null);
  };
  const del = (review) => {
    if (!window.confirm('ลบบันทึกทบทวนผลสอบเทียบนี้?')) return;
    window.CalReviews.remove(review.id);
  };

  return (
    <SectionCard icon={I.shield} title="ทบทวนผลสอบเทียบ & รับรองการใช้งาน" sub="Calibration result review (ISO 15189 §6.4/6.5)"
      right={
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
          {admin && <button className="btn btn-sm" title="ตั้งชื่อผู้ลงนามเริ่มต้น" onClick={() => setSignersOpen(true)}><I.user size={14} /> ผู้ลงนาม</button>}
          {!readOnly && <button className="btn btn-sm btn-primary" onClick={() => setEditTarget('new')}><I.plus size={14} /> สร้างบันทึกทบทวน</button>}
        </div>
      }>

      {editTarget && (
        <CalReviewModal inst={inst} review={editTarget === 'new' ? null : editTarget} currentUser={currentUser}
          onClose={() => setEditTarget(null)} onSaved={() => setEditTarget(null)} />
      )}
      {signTarget && (
        <CalSignModal role={signTarget.role} defaultName={signers[signTarget.role.key]} currentUser={currentUser}
          onClose={() => setSignTarget(null)} onSign={(sig) => doSign(signTarget.review, signTarget.role, sig)} />
      )}
      {signersOpen && (
        <CalSignersModal signers={signers} onClose={() => setSignersOpen(false)} onSave={onSaveSigners || (async () => {})} />
      )}

      {list.length === 0 ? (
        <div style={{ textAlign: 'center', padding: '26px 12px', color: 'var(--ink-3)' }}>
          <I.shield size={32} style={{ opacity: .5, marginBottom: 8 }} />
          <div style={{ fontSize: 13.5 }}>ยังไม่มีบันทึกทบทวนผลสอบเทียบ</div>
          <div style={{ fontSize: 11.5, marginTop: 4 }}>เมื่อได้ใบรับรองกลับมา กด “สร้างบันทึกทบทวน” เพื่อประเมินผลเทียบเกณฑ์และรับรองการใช้งาน</div>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {list.map(rev => {
            const c = calConcl(rev.conclusion);
            const [col, soft] = calToneVars(c.tone);
            const signedCount = CAL_SIGN_ROLES.filter(r => rev.signs && rev.signs[r.key]).length;
            return (
              <div key={rev.id} style={{ border: '1px solid var(--line)', borderRadius: 12, overflow: 'hidden' }}>
                {/* head row */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', padding: '11px 14px', background: 'var(--surface-2)', borderBottom: '1px solid var(--line)' }}>
                  <span className="tnum" style={{ fontWeight: 700, fontSize: 13.5 }}>{window.fmtDateFull(rev.calDate)}</span>
                  {rev.certNo && <span className="kbd-code" style={{ fontSize: 11 }}>{rev.certNo}</span>}
                  <span className="pill" style={{ background: soft, color: col, fontSize: 11.5, fontWeight: 700 }}><span className="dot" />{c.label}</span>
                  <div style={{ flex: 1 }} />
                  <span style={{ fontSize: 11.5, color: signedCount === 3 ? 'var(--ok)' : 'var(--ink-3)', fontWeight: 600 }}>ลงนาม {signedCount}/3</span>
                  <button className="btn btn-icon btn-ghost btn-sm" title="พิมพ์ฟอร์ม" onClick={() => window.printCalReview(rev, inst)}><I.print size={15} /></button>
                  {!readOnly && <button className="btn btn-icon btn-ghost btn-sm" title="แก้ไข" onClick={() => setEditTarget(rev)}><I.edit size={14} /></button>}
                  {!readOnly && admin && <button className="btn btn-icon btn-ghost btn-sm" title="ลบ" onClick={() => del(rev)} style={{ color: 'var(--danger)' }}><I.trash size={14} /></button>}
                </div>
                {/* body */}
                <div style={{ padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 12 }}>
                  {rev.purpose && <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.5 }}><b style={{ color: 'var(--ink)', fontWeight: 600 }}>วัตถุประสงค์ & จุดสอบเทียบ:</b> {rev.purpose}</div>}
                  {rev.params && rev.params.length > 0 && (
                    <div className="tbl-wrap" style={{ border: '1px solid var(--line)', borderRadius: 9 }}>
                      <table className="tbl" style={{ fontSize: 12 }}>
                        <thead><tr><th>พารามิเตอร์</th><th>ค่ากำหนด</th><th>ผลที่วัดได้</th><th>เกณฑ์ MPE</th><th style={{ width: 84, textAlign: 'center' }}>ผล</th></tr></thead>
                        <tbody>
                          {rev.params.map((p, i) => {
                            const [pc, ps] = calToneVars(p.pass ? 'ok' : 'danger');
                            return (
                              <tr key={i}>
                                <td>{p.name || '—'}</td><td>{p.nominal || '—'}</td><td>{p.measured || '—'}</td>
                                <td className="mono">{p.mpe || '—'}</td>
                                <td style={{ textAlign: 'center' }}><span className="pill" style={{ background: ps, color: pc, fontSize: 10.5, fontWeight: 700 }}>{p.pass ? 'ผ่าน' : 'ไม่ผ่าน'}</span></td>
                              </tr>
                            );
                          })}
                        </tbody>
                      </table>
                    </div>
                  )}
                  {rev.recommendation && <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.5 }}><b style={{ color: 'var(--ink)', fontWeight: 600 }}>ข้อเสนอแนะ:</b> {rev.recommendation}</div>}

                  {/* sign-off chain (in order) */}
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 10, paddingTop: 4 }}>
                    {CAL_SIGN_ROLES.map((role, ri) => {
                      const sig = rev.signs && rev.signs[role.key];
                      const prevDone = ri === 0 || (rev.signs && rev.signs[CAL_SIGN_ROLES[ri - 1].key]);
                      return (
                        <div key={role.key} style={{ border: '1px dashed var(--line)', borderRadius: 10, padding: '9px 11px', background: sig ? 'var(--ok-soft)' : 'var(--surface)' }}>
                          <div style={{ fontSize: 10.5, color: 'var(--ink-3)', fontWeight: 600 }}>{ri + 1}. {role.title}</div>
                          {sig ? (
                            <div style={{ marginTop: 4 }}>
                              <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{sig.name}</div>
                              <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{role.verb} · {window.fmtDateFull(sig.date)}</div>
                            </div>
                          ) : readOnly ? (
                            <div style={{ marginTop: 6, fontSize: 11.5, color: 'var(--ink-4)' }}>— รอลงนาม —</div>
                          ) : (
                            <button className="btn btn-sm" disabled={!prevDone} title={prevDone ? '' : 'ต้องลงนามลำดับก่อนหน้าก่อน'}
                              onClick={() => setSignTarget({ review: rev, role })}
                              style={{ marginTop: 6, width: '100%', justifyContent: 'center', opacity: prevDone ? 1 : .5 }}>
                              <I.check size={13} /> ลงนาม{role.verb}
                            </button>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </SectionCard>
  );
}
window.CalReviewSection = CalReviewSection;
