/* ============================================================
   audittrail.jsx — change history (ISO 15189 §6.x record control).
   Reads window.Audit; chronological, filterable, per-instrument.
   ============================================================ */
const AUDIT_META = {
  inst_edit:     { label: 'แก้ไขข้อมูลเครื่องมือ', tone: 'accent', icon: 'edit' },
  inst_status:   { label: 'เปลี่ยนสถานะการใช้งาน', tone: 'warn', icon: 'shield' },
  inst_add:      { label: 'เพิ่มเครื่องมือใหม่', tone: 'ok', icon: 'plus' },
  inst_delete:   { label: 'ลบเครื่องมือ', tone: 'danger', icon: 'close' },
  repair:        { label: 'งานแจ้งซ่อม', tone: 'warn', icon: 'wrench' },
  reagent_add:   { label: 'เพิ่มล็อตน้ำยา/QC', tone: 'ok', icon: 'flask' },
  reagent_edit:  { label: 'แก้ไขล็อตน้ำยา/QC', tone: 'accent', icon: 'flask' },
  reagent_delete:{ label: 'ลบล็อตน้ำยา/QC', tone: 'danger', icon: 'flask' },
  admin_login:   { label: 'เข้าสู่โหมดผู้ดูแล', tone: 'accent', icon: 'unlock' },
  admin_logout:  { label: 'ออกจากโหมดผู้ดูแล', tone: 'none', icon: 'lock' },
  login:         { label: 'เข้าสู่ระบบ', tone: 'none', icon: 'user' },
};
const AUDIT_CAT = [
  { key: 'all', label: 'ทั้งหมด', match: () => true },
  { key: 'inst', label: 'เครื่องมือ', match: a => a.startsWith('inst_') },
  { key: 'reagent', label: 'น้ำยา/QC', match: a => a.startsWith('reagent_') },
  { key: 'repair', label: 'แจ้งซ่อม', match: a => a === 'repair' },
  { key: 'access', label: 'การเข้าใช้ระบบ', match: a => a === 'login' || a.startsWith('admin_') },
];

function relTime(iso) {
  const d = new Date(iso), now = new Date();
  const mins = Math.round((now - d) / 60000);
  if (mins < 1) return 'เมื่อสักครู่';
  if (mins < 60) return `${mins} นาทีที่แล้ว`;
  const hrs = Math.round(mins / 60);
  if (hrs < 24) return `${hrs} ชม.ที่แล้ว`;
  const days = Math.round(hrs / 24);
  if (days < 30) return `${days} วันที่แล้ว`;
  return fmtDate(iso.slice(0, 10));
}
function tsFull(iso) {
  const d = new Date(iso);
  const t = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
  return `${fmtDate(iso.slice(0, 10))} ${t} น.`;
}
const ROLE_LABEL = { mt: 'นักเทคนิคการแพทย์', chief: 'หัวหน้าห้องแล็บ', admin: 'ผู้ดูแลระบบ' };

/* per-instrument compact audit (used on detail page) */
function InstrumentAudit({ code, max = 5 }) {
  const [, bump] = useState(0);
  useEffect(() => Audit.subscribe(() => bump(x => x + 1)), []);
  const rows = Audit.forCode(code).slice(0, max);
  if (!rows.length) return null;
  return (
    <SectionCard icon={I.history} title="ประวัติการแก้ไข (Audit trail)" sub={`บันทึกการเปลี่ยนแปลงล่าสุดของเครื่องนี้`}>
      <div style={{ position: 'relative', paddingLeft: 24 }}>
        <div style={{ position: 'absolute', left: 6, top: 4, bottom: 4, width: 2, background: 'var(--line)' }} />
        {rows.map(e => {
          const m = AUDIT_META[e.action] || { tone: 'none' };
          const col = m.tone === 'accent' ? 'var(--accent)' : m.tone === 'none' ? 'var(--ink-4)' : `var(--${m.tone})`;
          return (
            <div key={e.id} style={{ position: 'relative', paddingBottom: 16 }}>
              <div style={{ position: 'absolute', left: -24, top: 2, width: 14, height: 14, borderRadius: 99, background: col, border: '2.5px solid var(--surface)', boxShadow: '0 0 0 2px var(--line)' }} />
              <div style={{ display: 'flex', gap: 8, alignItems: 'baseline', flexWrap: 'wrap' }}>
                <span style={{ fontSize: 13, fontWeight: 600 }}>{(m.label) || e.action}</span>
                <span style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{tsFull(e.ts)}</span>
              </div>
              {e.field && <div style={{ fontSize: 12.5, color: 'var(--ink-2)', marginTop: 1 }}>{e.field}: <span style={{ color: 'var(--ink-3)' }}>{e.from || '—'}</span> → <b>{e.to || '—'}</b></div>}
              {e.detail && !e.field && <div style={{ fontSize: 12.5, color: 'var(--ink-2)', marginTop: 1 }}>{e.detail}</div>}
              <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 1 }}>โดย {e.user}</div>
            </div>
          );
        })}
      </div>
    </SectionCard>
  );
}

