// Case Review (M&M / RCA), Analytics, Supervisee dashboard, Nurse Profile

// ===================== Add Case Modal =====================
const AddCaseModal = ({ onSave, onClose }) => {
  const today = new Date().toISOString().slice(0, 10);
  const [form, setForm] = useState({
    title: '', date: today, severity: 'near-miss', type: 'M&M Review',
    rcaLink: '', summary: '', lead: 'n01', participants: [], status: 'in-progress',
  });
  const [lessons, setLessons] = useState(['']);
  const [err, setErr] = useState('');
  const set = (k, v) => setForm(p => ({ ...p, [k]: v }));

  const toggleParticipant = (id) => {
    setForm(p => ({
      ...p,
      participants: p.participants.includes(id)
        ? p.participants.filter(x => x !== id)
        : [...p.participants, id],
    }));
  };

  const handleSave = () => {
    if (!form.title.trim()) { setErr('กรุณากรอกชื่อเคส'); return; }
    if (!form.summary.trim()) { setErr('กรุณากรอกสรุปเคส'); return; }
    const validLessons = lessons.filter(l => l.trim());
    onSave({
      ...form,
      id: 'cs' + Date.now(),
      rcaLink: form.rcaLink.trim() || null,
      title: form.title.trim(),
      summary: form.summary.trim(),
      lessons: validLessons.length ? validLessons : ['ยังไม่ระบุ'],
    });
    onClose();
  };

  const inputStyle = { width: '100%', padding: '8px 10px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-surface)', color: 'var(--c-ink)', fontSize: 13, boxSizing: 'border-box' };
  const labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--c-ink-muted)', marginBottom: 4 };

  const supervisors = D.STAFF.filter(s => window.isSupervisorRole ? window.isSupervisorRole(s.role) : true);

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.45)', zIndex: 9990, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '16px' }}>
      <div style={{ background: 'var(--c-surface)', borderRadius: 14, padding: 28, width: 580, maxWidth: '100%', maxHeight: '92vh', overflowY: 'auto', boxShadow: '0 20px 60px rgba(0,0,0,.25)' }}>
        <div className="flex" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
          <h3 style={{ margin: 0 }}>เพิ่มเคสทบทวน</h3>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 22, lineHeight: 1 }}>×</button>
        </div>

        <div style={{ marginBottom: 14 }}>
          <label style={labelStyle}>ชื่อเคส *</label>
          <input value={form.title} onChange={e => set('title', e.target.value)} placeholder="เช่น Near-miss: Shoulder dystocia ในมารดาเบาหวาน" style={inputStyle} autoFocus />
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 14 }}>
          <div>
            <label style={labelStyle}>วันที่เกิดเหตุ</label>
            <input type="date" value={form.date} onChange={e => set('date', e.target.value)} style={inputStyle} />
          </div>
          <div>
            <label style={labelStyle}>ประเภทความรุนแรง</label>
            <select value={form.severity} onChange={e => set('severity', e.target.value)} style={inputStyle}>
              <option value="near-miss">⚠ Near miss</option>
              <option value="incident">⚠ Incident</option>
            </select>
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 14 }}>
          <div>
            <label style={labelStyle}>รูปแบบการทบทวน</label>
            <select value={form.type} onChange={e => set('type', e.target.value)} style={inputStyle}>
              <option value="M&M Review">M&M Review</option>
              <option value="RCA">RCA</option>
              <option value="Case Conference">Case Conference</option>
            </select>
          </div>
          <div>
            <label style={labelStyle}>เลข RCA (ถ้ามี)</label>
            <input value={form.rcaLink} onChange={e => set('rcaLink', e.target.value)} placeholder="เช่น RCA-2026-018" style={inputStyle} />
          </div>
        </div>

        <div style={{ marginBottom: 14 }}>
          <label style={labelStyle}>สรุปเคส *</label>
          <textarea value={form.summary} onChange={e => set('summary', e.target.value)} rows={3}
            placeholder="สรุปสิ่งที่เกิดขึ้น สาเหตุ และผลลัพธ์"
            style={{ ...inputStyle, resize: 'vertical', fontFamily: 'inherit', lineHeight: 1.6 }} />
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 14 }}>
          <div>
            <label style={labelStyle}>ผู้นำเคส</label>
            <select value={form.lead} onChange={e => set('lead', e.target.value)} style={inputStyle}>
              {supervisors.map(s => <option key={s.id} value={s.id}>{s.title}{s.name}</option>)}
            </select>
          </div>
          <div>
            <label style={labelStyle}>สถานะ</label>
            <select value={form.status} onChange={e => set('status', e.target.value)} style={inputStyle}>
              <option value="in-progress">in-progress</option>
              <option value="closed">closed</option>
            </select>
          </div>
        </div>

        <div style={{ marginBottom: 14 }}>
          <label style={labelStyle}>ผู้ร่วมอภิปราย</label>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, padding: '10px 12px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-bg)', maxHeight: 120, overflowY: 'auto' }}>
            {D.STAFF.filter(s => s.id !== form.lead).map(s => {
              const checked = form.participants.includes(s.id);
              return (
                <label key={s.id} style={{ display: 'flex', alignItems: 'center', gap: 5, cursor: 'pointer', padding: '2px 0' }}>
                  <input type="checkbox" checked={checked} onChange={() => toggleParticipant(s.id)} style={{ accentColor: 'var(--c-primary)' }} />
                  <span className="txt-xs">{s.title}{s.name.split(' ')[0]}</span>
                </label>
              );
            })}
          </div>
        </div>

        <div style={{ marginBottom: 18 }}>
          <label style={labelStyle}>Lessons learned</label>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {lessons.map((l, i) => (
              <div key={i} className="flex" style={{ gap: 6 }}>
                <input
                  value={l} onChange={e => setLessons(prev => prev.map((x, j) => j === i ? e.target.value : x))}
                  placeholder={`บทเรียนที่ ${i + 1}`}
                  style={{ ...inputStyle, flex: 1 }}
                />
                {lessons.length > 1 && (
                  <button onClick={() => setLessons(prev => prev.filter((_, j) => j !== i))}
                    style={{ background: 'none', border: '1px solid var(--c-border)', borderRadius: 8, padding: '0 10px', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 16 }}>✕</button>
                )}
              </div>
            ))}
            <button className="btn-outline txt-xs" style={{ alignSelf: 'flex-start', padding: '5px 14px', borderStyle: 'dashed' }}
              onClick={() => setLessons(p => [...p, ''])}>
              + เพิ่มบทเรียน
            </button>
          </div>
        </div>

        {err && <div className="txt-sm" style={{ color: 'var(--c-danger)', background: 'var(--c-danger-soft)', padding: '8px 12px', borderRadius: 8, marginBottom: 12 }}>{err}</div>}

        <div className="flex" style={{ gap: 10, justifyContent: 'flex-end' }}>
          <button className="btn-outline" onClick={onClose}>ยกเลิก</button>
          <button className="btn-primary" onClick={handleSave}>+ บันทึกเคส</button>
        </div>
      </div>
    </div>
  );
};