/* full audit-trail view */
function AuditTrail({ instruments, go, admin }) {
  const [, bump] = useState(0);
  useEffect(() => Audit.subscribe(() => bump(x => x + 1)), []);
  const [cat, setCat] = useState('all');
  const [q, setQ] = useState('');

  const all = Audit.all();
  const catDef = AUDIT_CAT.find(c => c.key === cat) || AUDIT_CAT[0];
  const filtered = useMemo(() => {
    const ql = q.trim().toLowerCase();
    return all.filter(e => {
      if (!catDef.match(e.action)) return false;
      if (ql) { const hay = `${e.code || ''} ${e.target || ''} ${e.detail || ''} ${e.field || ''} ${e.user || ''} ${(AUDIT_META[e.action] || {}).label || ''}`.toLowerCase(); if (!hay.includes(ql)) return false; }
      return true;
    });
  }, [all, cat, q, catDef]);

  // group by day
  const groups = useMemo(() => {
    const g = {};
    filtered.forEach(e => { const day = e.ts.slice(0, 10); (g[day] = g[day] || []).push(e); });
    return Object.entries(g).sort((a, b) => (a[0] < b[0] ? 1 : -1));
  }, [filtered]);

  const catCounts = useMemo(() => {
    const c = {};
    AUDIT_CAT.forEach(cd => c[cd.key] = all.filter(e => cd.match(e.action)).length);
    return c;
  }, [all]);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <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="ค้นหา รหัสเครื่อง / รายการ / ผู้ทำ…" value={q} onChange={e => setQ(e.target.value)} />
        </div>
        <div style={{ flex: 1 }} />
        <div style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>บันทึกทั้งหมด <b className="tnum" style={{ color: 'var(--ink)' }}>{all.length}</b> รายการ</div>
        {admin && all.length > 0 && (
          <button className="btn btn-sm" onClick={() => { if (window.confirm('ล้างประวัติการแก้ไขทั้งหมด? (เฉพาะผู้ดูแล)')) Audit.clear(); }}><I.close size={14} /> ล้างประวัติ</button>
        )}
      </div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        {AUDIT_CAT.map(c => (
          <button key={c.key} className={`chip ${cat === c.key ? 'on' : ''}`} onClick={() => setCat(c.key)}>
            {c.label} <span className="tnum" style={{ opacity: .6, marginLeft: 2 }}>{catCounts[c.key]}</span>
          </button>
        ))}
      </div>

      {groups.length === 0 ? (
        <div className="card"><EmptyState icon={I.history} title="ยังไม่มีประวัติการแก้ไข" sub="ทุกการเปลี่ยนแปลงในระบบจะถูกบันทึกที่นี่อัตโนมัติ" /></div>
      ) : groups.map(([day, rows]) => (
        <div key={day} className="card enter" style={{ overflow: 'hidden' }}>
          <div style={{ padding: '11px 20px', borderBottom: '1px solid var(--line)', background: 'var(--surface-2)', fontSize: 12.5, fontWeight: 700, color: 'var(--ink-2)' }}>
            {fmtDateFull(day)} <span className="tnum" style={{ color: 'var(--ink-4)', fontWeight: 500 }}>· {rows.length} รายการ</span>
          </div>
          <div>
            {rows.map(e => {
              const m = AUDIT_META[e.action] || { label: e.action, tone: 'none', icon: 'history' };
              const Ico = I[m.icon] || I.history;
              const col = m.tone === 'accent' ? 'var(--accent)' : m.tone === 'none' ? 'var(--ink-3)' : `var(--${m.tone})`;
              const soft = m.tone === 'accent' ? 'var(--accent-soft)' : m.tone === 'none' ? 'var(--none-soft)' : `var(--${m.tone}-soft)`;
              return (
                <div key={e.id} className="audit-row" style={{ display: 'flex', gap: 13, padding: '12px 20px', borderBottom: '1px solid var(--line-soft)', alignItems: 'flex-start', cursor: e.code ? 'pointer' : 'default' }}
                  onClick={() => e.code && instruments.some(i => i.code === e.code) && go('detail', { code: e.code })}>
                  <span style={{ width: 32, height: 32, borderRadius: 9, flex: 'none', display: 'grid', placeItems: 'center', background: soft, color: col }}><Ico size={16} /></span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', gap: 8, alignItems: 'baseline', flexWrap: 'wrap' }}>
                      <span style={{ fontSize: 13.5, fontWeight: 600 }}>{m.label}</span>
                      {e.code && <span className="code" style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{e.code}</span>}
                    </div>
                    {e.target && <div style={{ fontSize: 12.5, color: 'var(--ink-2)', marginTop: 1 }}>{e.target}</div>}
                    {e.field && <div style={{ fontSize: 12.5, color: 'var(--ink-2)', marginTop: 1 }}>{e.field}: <span style={{ color: 'var(--ink-3)' }}>{e.from || '—'}</span> → <b>{e.to || '—'}</b></div>}
                    {e.detail && !e.field && <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 1 }}>{e.detail}</div>}
                  </div>
                  <div style={{ textAlign: 'right', flex: 'none' }}>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-3)' }} title={tsFull(e.ts)}>{relTime(e.ts)}</div>
                    <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 1 }}>{e.user}{e.role && ROLE_LABEL[e.role] ? ` · ${ROLE_LABEL[e.role]}` : ''}</div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, { AuditTrail, InstrumentAudit, AUDIT_META });

/* demo seed so the trail isn't empty on first load (deterministic, past-dated) */
window.__seedAudit = function () {
  const insts = (window.LAB_DATA && window.LAB_DATA.instruments) || [];
  const pick = (n) => insts.filter(i => i.code)[n] || {};
  const iso = (daysAgo, hh, mm) => { const d = new Date(TODAY); d.setDate(d.getDate() - daysAgo); d.setHours(hh, mm, 0, 0); return d.toISOString(); };
  const e = (o) => ({ id: 'seed-' + Math.random().toString(36).slice(2), role: 'mt', user: 'นักเทคนิคการแพทย์', ...o });
  const a = pick(2), b = pick(20), c = pick(45);
  return [
    e({ ts: iso(0, 9, 12), action: 'inst_status', user: 'ทนพญ. สุภาวดี เบ้าทอง', code: a.code, target: a.type, field: 'สถานะการใช้งาน', from: 'ใช้งานได้', to: 'รอซ่อมบำรุง' }),
    e({ ts: iso(0, 8, 40), action: 'reagent_edit', user: 'ทนพ. พงศกร วันทาพงษ์', code: b.code, target: 'สารควบคุมคุณภาพระดับปกติ (QC Normal)', detail: 'อัปเดตผล QC ประจำวัน' }),
    e({ ts: iso(1, 15, 22), action: 'inst_edit', code: c.code, target: c.type, field: 'วันสอบเทียบ', from: '—', to: fmtDate(c.cal || TODAY.toISOString().slice(0,10)) }),
    e({ ts: iso(2, 11, 5), action: 'admin_login', user: 'หัวหน้าห้องแล็บ', role: 'chief', detail: 'เข้าสู่โหมดผู้ดูแลระบบ' }),
    e({ ts: iso(3, 13, 48), action: 'inst_add', code: b.code, target: b.type, detail: 'ลงทะเบียนเครื่องมือใหม่' }),
  ];
};