// ===================== Case Review =====================
const CaseReview = () => {
  const [cases, setCases] = useState(() => [...D.CASES]);
  const [selected, setSelected] = useState(D.CASES[0]);
  const [filter, setFilter] = useState('all');
  const [addOpen, setAddOpen] = useState(false);

  const displayed = cases.filter(c => {
    if (filter === 'near-miss') return c.severity === 'near-miss';
    if (filter === 'incident') return c.severity === 'incident';
    if (filter === 'pending') return c.status !== 'closed';
    return true;
  });

  const handleAdd = (newCase) => {
    setCases(prev => [newCase, ...prev]);
    setSelected(newCase);
  };

  return (
    <div className="page">
      <div className="section-h">
        <div>
          <h2>Case Review · M&M · RCA</h2>
          <div className="sub">การนิเทศจากเคสสำคัญและอุบัติการณ์ · เชื่อมโยงกับ Risk Management</div>
        </div>
        <button className="btn btn-primary" onClick={() => setAddOpen(true)}>
          <Icon name="plus" size={14} />+ เพิ่มเคสทบทวน
        </button>
      </div>

      <div className="kpi-row" style={{ marginBottom: 16 }}>
        <div className="kpi">
          <div className="label">เคสทั้งหมดเดือนนี้</div>
          <div className="value">{cases.length}</div>
          <div className="delta muted">ตั้งแต่ 1 พ.ค.</div>
        </div>
        <div className="kpi">
          <div className="label">Near miss</div>
          <div className="value">{cases.filter(c => c.severity === 'near-miss').length}</div>
          <div className="delta up">เรียนรู้ได้ก่อนเกิด</div>
        </div>
        <div className="kpi">
          <div className="label">Incident → RCA</div>
          <div className="value">{cases.filter(c => c.severity === 'incident').length}</div>
          <div className="delta muted">เชื่อมโยง Risk Mgmt</div>
        </div>
        <div className="kpi">
          <div className="label">ปิดเคส</div>
          <div className="value">{cases.filter(c => c.status === 'closed').length}<small> / {cases.length}</small></div>
          <div className="delta muted">การปรับปรุงระบบ</div>
        </div>
      </div>

      <div className="split">
        <div className="card">
          <div className="card-header">
            <h3>รายการเคส</h3>
            <div className="chips" style={{ marginLeft: 'auto' }}>
              <button className={`chip ${filter==='all'?'active':''}`} onClick={() => setFilter('all')}>ทั้งหมด</button>
              <button className={`chip ${filter==='near-miss'?'active':''}`} onClick={() => setFilter('near-miss')}>Near miss</button>
              <button className={`chip ${filter==='incident'?'active':''}`} onClick={() => setFilter('incident')}>Incident</button>
              <button className={`chip ${filter==='pending'?'active':''}`} onClick={() => setFilter('pending')}>รออภิปราย</button>
            </div>
          </div>
          <div className="card-body" style={{ padding: 0 }}>
            {displayed.length === 0 ? (
              <div className="empty" style={{ padding: 32 }}>ไม่มีเคสที่ตรงกับตัวกรอง</div>
            ) : displayed.map(c => (
              <div
                key={c.id}
                onClick={() => setSelected(c)}
                style={{
                  padding: 16,
                  borderBottom: '1px solid var(--c-border-soft)',
                  cursor: 'pointer',
                  background: selected?.id === c.id ? 'var(--c-primary-soft)' : 'transparent',
                  borderLeft: selected?.id === c.id ? '3px solid var(--c-primary)' : '3px solid transparent',
                }}
              >
                <div className="flex-between" style={{ marginBottom: 6 }}>
                  <div className="flex">
                    <span className={`badge sev-${c.severity}`}>{c.severity === 'near-miss' ? '⚠ Near miss' : '⚠ Incident'}</span>
                    <span className="badge">{c.type}</span>
                    {c.rcaLink && <span className="mono txt-xs muted">{c.rcaLink}</span>}
                  </div>
                  <span className={`badge ${c.status === 'closed' ? 'ok' : 'warn'}`}>{c.status}</span>
                </div>
                <h4 style={{ margin: '4px 0', fontSize: 14 }}>{c.title}</h4>
                <div className="txt-xs muted">{c.date} · นำโดย {staffShort(c.lead)} · ผู้ร่วม {c.participants.length} คน</div>
              </div>
            ))}
          </div>
        </div>

        {selected && (
          <div className="card">
            <div className="card-body">
              <div className="flex" style={{ gap: 6, marginBottom: 8 }}>
                <span className={`badge sev-${selected.severity}`}>{selected.severity === 'near-miss' ? '⚠ Near miss' : '⚠ Incident'}</span>
                <span className="badge">{selected.type}</span>
              </div>
              <h3 style={{ margin: '0 0 8px' }}>{selected.title}</h3>
              <div className="mono txt-xs muted" style={{ marginBottom: 12 }}>
                {selected.date} · {selected.rcaLink || 'ไม่ผูก RCA'}
              </div>
              <div className="form-section">
                <h4>Summary</h4>
                <p className="txt-sm" style={{ lineHeight: 1.6, color: 'var(--c-ink-soft)' }}>{selected.summary}</p>
              </div>
              <div className="form-section">
                <h4>Lessons learned</h4>
                <div className="stack" style={{ gap: 6 }}>
                  {selected.lessons.map((l, i) => (
                    <div key={i} className="flex" style={{ gap: 10, fontSize: 13 }}>
                      <div style={{ width: 20, height: 20, borderRadius: 4, background: 'var(--c-ok-soft)', color: 'var(--c-ok)', display: 'grid', placeItems: 'center', flexShrink: 0, marginTop: 2 }}>
                        <Icon name="check" size={12} />
                      </div>
                      <span>{l}</span>
                    </div>
                  ))}
                </div>
              </div>
              <div className="form-section">
                <h4>ผู้ร่วมอภิปราย</h4>
                <div className="flex" style={{ gap: 8, marginBottom: 8 }}>
                  <Avatar name={D.staffById(selected.lead)?.name || '?'} size={32} />
                  <div>
                    <strong className="txt-sm">{staffName(selected.lead)}</strong>
                    <div className="txt-xs muted">ผู้นำเคส</div>
                  </div>
                </div>
                <div className="flex" style={{ flexWrap: 'wrap', gap: 4 }}>
                  {selected.participants.map(p => (
                    <div key={p} title={staffName(p)}>
                      <Avatar name={D.staffById(p)?.name || '?'} size={26} />
                    </div>
                  ))}
                  {selected.participants.length > 0 && (
                    <span className="txt-xs muted" style={{ alignSelf: 'center' }}>+ {selected.participants.length} ท่าน</span>
                  )}
                </div>
              </div>
              <div className="flex" style={{ gap: 8 }}>
                <button className="btn" style={{ flex: 1 }}><Icon name="edit" size={14} />แก้ไข</button>
                <button className="btn btn-primary" style={{ flex: 1 }}>เปิด RCA</button>
              </div>
            </div>
          </div>
        )}
      </div>

      {addOpen && <AddCaseModal onSave={handleAdd} onClose={() => setAddOpen(false)} />}
    </div>
  );
};

// ===================== Analytics =====================
const Analytics = () => {
  const monthly = [
    { m: 'ธ.ค.', planned: 40, done: 32 },
    { m: 'ม.ค.', planned: 44, done: 36 },
    { m: 'ก.พ.', planned: 42, done: 35 },
    { m: 'มี.ค.', planned: 46, done: 39 },
    { m: 'เม.ย.', planned: 48, done: 42 },
    { m: 'พ.ค.', planned: 48, done: 42 },
  ];
  const byActivity = [
    { label: 'Round', value: 12 },
    { label: 'Conf', value: 4 },
    { label: 'Teach', value: 9 },
    { label: 'Couns', value: 6 },
    { label: 'Probl', value: 3 },
    { label: 'Obs', value: 5 },
    { label: 'Part', value: 8 },
  ];
  const byCompetency = [3.5, 3.8, 3.6, 3.4, 3.9, 3.7];
  const compAxes = ['ทำคลอดปกติ', 'ภาวะฉุกเฉิน', 'ภาวะแทรกซ้อน', 'สูติศาสตร์หัตถการ', 'EFM', 'Functional'];
  const [rateChart, setRateChart] = useState('stacked');
  const [actChart, setActChart] = useState('bar');
  const [compChart, setCompChart] = useState('radar');

  return (
    <div className="page">
      <div className="section-h">
        <div>
          <h2>Analytics & KPI</h2>
          <div className="sub">รายงาน 6 เดือน · ตัวชี้วัดการนิเทศ · Skill development trend</div>
        </div>
        <div className="flex">
          <div className="tabs">
            <button className="tab">3 เดือน</button>
            <button className="tab active">6 เดือน</button>
            <button className="tab">1 ปี</button>
          </div>
          <button className="btn"><Icon name="download" size={14} />รายงาน PDF</button>
        </div>
      </div>

      <div className="grid-2">
        <div className="card">
          <div className="card-header">
            <h3>อัตราการนิเทศตามแผน</h3>
            <span className="sub">· เป้า 90%</span>
            <div className="tabs" style={{ marginLeft: 'auto' }}>
              <button className={`tab ${rateChart==='stacked'?'active':''}`} onClick={() => setRateChart('stacked')}>Stack</button>
              <button className={`tab ${rateChart==='line'?'active':''}`} onClick={() => setRateChart('line')}>Line</button>
              <button className={`tab ${rateChart==='area'?'active':''}`} onClick={() => setRateChart('area')}>Area</button>
            </div>
          </div>
          <div className="card-body">
            <SupervisionRateChart data={monthly} type={rateChart} />
            <div className="flex" style={{ marginTop: 12, gap: 16 }}>
              <span className="flex txt-xs muted"><span style={{ width: 10, height: 10, background: 'var(--c-primary)', borderRadius: 2 }} />ดำเนินการ</span>
              <span className="flex txt-xs muted"><span style={{ width: 10, height: 10, background: 'var(--c-primary-soft)', borderRadius: 2 }} />ขาด</span>
            </div>
          </div>
        </div>

        <div className="card">
          <div className="card-header">
            <h3>กิจกรรมการนิเทศ 7 ประการ</h3>
            <div className="tabs" style={{ marginLeft: 'auto' }}>
              <button className={`tab ${actChart==='bar'?'active':''}`} onClick={() => setActChart('bar')}>Bar</button>
              <button className={`tab ${actChart==='donut'?'active':''}`} onClick={() => setActChart('donut')}>Donut</button>
              <button className={`tab ${actChart==='hbar'?'active':''}`} onClick={() => setActChart('hbar')}>H-Bar</button>
            </div>
          </div>
          <div className="card-body">
            <ActivityChart data={byActivity} type={actChart} />
            <div className="muted txt-xs" style={{ marginTop: 12 }}>
              Round=เยี่ยมตรวจ · Conf=ประชุม · Teach=สอน · Couns=ปรึกษา · Probl=แก้ปัญหา · Obs=สังเกต · Part=ร่วมปฏิบัติ
            </div>
          </div>
        </div>

        <div className="card">
          <div className="card-header">
            <h3>คะแนนเฉลี่ยตามหมวดสมรรถนะ</h3>
            <div className="tabs" style={{ marginLeft: 'auto' }}>
              <button className={`tab ${compChart==='radar'?'active':''}`} onClick={() => setCompChart('radar')}>Radar</button>
              <button className={`tab ${compChart==='bars'?'active':''}`} onClick={() => setCompChart('bars')}>Bars</button>
              <button className={`tab ${compChart==='lollipop'?'active':''}`} onClick={() => setCompChart('lollipop')}>Lollipop</button>
              <button className={`tab ${compChart==='ring'?'active':''}`} onClick={() => setCompChart('ring')}>Rings</button>
            </div>
          </div>
          <div className="card-body">
            <CompetencyChart
              type={compChart}
              axes={compAxes.map(l => ({ id: l, label: l }))}
              values={byCompetency}
            />
          </div>
        </div>

        <div className="card">
          <div className="card-header">
            <h3>Top 5 ทักษะที่ต้องอบรม</h3>
            <span className="sub">· In-service Training Plan</span>
          </div>
          <div className="card-body" style={{ padding: 0 }}>
            <table className="t">
              <thead><tr><th>#</th><th>ทักษะ</th><th>เฉลี่ย</th><th>ผู้ต้องอบรม</th></tr></thead>
              <tbody>
                {D.topGaps().slice(0, 5).map((g, i) => {
                  const needs = D.STAFF.filter(s => !['aide','assistant'].includes(s.pos) && D.MATRIX[s.id][g.id] < 3).length;
                  return (
                    <tr key={g.id}>
                      <td className="mono">{i + 1}</td>
                      <td>
                        <strong className="txt-sm">{g.label}</strong>
                        <div className="txt-xs muted">{g.en}</div>
                      </td>
                      <td><strong className="mono">{g.avg.toFixed(2)}</strong></td>
                      <td>
                        <div className="flex">
                          <span className="badge warn">{needs} ท่าน</span>
                          <button className="btn btn-sm">วางแผน</button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>

      <div className="card" style={{ marginTop: 16 }}>
        <div className="card-header">
          <h3>KPI สรุปประจำเดือน</h3>
          <span className="sub">· พฤษภาคม 2569</span>
        </div>
        <div className="card-body">
          <table className="t">
            <thead><tr><th>ตัวชี้วัด</th><th>เป้าหมาย</th><th>ผลงาน</th><th>สถานะ</th><th>แนวโน้ม</th></tr></thead>
            <tbody>
              <tr><td>อัตราการได้รับการนิเทศครบตามเป้า</td><td>≥ 90%</td><td><strong className="mono">87%</strong></td><td><span className="badge warn">ต่ำกว่าเป้า</span></td><td className="muted">▲ 4%</td></tr>
              <tr><td>อัตรา Bedside Round / นิเทศทั้งหมด</td><td>≥ 60%</td><td><strong className="mono">67%</strong></td><td><span className="badge ok">ผ่าน</span></td><td className="muted">▲ 2%</td></tr>
              <tr><td>คะแนนเฉลี่ยสมรรถนะหลังนิเทศ</td><td>≥ 3.5</td><td><strong className="mono">3.82</strong></td><td><span className="badge ok">ผ่าน</span></td><td className="muted">▲ 0.08</td></tr>
              <tr><td>Near miss → Lesson learned</td><td>100%</td><td><strong className="mono">100%</strong></td><td><span className="badge ok">ผ่าน</span></td><td className="muted">—</td></tr>
              <tr><td>เวลาเฉลี่ย: ตอบสนอง Stat order</td><td>≤ 30 นาที</td><td><strong className="mono">24 นาที</strong></td><td><span className="badge ok">ผ่าน</span></td><td className="muted">▼ 3 นาที</td></tr>
              <tr><td>การส่งเวร ISBAR ผ่านมาตรฐาน</td><td>≥ 85%</td><td><strong className="mono">81%</strong></td><td><span className="badge warn">ใกล้เป้า</span></td><td className="muted">▲ 6%</td></tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
};

// === Supervision rate chart variants ===
const SupervisionRateChart = ({ data, type }) => {
  if (type === 'stacked') {
    return (
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 10, height: 180 }}>
        {data.map((m, i) => {
          const rate = (m.done / m.planned) * 100;
          return (
            <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
              <div className="mono txt-xs muted">{rate.toFixed(0)}%</div>
              <div style={{ width: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', height: 130, gap: 3 }}>
                <div style={{ background: 'var(--c-primary)', height: `${rate * 0.9}%`, borderRadius: '4px 4px 0 0' }} />
                <div style={{ background: 'var(--c-primary-soft)', height: `${(100 - rate) * 0.9}%`, borderRadius: '0 0 4px 4px' }} />
              </div>
              <div className="mono txt-xs muted">{m.m}</div>
            </div>
          );
        })}
      </div>
    );
  }
  const rates = data.map(d => (d.done / d.planned) * 100);
  const w = 480, h = 180, pad = 24;
  const xs = data.map((_, i) => pad + (i * (w - pad * 2) / (data.length - 1)));
  const ys = rates.map(r => h - pad - ((r - 60) / 40) * (h - pad * 2));
  const linePath = 'M ' + xs.map((x, i) => `${x},${ys[i]}`).join(' L ');
  const areaPath = `M ${xs[0]},${h - pad} L ` + xs.map((x, i) => `${x},${ys[i]}`).join(' L ') + ` L ${xs[xs.length-1]},${h - pad} Z`;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} style={{ width: '100%', height: 200 }}>
      {[60, 70, 80, 90, 100].map(g => {
        const y = h - pad - ((g - 60) / 40) * (h - pad * 2);
        return (
          <g key={g}>
            <line x1={pad} y1={y} x2={w - pad / 2} y2={y} stroke="var(--c-border-soft)" strokeDasharray={g === 90 ? '' : '3 3'} strokeWidth={g === 90 ? 1.5 : 1} />
            <text x="4" y={y + 3} fontSize="9" fill="var(--c-ink-muted)" fontFamily="var(--font-mono)">{g}%</text>
          </g>
        );
      })}
      {type === 'area' && <path d={areaPath} fill="var(--c-primary-soft)" />}
      <path d={linePath} fill="none" stroke="var(--c-primary)" strokeWidth="2.5" />
      {xs.map((x, i) => (
        <g key={i}>
          <circle cx={x} cy={ys[i]} r="4" fill="var(--c-primary)" />
          <text x={x} y={ys[i] - 8} textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fontWeight="700" fill="var(--c-primary-ink)">{rates[i].toFixed(0)}%</text>
          <text x={x} y={h - 6} textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--c-ink-muted)">{data[i].m}</text>
        </g>
      ))}
    </svg>
  );
};

// === Activity chart variants ===
const ActivityChart = ({ data, type }) => {
  if (type === 'bar') {
    return <BarChart data={data.map(d => ({ ...d, color: 'var(--c-primary)' }))} height={180} max={14} />;
  }
  if (type === 'hbar') {
    const max = Math.max(...data.map(d => d.value));
    return (
      <div className="stack" style={{ gap: 8 }}>
        {data.map((d, i) => (
          <div key={i}>
            <div className="flex-between txt-sm">
              <span>{d.label}</span>
              <strong className="mono">{d.value}</strong>
            </div>
            <div style={{ height: 10, background: 'var(--c-surface-2)', borderRadius: 999, overflow: 'hidden', marginTop: 3 }}>
              <div style={{ height: '100%', width: `${(d.value / max) * 100}%`, background: 'var(--c-primary)', borderRadius: 999 }} />
            </div>
          </div>
        ))}
      </div>
    );
  }
  if (type === 'donut') {
    const total = data.reduce((s, d) => s + d.value, 0);
    const colors = ['var(--lvl-5)', 'var(--lvl-4)', 'var(--c-accent-blue)', 'var(--c-primary)', 'var(--lvl-3)', 'var(--lvl-2)', 'var(--c-warn)'];
    const segs = data.map((d, i) => ({ value: d.value, color: colors[i % colors.length], label: d.label }));
    return (
      <div style={{ display: 'flex', gap: 24, alignItems: 'center' }}>
        <div style={{ position: 'relative' }}>
          <Donut size={170} segments={segs} thickness={22} />
          <div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', textAlign: 'center' }}>
            <div className="mono" style={{ fontSize: 24, fontWeight: 700 }}>{total}</div>
            <div className="muted txt-xs">รวม</div>
          </div>
        </div>
        <div style={{ flex: 1, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 4 }}>
          {data.map((d, i) => (
            <div key={d.label} className="flex-between txt-sm">
              <span className="flex">
                <span style={{ width: 10, height: 10, background: colors[i % colors.length], borderRadius: 2 }} />
                {d.label}
              </span>
              <strong className="mono">{d.value}</strong>
            </div>
          ))}
        </div>
      </div>
    );
  }
  return null;
};

// ===================== Supervisee dashboard =====================
const SuperviseeDashboard = ({ user }) => {
  const me = D.staffById(user) || D.STAFF[10];
  const skills = D.SKILLS;
  const mySkills = skills.map(sk => ({ ...sk, score: D.MATRIX[me.id][sk.id] }));
  const myStrong = mySkills.filter(s => s.score >= 4).sort((a, b) => b.score - a.score).slice(0, 5);
  const myWeak = mySkills.filter(s => s.score <= 2).sort((a, b) => a.score - b.score).slice(0, 5);
  const radarAxes = D.COMPETENCIES.flatMap(c => c.groups);
  const radarValues = radarAxes.map(ax => avg(ax.items.map(it => D.MATRIX[me.id][it.id])));
  const [chartType, setChartType] = useState('radar');

  return (
    <div className="page">
      <div className="section-h">
        <div>
          <h2>สวัสดี {me.title}{me.name.split(' ')[0]} 👋</h2>
          <div className="sub">{D.POSITIONS[me.pos]} · {me.years} ปี · งานห้องคลอด</div>
        </div>
        <div className="flex">
          <LevelChip level={me.level} />
        </div>
      </div>

      <div className="kpi-row" style={{ marginBottom: 16 }}>
        <div className="kpi accent">
          <div className="label">ระดับสมรรถนะรวม</div>
          <div className="value">{avg(radarValues).toFixed(1)}<small>/5</small></div>
          <div className="delta up">▲ 0.2 จากเดือนที่แล้ว</div>
        </div>
        <div className="kpi">
          <div className="label">นิเทศที่ได้รับเดือนนี้</div>
          <div className="value">8</div>
          <div className="delta muted">เป้า 10 ครั้ง</div>
        </div>
        <div className="kpi">
          <div className="label">จุดแข็ง / จุดอ่อน</div>
          <div className="value">{myStrong.length}<small> · {myWeak.length}</small></div>
          <div className="delta muted">ทักษะที่ต้องรักษา / พัฒนา</div>
        </div>
        <div className="kpi">
          <div className="label">นัดนิเทศครั้งถัดไป</div>
          <div className="value" style={{ fontSize: 20 }}>20 พ.ค.</div>
          <div className="delta muted">PIH/MgSO4 · 08:00</div>
        </div>
      </div>

      <div className="split">
        <div className="stack">
          <div className="card">
            <div className="card-header">
              <h3>โปรไฟล์สมรรถนะของฉัน</h3>
              <div className="tabs" style={{ marginLeft: 'auto' }}>
                <button className={`tab ${chartType==='radar'?'active':''}`} onClick={() => setChartType('radar')}>Radar</button>
                <button className={`tab ${chartType==='bars'?'active':''}`} onClick={() => setChartType('bars')}>Bars</button>
                <button className={`tab ${chartType==='lollipop'?'active':''}`} onClick={() => setChartType('lollipop')}>Lollipop</button>
                <button className={`tab ${chartType==='ring'?'active':''}`} onClick={() => setChartType('ring')}>Rings</button>
              </div>
            </div>
            <div className="card-body">
              <CompetencyChart type={chartType} axes={radarAxes} values={radarValues} />
            </div>
          </div>

          <StrengthsWeaknesses strengths={myStrong} weaknesses={myWeak} />

          <div className="card">
            <div className="card-header">
              <h3>แผนพัฒนาส่วนบุคคล (IDP)</h3>
              <span className="sub">· พฤษภาคม 2569</span>
            </div>
            <div className="card-body">
              {[
                { goal: 'EFM Cat-II interpretation', plan: 'Workshop EFM 19 พ.ค. · ฝึก 10 strips กับ APN', status: 'in-progress', mentor: 'n01' },
                { goal: 'ทำคลอดปกติ (1st delivery)', plan: 'Participation 5 case ภายในสัปดาห์นี้', status: 'in-progress', mentor: 'n05' },
                { goal: 'ส่งเวร ISBAR', plan: 'ฝึก template + ประเมินสัปดาห์หน้า', status: 'todo', mentor: 'n08' },
              ].map((p, i) => (
                <div key={i} style={{ padding: 12, marginBottom: 8, border: '1px solid var(--c-border)', borderRadius: 10 }}>
                  <div className="flex-between">
                    <strong className="txt-sm">{p.goal}</strong>
                    <span className={`badge ${p.status === 'in-progress' ? 'info' : 'warn'}`}>{p.status === 'in-progress' ? 'กำลังดำเนินการ' : 'รอเริ่ม'}</span>
                  </div>
                  <div className="txt-sm muted" style={{ marginTop: 4 }}>{p.plan}</div>
                  <div className="flex" style={{ marginTop: 8 }}>
                    <span className="flex txt-xs">
                      <Avatar name={D.staffById(p.mentor).name} size={20} />
                      <span>นิเทศโดย {staffShort(p.mentor)}</span>
                    </span>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>

        <div className="stack">
          <div className="card card-tight">
            <div className="card-header"><h3>Feedback ที่ได้รับ</h3></div>
            <div className="card-body" style={{ padding: 0 }}>
              {D.LOGS.filter(l => l.supervisee === me.id || l.supervisee === 'n11').slice(0, 4).map(lg => (
                <div key={lg.id} style={{ padding: '12px 16px', borderBottom: '1px solid var(--c-border-soft)' }}>
                  <div className="flex-between">
                    <strong className="txt-sm">{lg.topic}</strong>
                    <LevelChip level={lg.score} />
                  </div>
                  <div className="txt-xs muted" style={{ marginTop: 4 }}>โดย {staffShort(lg.supervisor)} · {lg.date}</div>
                  <div className="txt-sm" style={{ marginTop: 6, color: 'var(--c-ink-soft)' }}>“{lg.note}”</div>
                </div>
              ))}
            </div>
          </div>
          <div className="card card-tight">
            <div className="card-header"><h3>เคสที่ฉันร่วมอภิปราย</h3></div>
            <div className="card-body" style={{ padding: 0 }}>
              {D.CASES.filter(c => c.participants.includes('n11')).map(c => (
                <div key={c.id} style={{ padding: '12px 16px', borderBottom: '1px solid var(--c-border-soft)' }}>
                  <span className={`badge sev-${c.severity}`}>{c.severity}</span>
                  <div className="txt-sm" style={{ fontWeight: 600, marginTop: 4 }}>{c.title}</div>
                  <div className="txt-xs muted" style={{ marginTop: 2 }}>{c.date}</div>
                </div>
              ))}
              <div className="empty">ดูเคสทั้งหมด →</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

// Chart type variations for supervisee competency profile
const CompetencyChart = ({ type, axes, values }) => {
  if (type === 'radar') {
    return (
      <div className="radar-wrap">
        <Radar
          axes={axes.map(a => a.label.length > 14 ? a.label.slice(0, 13) + '…' : a.label)}
          values={values}
          size={320}
        />
      </div>
    );
  }
  if (type === 'bars') {
    return (
      <div className="stack" style={{ gap: 10 }}>
        {axes.map((ax, i) => (
          <div key={ax.id}>
            <div className="flex-between" style={{ marginBottom: 4 }}>
              <span className="txt-sm">{ax.label}</span>
              <div className="flex">
                <LevelChip level={Math.round(values[i])} />
                <strong className="mono txt-sm" style={{ width: 36, textAlign: 'right' }}>{values[i].toFixed(2)}</strong>
              </div>
            </div>
            <div style={{ height: 12, background: 'var(--c-surface-2)', borderRadius: 999, overflow: 'hidden', display: 'flex' }}>
              {[1,2,3,4,5].map(seg => (
                <div
                  key={seg}
                  style={{
                    flex: 1,
                    background: values[i] >= seg ? `var(--lvl-${Math.min(5, Math.round(values[i]))})` : 'transparent',
                    borderRight: seg < 5 ? '2px solid var(--c-surface)' : 'none',
                  }}
                />
              ))}
            </div>
          </div>
        ))}
      </div>
    );
  }
  if (type === 'lollipop') {
    const max = 5;
    return (
      <svg viewBox="0 0 600 280" style={{ width: '100%', height: 320 }}>
        {/* gridlines */}
        {[1,2,3,4,5].map(g => {
          const x = 160 + (g / max) * 400;
          return <line key={g} x1={x} y1="20" x2={x} y2="260" stroke="var(--c-border-soft)" strokeDasharray="3 3" />;
        })}
        {[1,2,3,4,5].map(g => {
          const x = 160 + (g / max) * 400;
          return <text key={g} x={x} y="275" textAnchor="middle" fontSize="9" fill="var(--c-ink-muted)" fontFamily="var(--font-mono)">{g}</text>;
        })}
        {axes.map((ax, i) => {
          const y = 30 + (i * (220 / (axes.length - 1)));
          const v = values[i];
          const x = 160 + (v / max) * 400;
          return (
            <g key={ax.id}>
              <text x="150" y={y + 4} textAnchor="end" fontSize="11" fill="var(--c-ink)">{ax.label.length > 22 ? ax.label.slice(0, 21) + '…' : ax.label}</text>
              <line x1="160" y1={y} x2={x} y2={y} stroke={`var(--lvl-${Math.round(v)})`} strokeWidth="3" />
              <circle cx={x} cy={y} r="8" fill={`var(--lvl-${Math.round(v)})`} />
              <text x={x} y={y + 3} textAnchor="middle" fontSize="10" fontWeight="700" fill="var(--lvl-5-ink)" fontFamily="var(--font-mono)">{Math.round(v)}</text>
            </g>
          );
        })}
      </svg>
    );
  }
  if (type === 'ring') {
    return (
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 16 }}>
        {axes.map((ax, i) => {
          const v = values[i];
          const pct = (v / 5) * 100;
          const r = 40, c = 2 * Math.PI * r;
          return (
            <div key={ax.id} style={{ textAlign: 'center' }}>
              <svg width="100" height="100" viewBox="0 0 100 100">
                <circle cx="50" cy="50" r={r} fill="none" stroke="var(--c-surface-2)" strokeWidth="8" />
                <circle
                  cx="50" cy="50" r={r} fill="none"
                  stroke={`var(--lvl-${Math.round(v)})`}
                  strokeWidth="8"
                  strokeDasharray={`${(pct / 100) * c} ${c}`}
                  strokeDashoffset={c * 0.25}
                  strokeLinecap="round"
                  transform="rotate(-90 50 50)"
                />
                <text x="50" y="55" textAnchor="middle" fontSize="20" fontWeight="700" fontFamily="var(--font-mono)" fill="var(--c-ink)">{v.toFixed(1)}</text>
              </svg>
              <div className="txt-sm" style={{ marginTop: 4, fontWeight: 500 }}>{ax.label.length > 16 ? ax.label.slice(0, 15) + '…' : ax.label}</div>
            </div>
          );
        })}
      </div>
    );
  }
  return null;
};

const StrengthsWeaknesses = ({ strengths, weaknesses }) => (
  <div className="card">
    <div className="card-header">
      <h3>จุดแข็ง · จุดอ่อน</h3>
      <span className="sub">· วิเคราะห์จากผลประเมินล่าสุด</span>
    </div>
    <div className="card-body">
      <div className="grid-2">
        <div style={{ padding: 16, borderRadius: 10, background: 'var(--c-ok-soft)', border: '1px solid transparent' }}>
          <div className="flex" style={{ marginBottom: 12 }}>
            <div style={{ width: 32, height: 32, borderRadius: 8, background: 'var(--c-ok)', color: 'white', display: 'grid', placeItems: 'center' }}>
              <Icon name="sparkles" size={18} />
            </div>
            <div>
              <strong style={{ color: 'var(--c-ok)' }}>จุดแข็ง</strong>
              <div className="txt-xs muted">ทักษะที่ทำได้ดี · พร้อมเป็น Preceptor ได้</div>
            </div>
          </div>
          {strengths.length === 0 && <div className="muted txt-sm">ยังไม่มีทักษะที่ถึงระดับ Proficient ขึ้นไป — แต่กำลังพัฒนาดี ✨</div>}
          {strengths.map(s => (
            <div key={s.id} className="flex-between" style={{ padding: '6px 0', borderBottom: '1px solid rgba(0,0,0,0.06)' }}>
              <div>
                <div className="txt-sm" style={{ fontWeight: 500 }}>{s.label}</div>
                <div className="txt-xs muted">{s.groupLabel}</div>
              </div>
              <LevelChip level={s.score} />
            </div>
          ))}
        </div>

        <div style={{ padding: 16, borderRadius: 10, background: 'var(--c-warn-soft)', border: '1px solid transparent' }}>
          <div className="flex" style={{ marginBottom: 12 }}>
            <div style={{ width: 32, height: 32, borderRadius: 8, background: 'var(--c-warn)', color: 'white', display: 'grid', placeItems: 'center' }}>
              <Icon name="target" size={18} />
            </div>
            <div>
              <strong style={{ color: 'var(--c-warn)' }}>จุดที่ต้องพัฒนา</strong>
              <div className="txt-xs muted">ทักษะที่ต้องเน้นในการนิเทศต่อไป</div>
            </div>
          </div>
          {weaknesses.length === 0 && <div className="muted txt-sm">ผ่านเกณฑ์ทุกทักษะ! ดูแลรักษามาตรฐานนี้ต่อไป ✓</div>}
          {weaknesses.map(s => (
            <div key={s.id} className="flex-between" style={{ padding: '6px 0', borderBottom: '1px solid rgba(0,0,0,0.06)' }}>
              <div>
                <div className="txt-sm" style={{ fontWeight: 500 }}>{s.label}</div>
                <div className="txt-xs muted">{s.groupLabel}</div>
              </div>
              <div className="flex">
                <LevelChip level={s.score} />
                <button className="btn btn-sm">วางแผน</button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  </div>
);

// ===================== User Management =====================

const USER_ROLES = [
  { key: 'dept_head',  label: 'หัวหน้ากลุ่มงาน', color: '#7c3aed',
    desc: 'เข้าถึงทุกส่วน · จัดการผู้ใช้ · ดูรายงานทั้งหมด' },
  { key: 'unit_head',  label: 'หัวหน้างาน',       color: '#059669',
    desc: 'จัดการนิเทศ · บุคลากร · Analytics · หัวข้อนิเทศ' },
  { key: 'shift_head', label: 'หัวหน้าเวร',        color: '#0284c7',
    desc: 'นิเทศ · บันทึก · Case Review · Analytics' },
  { key: 'supervisor', label: 'ผู้นิเทศ',           color: '#0369a1',
    desc: 'นิเทศ · บันทึก · Case Review · คลังความรู้' },
  { key: 'supervisee', label: 'ผู้รับการนิเทศ',     color: '#6b7280',
    desc: 'Dashboard ส่วนตัว · บันทึกนิเทศของตน · คลังความรู้' },
];

const ACCESS_MATRIX = [
  { page: 'Dashboard',          dept_head: true,  unit_head: true,  shift_head: true,  supervisor: true,  supervisee: true  },
  { page: 'Skill Matrix',       dept_head: true,  unit_head: true,  shift_head: true,  supervisor: true,  supervisee: false },
  { page: 'แผน & ปฏิทิน',       dept_head: true,  unit_head: true,  shift_head: true,  supervisor: true,  supervisee: false },
  { page: 'หัวข้อนิเทศ (Admin)', dept_head: true,  unit_head: true,  shift_head: false, supervisor: false, supervisee: false },
  { page: 'บันทึกการนิเทศ',      dept_head: true,  unit_head: true,  shift_head: true,  supervisor: true,  supervisee: true  },
  { page: 'Case Review',        dept_head: true,  unit_head: true,  shift_head: true,  supervisor: true,  supervisee: false },
  { page: 'Analytics',          dept_head: true,  unit_head: true,  shift_head: true,  supervisor: false, supervisee: false },
  { page: 'บุคลากร',             dept_head: true,  unit_head: true,  shift_head: false, supervisor: false, supervisee: false },
  { page: 'คลังความรู้',         dept_head: true,  unit_head: true,  shift_head: true,  supervisor: true,  supervisee: true  },
  { page: 'จัดการผู้ใช้งาน',     dept_head: true,  unit_head: true,  shift_head: false, supervisor: false, supervisee: false },
];

const RoleBadge = ({ roleKey }) => {
  const roles = window.parseRoles ? window.parseRoles(roleKey) : [roleKey];
  return (
    <div className="flex" style={{ gap: 3, flexWrap: 'wrap' }}>
      {roles.map(rk => {
        const r = USER_ROLES.find(x => x.key === rk);
        if (!r) return null;
        return (
          <span key={rk} className="badge" style={{ background: r.color + '1a', color: r.color, border: `1px solid ${r.color}44`, whiteSpace: 'nowrap', fontSize: 11 }}>
            {r.label}
          </span>
        );
      })}
    </div>
  );
};

// ── Role checkbox popover ──────────────────────────────────
const RolePopover = ({ staffId, currentRole, onClose }) => {
  const [selected, setSelected] = useState(() => window.parseRoles ? window.parseRoles(currentRole) : [currentRole || 'supervisee']);
  const [saving, setSaving] = useState(false);

  const toggle = (key) => {
    setSelected(prev => {
      if (prev.includes(key)) {
        const next = prev.filter(k => k !== key);
        return next.length ? next : prev; // must have at least 1
      }
      return [...prev, key];
    });
  };

  const handleSave = async () => {
    setSaving(true);
    const roleVal = selected.length === 1 ? selected[0] : JSON.stringify(selected);
    try {
      await window.DB.staff.update(staffId, { role: roleVal });
      onClose();
    } catch (e) {
      alert('บันทึกไม่สำเร็จ: ' + e.message);
      setSaving(false);
    }
  };

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 9999 }} onClick={onClose}>
      <div
        style={{ position: 'absolute', background: 'var(--c-surface)', border: '1px solid var(--c-border)', borderRadius: 10, padding: '12px 14px', boxShadow: '0 8px 24px rgba(0,0,0,.15)', minWidth: 200, top: '50%', left: '50%', transform: 'translate(-50%,-50%)' }}
        onClick={e => e.stopPropagation()}
      >
        <div className="txt-sm" style={{ fontWeight: 600, marginBottom: 10 }}>เลือกบทบาท (เลือกได้หลายบทบาท)</div>
        {USER_ROLES.map(r => (
          <label key={r.key} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 0', cursor: 'pointer' }}>
            <input
              type="checkbox"
              checked={selected.includes(r.key)}
              onChange={() => toggle(r.key)}
              style={{ width: 15, height: 15, accentColor: r.color }}
            />
            <span style={{ fontSize: 12, fontWeight: 600, color: r.color, background: r.color + '15', padding: '2px 8px', borderRadius: 10, border: `1px solid ${r.color}33` }}>{r.label}</span>
          </label>
        ))}
        <div className="flex" style={{ gap: 8, marginTop: 12, justifyContent: 'flex-end' }}>
          <button className="btn-outline txt-xs" onClick={onClose} style={{ padding: '5px 12px' }}>ยกเลิก</button>
          <button className="btn-primary txt-xs" onClick={handleSave} disabled={saving} style={{ padding: '5px 14px' }}>
            {saving ? '…' : 'บันทึก'}
          </button>
        </div>
      </div>
    </div>
  );
};

// ── Add User Modal ─────────────────────────────────────────
const TITLES = ['นาง', 'น.ส.', 'นาย', 'ว่าที่ ร.ต.'];
const BENNER = ['Novice', 'Advanced Beginner', 'Competent', 'Proficient', 'Expert'];

function genPassword() {
  const chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789';
  return Array.from({ length: 8 }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
}

const CredentialCard = ({ name, email, password, onClose }) => {
  const [copied, setCopied] = useState(false);
  const text = `ชื่อผู้ใช้ (อีเมล): ${email}\nรหัสผ่าน: ${password}`;
  const doCopy = () => {
    navigator.clipboard.writeText(text).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000); });
  };
  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.5)', zIndex: 9999, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{ background: 'var(--c-surface)', borderRadius: 16, padding: 32, width: 420, maxWidth: '95vw', boxShadow: '0 24px 64px rgba(0,0,0,.3)', textAlign: 'center' }}>
        <div style={{ fontSize: 40, marginBottom: 8 }}>✅</div>
        <h3 style={{ margin: '0 0 4px' }}>เพิ่มผู้ใช้งานสำเร็จ</h3>
        <div className="txt-sm muted" style={{ marginBottom: 20 }}>{name}</div>

        <div style={{ background: 'var(--c-bg)', border: '1.5px dashed var(--c-border)', borderRadius: 12, padding: '16px 20px', marginBottom: 16, textAlign: 'left' }}>
          <div className="txt-xs muted" style={{ marginBottom: 8, fontWeight: 600, letterSpacing: 1 }}>ข้อมูลเข้าสู่ระบบ</div>
          <div style={{ marginBottom: 8 }}>
            <div className="txt-xs muted">อีเมล (Username)</div>
            <div style={{ fontFamily: 'monospace', fontWeight: 700, fontSize: 14, marginTop: 2 }}>{email}</div>
          </div>
          <div>
            <div className="txt-xs muted">รหัสผ่าน (Password)</div>
            <div style={{ fontFamily: 'monospace', fontWeight: 700, fontSize: 18, letterSpacing: 3, marginTop: 2, color: 'var(--c-primary)' }}>{password}</div>
          </div>
        </div>

        <div className="txt-xs muted" style={{ marginBottom: 16 }}>กรุณาแจ้งข้อมูลนี้ให้ผู้ใช้งานโดยตรง — ระบบไม่ส่งอีเมลอัตโนมัติ</div>

        <div className="flex" style={{ gap: 10, justifyContent: 'center' }}>
          <button className="btn-outline" onClick={doCopy} style={{ minWidth: 120 }}>
            {copied ? '✓ คัดลอกแล้ว' : '📋 คัดลอก'}
          </button>
          <button className="btn-primary" onClick={onClose} style={{ minWidth: 80 }}>ปิด</button>
        </div>
      </div>
    </div>
  );
};

const AddUserModal = ({ onClose, onSaved }) => {
  const [form, setForm] = useState({
    title: 'น.ส.', name: '', position: 'rn', years: 0, level: 'Competent',
    email: '', password: genPassword(), roles: ['supervisee'],
  });
  const [showPass, setShowPass] = useState(false);
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState('');
  const [credential, setCredential] = useState(null);

  const set = (k, v) => setForm(p => ({ ...p, [k]: v }));

  const toggleRole = (key) => {
    set('roles', form.roles.includes(key)
      ? form.roles.length > 1 ? form.roles.filter(k => k !== key) : form.roles
      : [...form.roles, key]
    );
  };

  const handleSave = async () => {
    if (!form.name.trim()) { setErr('กรุณากรอกชื่อ'); return; }
    if (!form.email.trim()) { setErr('กรุณากรอกอีเมล'); return; }
    if (form.password.trim().length < 4) { setErr('รหัสผ่านต้องมีอย่างน้อย 4 ตัวอักษร'); return; }
    setSaving(true); setErr('');
    try {
      const roleVal = form.roles.length === 1 ? form.roles[0] : JSON.stringify(form.roles);
      const created = await (window.DB.staff.create || window.DB.staff.add)({
        name: form.name.trim(), title: form.title,
        pos: form.position, years: Number(form.years),
        level: form.level, role: roleVal, email: form.email.trim(),
        password: form.password.trim(),
      });
      onSaved?.();
      setCredential({ name: form.title + form.name.trim(), email: form.email.trim(), password: form.password.trim() });
    } catch (e) {
      setErr(e.message || 'บันทึกไม่สำเร็จ');
      setSaving(false);
    }
  };

  if (credential) return <CredentialCard {...credential} onClose={onClose} />;

  const inputStyle = { width: '100%', padding: '8px 10px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-surface)', color: 'var(--c-ink)', fontSize: 13, boxSizing: 'border-box' };
  const labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--c-ink-muted)', marginBottom: 4 };

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.4)', zIndex: 9990, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{ background: 'var(--c-surface)', borderRadius: 14, padding: 28, width: 480, maxWidth: '95vw', maxHeight: '90vh', overflowY: 'auto', boxShadow: '0 20px 60px rgba(0,0,0,.25)' }}>
        <div className="flex" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
          <h3 style={{ margin: 0 }}>เพิ่มผู้ใช้งานใหม่</h3>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 20, lineHeight: 1 }}>×</button>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '80px 1fr', gap: 10, marginBottom: 14 }}>
          <div>
            <label style={labelStyle}>คำนำหน้า</label>
            <select value={form.title} onChange={e => set('title', e.target.value)} style={inputStyle}>
              {TITLES.map(t => <option key={t} value={t}>{t}</option>)}
            </select>
          </div>
          <div>
            <label style={labelStyle}>ชื่อ-นามสกุล *</label>
            <input value={form.name} onChange={e => set('name', e.target.value)} placeholder="เช่น สมใจ มีใจดี" style={inputStyle} />
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 14 }}>
          <div>
            <label style={labelStyle}>ตำแหน่ง</label>
            <select value={form.position} onChange={e => set('position', e.target.value)} style={inputStyle}>
              {Object.entries(D.POSITIONS || { rn: 'พยาบาลวิชาชีพ' }).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
            </select>
          </div>
          <div>
            <label style={labelStyle}>ประสบการณ์ (ปี)</label>
            <input type="number" min={0} max={40} value={form.years} onChange={e => set('years', e.target.value)} style={inputStyle} />
          </div>
        </div>

        <div style={{ marginBottom: 14 }}>
          <label style={labelStyle}>ระดับ Benner</label>
          <select value={form.level} onChange={e => set('level', e.target.value)} style={inputStyle}>
            {BENNER.map(b => <option key={b} value={b}>{b}</option>)}
          </select>
        </div>

        <div style={{ marginBottom: 14 }}>
          <label style={labelStyle}>อีเมล (ใช้เป็น Username เข้าสู่ระบบ) *</label>
          <input type="email" value={form.email} onChange={e => set('email', e.target.value)} placeholder="staff@sskh.go.th" style={inputStyle} />
        </div>

        <div style={{ marginBottom: 18 }}>
          <label style={labelStyle}>รหัสผ่านเริ่มต้น *</label>
          <div style={{ display: 'flex', gap: 6 }}>
            <div style={{ position: 'relative', flex: 1 }}>
              <input
                type={showPass ? 'text' : 'password'}
                value={form.password}
                onChange={e => set('password', e.target.value)}
                style={{ ...inputStyle, paddingRight: 36, fontFamily: showPass ? 'inherit' : 'monospace', letterSpacing: showPass ? 'normal' : 3 }}
              />
              <button
                type="button"
                onClick={() => setShowPass(v => !v)}
                style={{ position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 14 }}
              >{showPass ? '🙈' : '👁'}</button>
            </div>
            <button
              type="button"
              className="btn-outline"
              style={{ whiteSpace: 'nowrap', padding: '8px 12px', fontSize: 12 }}
              onClick={() => set('password', genPassword())}
            >🔀 สุ่มใหม่</button>
          </div>
          <div className="txt-xs muted" style={{ marginTop: 4 }}>ผู้ดูแลระบบสามารถแจ้งรหัสผ่านนี้ให้ผู้ใช้งานหลังสร้างบัญชี</div>
        </div>

        <div style={{ marginBottom: 18 }}>
          <label style={labelStyle}>บทบาท (เลือกได้หลายบทบาท) *</label>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, padding: '10px 12px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-bg)' }}>
            {USER_ROLES.map(r => (
              <label key={r.key} style={{ display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
                <input type="checkbox" checked={form.roles.includes(r.key)} onChange={() => toggleRole(r.key)} style={{ accentColor: r.color }} />
                <span style={{ fontSize: 12, fontWeight: 600, color: r.color, background: r.color + '15', padding: '3px 10px', borderRadius: 10, border: `1px solid ${r.color}33` }}>{r.label}</span>
              </label>
            ))}
          </div>
        </div>

        {err && <div className="txt-sm" style={{ color: 'var(--c-danger)', marginBottom: 12, background: 'var(--c-danger-soft)', padding: '8px 12px', borderRadius: 8 }}>{err}</div>}

        <div className="flex" style={{ gap: 10, justifyContent: 'flex-end' }}>
          <button className="btn-outline" onClick={onClose}>ยกเลิก</button>
          <button className="btn-primary" onClick={handleSave} disabled={saving}>
            {saving ? 'กำลังบันทึก…' : '+ เพิ่มผู้ใช้งาน'}
          </button>
        </div>
      </div>
    </div>
  );
};

// ── Task Assignments ──────────────────────────────────────────
const ASSIGNMENTS_KEY = 'lr_assignments';
function loadAssignments() {
  try { const s = localStorage.getItem(ASSIGNMENTS_KEY); if (s) return JSON.parse(s); } catch {}
  return [];
}
function saveAssignments(a) { localStorage.setItem(ASSIGNMENTS_KEY, JSON.stringify(a)); }

const PRIORITY_COLORS = { สูง: '#e53e3e', ปกติ: '#2b6cb0', ต่ำ: '#718096' };
const STATUS_LABELS   = { pending: 'รอดำเนินการ', inprogress: 'กำลังดำเนินการ', done: 'เสร็จแล้ว' };
const STATUS_COLORS   = { pending: '#d69e2e', inprogress: '#3182ce', done: '#38a169' };

const AssignTaskModal = ({ staffId, assignments, onSave, onClose }) => {
  const staff = D.STAFF.find(s => s.id === staffId);
  const myTasks = assignments.filter(a => a.staffId === staffId);
  const [adding, setAdding] = useState(false);
  const [form, setForm] = useState({ title: '', desc: '', due: '', priority: 'ปกติ' });
  const set = (k, v) => setForm(p => ({ ...p, [k]: v }));

  const handleAdd = () => {
    if (!form.title.trim()) return;
    onSave([...assignments, {
      id: Date.now().toString(), staffId,
      title: form.title.trim(), desc: form.desc.trim(),
      dueDate: form.due, priority: form.priority,
      status: 'pending', createdAt: new Date().toISOString(),
    }]);
    setForm({ title: '', desc: '', due: '', priority: 'ปกติ' });
    setAdding(false);
  };

  const cycleStatus = (id) => {
    const cycle = { pending: 'inprogress', inprogress: 'done', done: 'pending' };
    onSave(assignments.map(a => a.id === id ? { ...a, status: cycle[a.status] || 'pending' } : a));
  };

  const deleteTask = (id) => {
    if (!confirm('ลบงานนี้?')) return;
    onSave(assignments.filter(a => a.id !== id));
  };

  const inputStyle = { width: '100%', padding: '7px 10px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-surface)', color: 'var(--c-ink)', fontSize: 13, boxSizing: 'border-box' };
  const labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--c-ink-muted)', marginBottom: 4 };

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.45)', zIndex: 9990, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{ background: 'var(--c-surface)', borderRadius: 14, padding: 28, width: 520, maxWidth: '95vw', maxHeight: '90vh', overflowY: 'auto', boxShadow: '0 20px 60px rgba(0,0,0,.25)' }}>
        <div className="flex" style={{ justifyContent: 'space-between', marginBottom: 18, alignItems: 'flex-start' }}>
          <div style={{ flex: 1 }}>
            <h3 style={{ margin: 0, marginBottom: 8 }}>มอบหมายงาน</h3>
            {staff && (
              <div className="flex" style={{ gap: 8, alignItems: 'center' }}>
                <Avatar name={staff.name} size={28} />
                <div>
                  <div className="txt-sm" style={{ fontWeight: 600 }}>{staff.title}{staff.name}</div>
                  <div className="txt-xs muted">{D.POSITIONS[staff.pos]} · {staff.id}</div>
                </div>
              </div>
            )}
          </div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 22, lineHeight: 1, flexShrink: 0 }}>×</button>
        </div>

        <div style={{ marginBottom: 14 }}>
          {myTasks.length === 0 ? (
            <div className="empty" style={{ padding: '24px 0', fontSize: 13 }}>ยังไม่มีงานที่มอบหมาย</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {myTasks.map(task => (
                <div key={task.id} style={{
                  display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 14px',
                  border: '1px solid var(--c-border-soft)', borderRadius: 10,
                  background: task.status === 'done' ? 'var(--c-bg)' : 'var(--c-surface)',
                  opacity: task.status === 'done' ? 0.65 : 1, transition: 'opacity .2s',
                }}>
                  <button
                    onClick={() => cycleStatus(task.id)}
                    title="คลิกเปลี่ยนสถานะ"
                    style={{
                      width: 22, height: 22, borderRadius: '50%', flexShrink: 0, marginTop: 2,
                      border: `2px solid ${STATUS_COLORS[task.status]}`,
                      background: task.status === 'done' ? STATUS_COLORS.done : 'transparent',
                      cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
                      color: '#fff', fontSize: 11, fontWeight: 700,
                    }}
                  >{task.status === 'done' ? '✓' : task.status === 'inprogress' ? '▶' : ''}</button>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="txt-sm" style={{ fontWeight: 600, textDecoration: task.status === 'done' ? 'line-through' : 'none', color: task.status === 'done' ? 'var(--c-ink-muted)' : 'var(--c-ink)' }}>{task.title}</div>
                    {task.desc && <div className="txt-xs muted" style={{ marginTop: 2 }}>{task.desc}</div>}
                    <div className="flex" style={{ gap: 6, marginTop: 5, flexWrap: 'wrap', alignItems: 'center' }}>
                      <span style={{ fontSize: 11, fontWeight: 700, color: PRIORITY_COLORS[task.priority] || '#718096', background: (PRIORITY_COLORS[task.priority] || '#718096') + '18', padding: '1px 8px', borderRadius: 8 }}>
                        {task.priority === 'สูง' ? '▲' : task.priority === 'ต่ำ' ? '▼' : '●'} {task.priority}
                      </span>
                      {task.dueDate && <span style={{ fontSize: 11, color: 'var(--c-ink-muted)' }}>กำหนด {task.dueDate}</span>}
                      <span style={{ fontSize: 11, color: STATUS_COLORS[task.status], background: STATUS_COLORS[task.status] + '18', padding: '1px 8px', borderRadius: 8 }}>{STATUS_LABELS[task.status]}</span>
                    </div>
                  </div>
                  <button onClick={() => deleteTask(task.id)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', padding: '2px 4px', flexShrink: 0, fontSize: 16 }}>✕</button>
                </div>
              ))}
            </div>
          )}
        </div>

        {!adding ? (
          <button className="btn-outline txt-sm" style={{ width: '100%', padding: '9px', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, borderStyle: 'dashed' }} onClick={() => setAdding(true)}>
            <Icon name="plus" size={13} /> เพิ่มงานใหม่
          </button>
        ) : (
          <div style={{ border: '1px solid var(--c-primary)', borderRadius: 10, padding: 16 }}>
            <div style={{ marginBottom: 10 }}>
              <label style={labelStyle}>ชื่องาน / ภารกิจ *</label>
              <input value={form.title} onChange={e => set('title', e.target.value)} placeholder="เช่น ทบทวน Protocol การช่วยคลอด" style={inputStyle} autoFocus />
            </div>
            <div style={{ marginBottom: 10 }}>
              <label style={labelStyle}>รายละเอียด</label>
              <input value={form.desc} onChange={e => set('desc', e.target.value)} placeholder="เพิ่มเติม (ไม่บังคับ)" style={inputStyle} />
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 14 }}>
              <div>
                <label style={labelStyle}>วันที่กำหนดเสร็จ</label>
                <input type="date" value={form.due} onChange={e => set('due', e.target.value)} style={inputStyle} />
              </div>
              <div>
                <label style={labelStyle}>ความสำคัญ</label>
                <select value={form.priority} onChange={e => set('priority', e.target.value)} style={inputStyle}>
                  <option value="สูง">▲ สูง</option>
                  <option value="ปกติ">● ปกติ</option>
                  <option value="ต่ำ">▼ ต่ำ</option>
                </select>
              </div>
            </div>
            <div className="flex" style={{ gap: 8, justifyContent: 'flex-end' }}>
              <button className="btn-outline txt-xs" style={{ padding: '6px 14px' }} onClick={() => { setAdding(false); setForm({ title: '', desc: '', due: '', priority: 'ปกติ' }); }}>ยกเลิก</button>
              <button className="btn-primary txt-xs" style={{ padding: '6px 16px' }} onClick={handleAdd} disabled={!form.title.trim()}>+ เพิ่มงาน</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

const MATRIX_KEY = 'lr_access_matrix';
function loadMatrix() {
  try { const s = localStorage.getItem(MATRIX_KEY); if (s) return JSON.parse(s); } catch {}
  return ACCESS_MATRIX.map(r => ({ ...r }));
}
function saveMatrix(m) { localStorage.setItem(MATRIX_KEY, JSON.stringify(m)); }

const ResetPasswordModal = ({ staffId, onClose }) => {
  const staff = D.staffById(staffId);
  const [password, setPassword] = useState(genPassword);
  const [showPass, setShowPass] = useState(true);
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState('');
  const [done, setDone] = useState(false);
  const [copied, setCopied] = useState(false);

  const handleReset = async () => {
    if (password.trim().length < 4) { setErr('รหัสผ่านต้องมีอย่างน้อย 4 ตัวอักษร'); return; }
    setSaving(true); setErr('');
    try {
      await window.DB.staff.resetPassword(staffId, password.trim());
      setDone(true);
    } catch (e) {
      setErr(e.message || 'รีเซ็ตไม่สำเร็จ');
      setSaving(false);
    }
  };

  const doCopy = () => {
    const text = `ชื่อผู้ใช้ (อีเมล): ${staff?.email || ''}\nรหัสผ่านใหม่: ${password.trim()}`;
    navigator.clipboard.writeText(text).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000); });
  };

  const inputStyle = { width: '100%', padding: '8px 10px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-surface)', color: 'var(--c-ink)', fontSize: 14, boxSizing: 'border-box', fontFamily: 'monospace', letterSpacing: 2 };

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.45)', zIndex: 9995, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{ background: 'var(--c-surface)', borderRadius: 14, padding: 28, width: 420, maxWidth: '95vw', boxShadow: '0 20px 60px rgba(0,0,0,.25)' }}>
        {!done ? (
          <>
            <div className="flex" style={{ justifyContent: 'space-between', marginBottom: 18 }}>
              <h3 style={{ margin: 0 }}>🔑 รีเซ็ตรหัสผ่าน</h3>
              <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 20 }}>×</button>
            </div>
            <div className="txt-sm" style={{ marginBottom: 16 }}>
              <strong>{staff?.title}{staff?.name}</strong>
              <span className="muted" style={{ marginLeft: 8, fontSize: 12 }}>{staff?.email}</span>
            </div>
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--c-ink-muted)', marginBottom: 6 }}>รหัสผ่านใหม่</label>
              <div style={{ display: 'flex', gap: 6 }}>
                <div style={{ position: 'relative', flex: 1 }}>
                  <input
                    type={showPass ? 'text' : 'password'}
                    value={password}
                    onChange={e => setPassword(e.target.value)}
                    style={{ ...inputStyle, paddingRight: 36 }}
                  />
                  <button type="button" onClick={() => setShowPass(v => !v)}
                    style={{ position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', cursor: 'pointer', color: 'var(--c-ink-muted)', fontSize: 14 }}>
                    {showPass ? '🙈' : '👁'}
                  </button>
                </div>
                <button type="button" className="btn-outline" style={{ whiteSpace: 'nowrap', padding: '8px 12px', fontSize: 12 }} onClick={() => setPassword(genPassword())}>🔀</button>
              </div>
            </div>
            {err && <div className="txt-sm" style={{ color: 'var(--c-danger)', marginBottom: 12, background: 'var(--c-danger-soft)', padding: '8px 12px', borderRadius: 8 }}>{err}</div>}
            <div className="flex" style={{ gap: 10, justifyContent: 'flex-end' }}>
              <button className="btn-outline" onClick={onClose}>ยกเลิก</button>
              <button className="btn-primary" onClick={handleReset} disabled={saving}>{saving ? 'กำลังบันทึก…' : 'รีเซ็ตรหัสผ่าน'}</button>
            </div>
          </>
        ) : (
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 36, marginBottom: 8 }}>✅</div>
            <h3 style={{ margin: '0 0 4px' }}>รีเซ็ตสำเร็จ</h3>
            <div className="txt-sm muted" style={{ marginBottom: 20 }}>{staff?.title}{staff?.name}</div>
            <div style={{ background: 'var(--c-bg)', border: '1.5px dashed var(--c-border)', borderRadius: 12, padding: '14px 18px', marginBottom: 16, textAlign: 'left' }}>
              <div className="txt-xs muted" style={{ marginBottom: 6, fontWeight: 600 }}>รหัสผ่านใหม่</div>
              <div style={{ fontFamily: 'monospace', fontWeight: 700, fontSize: 22, letterSpacing: 4, color: 'var(--c-primary)' }}>{password.trim()}</div>
              {staff?.email && <div className="txt-xs muted" style={{ marginTop: 6 }}>อีเมล: {staff.email}</div>}
            </div>
            <div className="flex" style={{ gap: 10, justifyContent: 'center' }}>
              <button className="btn-outline" onClick={doCopy} style={{ minWidth: 120 }}>{copied ? '✓ คัดลอกแล้ว' : '📋 คัดลอก'}</button>
              <button className="btn-primary" onClick={onClose} style={{ minWidth: 80 }}>ปิด</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

const UserManagement = () => {
  const [, force] = useState(0);
  useEffect(() => window.LR_STAFF_STORE?.subscribe(() => force(n => n + 1)), []);
  const [tab, setTab] = useState('users');
  const [search, setSearch] = useState('');
  const [popover, setPopover] = useState(null); // { staffId, currentRole }
  const [addOpen, setAddOpen] = useState(false);
  const [resetModal, setResetModal] = useState(null); // staffId
  const [matrix, setMatrix] = useState(loadMatrix);
  const [matrixDirty, setMatrixDirty] = useState(false);
  const [assignments, setAssignments] = useState(loadAssignments);
  const [assignModal, setAssignModal] = useState(null);

  const handleSaveAssignments = (updated) => {
    setAssignments(updated);
    saveAssignments(updated);
  };

  const toggleCell = (pageIdx, roleKey) => {
    setMatrix(prev => {
      const next = prev.map((row, i) => i === pageIdx ? { ...row, [roleKey]: !row[roleKey] } : row);
      saveMatrix(next);
      return next;
    });
    setMatrixDirty(true);
  };

  const resetMatrix = () => {
    const def = ACCESS_MATRIX.map(r => ({ ...r }));
    setMatrix(def);
    saveMatrix(def);
    setMatrixDirty(false);
  };

  const filtered = D.STAFF.filter(s =>
    !search || s.name.toLowerCase().includes(search.toLowerCase())
  );

  // Count staff that include each role in their role list
  const countByRole = {};
  USER_ROLES.forEach(r => {
    countByRole[r.key] = D.STAFF.filter(s => {
      const roles = window.parseRoles ? window.parseRoles(s.role) : [s.role];
      return roles.includes(r.key);
    }).length;
  });

  return (
    <div className="page">
      <div className="section-h">
        <div>
          <h2>บริหารจัดการผู้ใช้งาน</h2>
          <div className="sub">กำหนดบทบาทและสิทธิ์การเข้าถึงสำหรับบุคลากรแต่ละระดับ</div>
        </div>
        <div className="flex" style={{ gap: 10 }}>
          <div className="tabs">
            <button className={`tab ${tab==='users'?'active':''}`} onClick={() => setTab('users')}>รายชื่อผู้ใช้</button>
            <button className={`tab ${tab==='matrix'?'active':''}`} onClick={() => setTab('matrix')}>ตารางสิทธิ์</button>
            <button className={`tab ${tab==='assign'?'active':''}`} onClick={() => setTab('assign')}>
              มอบหมายงาน
              {assignments.filter(a => a.status !== 'done').length > 0 && (
                <span style={{ marginLeft: 5, background: 'var(--c-primary)', color: '#fff', borderRadius: 10, padding: '1px 6px', fontSize: 10, fontWeight: 700 }}>
                  {assignments.filter(a => a.status !== 'done').length}
                </span>
              )}
            </button>
          </div>
          <button className="btn-primary" style={{ display: 'flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap' }} onClick={() => setAddOpen(true)}>
            <Icon name="plus" size={14} /> เพิ่มผู้ใช้งาน
          </button>
        </div>
      </div>

      {/* Role summary KPIs */}
      <div className="kpi-row" style={{ marginBottom: 16 }}>
        {USER_ROLES.map(r => (
          <div key={r.key} className="kpi">
            <div className="label" style={{ color: r.color, fontWeight: 600 }}>{r.label}</div>
            <div className="value" style={{ color: r.color }}>{countByRole[r.key] || 0}</div>
            <div className="delta muted" style={{ fontSize: 11 }}>{r.desc}</div>
          </div>
        ))}
      </div>

      {tab === 'users' ? (
        <div className="card">
          <div className="card-header">
            <h3>รายชื่อบุคลากรและบทบาท</h3>
            <div style={{ marginLeft: 'auto', position: 'relative' }}>
              <input
                value={search} onChange={e => setSearch(e.target.value)}
                placeholder="ค้นหาชื่อ..."
                style={{ padding: '7px 12px 7px 30px', border: '1px solid var(--c-border)', borderRadius: 8, background: 'var(--c-surface)', color: 'var(--c-ink)', width: 180, fontSize: 13 }}
              />
              <span style={{ position: 'absolute', left: 8, top: '50%', transform: 'translateY(-50%)', color: 'var(--c-ink-muted)', pointerEvents: 'none' }}>
                <Icon name="search" size={14} />
              </span>
            </div>
          </div>
          <div className="card-body" style={{ padding: 0 }}>
            <table className="t">
              <thead>
                <tr>
                  <th>ชื่อ-สกุล</th>
                  <th>ตำแหน่ง</th>
                  <th>อีเมล</th>
                  <th>บทบาทปัจจุบัน</th>
                  <th style={{ width: 220 }}></th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(s => (
                  <tr key={s.id}>
                    <td>
                      <div className="flex">
                        <Avatar name={s.name} size={28} />
                        <div>
                          <strong className="txt-sm">{s.title}{s.name}</strong>
                          <div className="txt-xs muted mono">{s.id}</div>
                        </div>
                      </div>
                    </td>
                    <td className="txt-sm">{D.POSITIONS[s.pos]}</td>
                    <td className="txt-xs muted">{s.email || '—'}</td>
                    <td><RoleBadge roleKey={s.role} /></td>
                    <td>
                      <div className="flex" style={{ gap: 6 }}>
                        <button
                          className="btn-outline txt-xs"
                          style={{ padding: '5px 10px', whiteSpace: 'nowrap', display: 'flex', alignItems: 'center', gap: 5 }}
                          onClick={() => setAssignModal(s.id)}
                        >
                          มอบหมายงาน
                          {assignments.filter(a => a.staffId === s.id && a.status !== 'done').length > 0 && (
                            <span style={{ background: 'var(--c-primary)', color: '#fff', borderRadius: 10, padding: '0 5px', fontSize: 10, fontWeight: 700, minWidth: 16, textAlign: 'center' }}>
                              {assignments.filter(a => a.staffId === s.id && a.status !== 'done').length}
                            </span>
                          )}
                        </button>
                        <button
                          className="btn-outline txt-xs"
                          style={{ padding: '5px 10px', whiteSpace: 'nowrap' }}
                          onClick={() => setPopover({ staffId: s.id, currentRole: s.role })}
                        >
                          บทบาท
                        </button>
                        <button
                          className="btn-outline txt-xs"
                          style={{ padding: '5px 10px', whiteSpace: 'nowrap', color: 'var(--c-warning, #d69e2e)', borderColor: 'var(--c-warning, #d69e2e)' }}
                          onClick={() => setResetModal(s.id)}
                        >
                          🔑 รหัสผ่าน
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      ) : tab === 'matrix' ? (
        /* Permissions matrix tab */
        <div className="card">
          <div className="card-header">
            <h3>ตารางสิทธิ์การเข้าถึงตามบทบาท</h3>
            <div className="flex" style={{ gap: 8, marginLeft: 'auto', alignItems: 'center' }}>
              {matrixDirty && (
                <span className="txt-xs" style={{ color: 'var(--c-primary)', background: 'var(--c-primary-soft)', padding: '3px 10px', borderRadius: 10 }}>
                  บันทึกอัตโนมัติแล้ว ✓
                </span>
              )}
              <button className="btn-outline txt-xs" style={{ padding: '5px 14px' }} onClick={resetMatrix}>
                รีเซ็ตค่าเริ่มต้น
              </button>
            </div>
          </div>
          <div className="card-body" style={{ padding: 0, overflowX: 'auto' }}>
            <table className="t" style={{ minWidth: 600 }}>
              <thead>
                <tr>
                  <th style={{ minWidth: 160 }}>เมนู / ฟีเจอร์</th>
                  {USER_ROLES.map(r => (
                    <th key={r.key} style={{ textAlign: 'center', minWidth: 110 }}>
                      <div style={{ color: r.color, fontWeight: 700, fontSize: 12 }}>{r.label}</div>
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {matrix.map((row, pageIdx) => (
                  <tr key={row.page}>
                    <td><strong className="txt-sm">{row.page}</strong></td>
                    {USER_ROLES.map(r => (
                      <td key={r.key} style={{ textAlign: 'center', padding: '8px 4px' }}>
                        <button
                          onClick={() => toggleCell(pageIdx, r.key)}
                          title={row[r.key] ? 'คลิกเพื่อลบสิทธิ์' : 'คลิกเพื่อให้สิทธิ์'}
                          style={{
                            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                            width: 28, height: 28, borderRadius: '50%', border: 'none',
                            cursor: 'pointer', transition: 'all .15s',
                            background: row[r.key] ? r.color + '22' : 'transparent',
                            color: row[r.key] ? r.color : 'var(--c-ink-muted)',
                            outline: row[r.key] ? `1.5px solid ${r.color}55` : '1.5px dashed var(--c-border)',
                            fontSize: row[r.key] ? 14 : 18, fontWeight: 700,
                          }}
                        >
                          {row[r.key] ? '✓' : '—'}
                        </button>
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="card-body" style={{ paddingTop: 12, borderTop: '1px solid var(--c-border-soft)' }}>
            <div className="txt-xs muted" style={{ marginBottom: 6, fontWeight: 600 }}>คลิกช่องเพื่อเปิด/ปิดสิทธิ์ · บันทึกอัตโนมัติ</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginTop: 8 }}>
              {USER_ROLES.map(r => (
                <div key={r.key} className="flex" style={{ gap: 10, alignItems: 'flex-start' }}>
                  <RoleBadge roleKey={r.key} />
                  <span className="txt-xs muted">{r.desc}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      ) : (
        /* Assignment tab */
        <div className="card">
          <div className="card-header">
            <h3>ภาพรวมการมอบหมายงาน</h3>
            <div className="flex" style={{ gap: 10, marginLeft: 'auto', alignItems: 'center' }}>
              <span className="txt-xs muted">{assignments.length} รายการทั้งหมด · เสร็จแล้ว {assignments.filter(a => a.status === 'done').length}</span>
            </div>
          </div>
          <div className="card-body" style={{ padding: 0, overflowX: 'auto' }}>
            {assignments.length === 0 ? (
              <div className="empty" style={{ padding: 48 }}>ยังไม่มีการมอบหมายงาน · กดปุ่ม "มอบหมายงาน" ที่รายชื่อบุคลากร</div>
            ) : (
              <table className="t">
                <thead>
                  <tr>
                    <th>บุคลากร</th>
                    <th>งาน / ภารกิจ</th>
                    <th>ความสำคัญ</th>
                    <th>กำหนดเสร็จ</th>
                    <th>สถานะ</th>
                    <th style={{ width: 80 }}></th>
                  </tr>
                </thead>
                <tbody>
                  {assignments.map(task => {
                    const s = D.STAFF.find(x => x.id === task.staffId);
                    return (
                      <tr key={task.id} style={{ opacity: task.status === 'done' ? 0.55 : 1 }}>
                        <td>
                          {s ? (
                            <div className="flex">
                              <Avatar name={s.name} size={24} />
                              <span className="txt-sm">{s.title}{s.name}</span>
                            </div>
                          ) : <span className="muted txt-xs">{task.staffId}</span>}
                        </td>
                        <td>
                          <div className="txt-sm" style={{ fontWeight: 600, textDecoration: task.status === 'done' ? 'line-through' : 'none' }}>{task.title}</div>
                          {task.desc && <div className="txt-xs muted">{task.desc}</div>}
                        </td>
                        <td>
                          <span style={{ fontSize: 11, fontWeight: 700, color: PRIORITY_COLORS[task.priority] || '#718096', background: (PRIORITY_COLORS[task.priority] || '#718096') + '18', padding: '2px 8px', borderRadius: 8 }}>
                            {task.priority === 'สูง' ? '▲' : task.priority === 'ต่ำ' ? '▼' : '●'} {task.priority}
                          </span>
                        </td>
                        <td className="txt-xs muted">{task.dueDate || '—'}</td>
                        <td>
                          <span style={{ fontSize: 11, color: STATUS_COLORS[task.status], background: STATUS_COLORS[task.status] + '18', padding: '2px 8px', borderRadius: 8 }}>
                            {STATUS_LABELS[task.status]}
                          </span>
                        </td>
                        <td>
                          <button className="btn-outline txt-xs" style={{ padding: '4px 10px' }} onClick={() => setAssignModal(task.staffId)}>จัดการ</button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            )}
          </div>
        </div>
      )}

      {popover && (
        <RolePopover
          staffId={popover.staffId}
          currentRole={popover.currentRole}
          onClose={() => setPopover(null)}
        />
      )}
      {addOpen && <AddUserModal onClose={() => setAddOpen(false)} onSaved={() => force(n => n + 1)} />}
      {resetModal && <ResetPasswordModal staffId={resetModal} onClose={() => setResetModal(null)} />}
      {assignModal && (
        <AssignTaskModal
          staffId={assignModal}
          assignments={assignments}
          onSave={handleSaveAssignments}
          onClose={() => setAssignModal(null)}
        />
      )}
    </div>
  );
};

// ===================== Settings (placeholder) =====================
const Settings = () => (
  <div className="page">
    <div className="section-h">
      <div>
        <h2>ตั้งค่าระบบ</h2>
        <div className="sub">การจัดการสิทธิ์ บัญชี และการตั้งค่าทั่วไป</div>
      </div>
    </div>
    <div className="empty card" style={{ padding: 60 }}>
      หน้านี้สำหรับ Admin · ลองเปลี่ยน Tweaks ด้านขวาเพื่อทดสอบ Theme/Font ⚙
    </div>
  </div>
);

Object.assign(window, { CaseReview, Analytics, SuperviseeDashboard, Settings, UserManagement });
