/* ======================================================
   Executive dashboard — analytics & risk monitoring
====================================================== */

function CollegeOverview({ onDrillIn }) {
  const { PROGRAMS, COLLEGE_STATS } = window.VRP_DATA;
  const [hoverMajor, setHoverMajor] = useState(null);

  // Overall avg / att across all majors (weighted by student count)
  const totals = useMemo(() => {
    let sw = 0, attw = 0, pop = 0, risk = 0;
    Object.values(PROGRAMS).forEach(p => p.categories.forEach(c => c.majors.forEach(m => {
      sw += m.avg * m.students; attw += m.att * m.students; pop += m.students; risk += m.risk;
    })));
    return { avg: sw / pop, att: attw / pop, pop, risk };
  }, []);

  return (
    <div className="fade-in">
      {/* Hero */}
      <div className="hero-card" style={{ marginBottom: 18 }}>
        <div>
          <div className="eyebrow">ระบบบริหารวิทยาลัย · ภาพรวมทั้งสถาบัน</div>
          <h2>วิทยาลัยเทคโนโลยีวีรพัฒน์</h2>
          <p>ภาพรวมการจัดการศึกษา 2 ระดับ · 4 ประเภทวิชา · {COLLEGE_STATS.majors} สาขาวิชา ตลอดภาคการศึกษาที่ 1/2569 พร้อมระบบติดตามคุณภาพและกลุ่มเสี่ยงในทุกสาขา</p>
          <div className="hero-stats">
            <div className="hero-stat"><b><AnimNum value={COLLEGE_STATS.students} /></b><small>นักศึกษาทั้งหมด</small></div>
            <div className="hero-stat"><b><AnimNum value={COLLEGE_STATS.majors} /></b><small>สาขาวิชา</small></div>
            <div className="hero-stat"><b><AnimNum value={COLLEGE_STATS.classes} /></b><small>ห้องเรียน</small></div>
          </div>
        </div>
        <div style={{ display:'grid', placeItems:'center' }}>
          <Donut value={1 - totals.risk / totals.pop}
                 label={Math.round((1 - totals.risk / totals.pop) * 100) + "%"}
                 sub={"ปลอดภัย · " + totals.risk + " เสี่ยง"} size={170} thickness={16}/>
        </div>
      </div>

      {/* Stat strip */}
      <div className="stat-grid" style={{ marginBottom: 18 }}>
        <Stat label="คะแนนเฉลี่ยรวม" value={Number(totals.avg.toFixed(1))} suffix="/100" accent="var(--magenta)"
              sub="ถ่วงน้ำหนักตามจำนวนผู้เรียน"/>
        <Stat label="เข้าเรียนเฉลี่ย" value={Number(totals.att.toFixed(1))} suffix="%" accent="var(--cyan)"
              trend={{ dir: "up", value: "+1.4 เทียบเทอมก่อน" }}/>
        <Stat label="ประเภทวิชา" value={COLLEGE_STATS.categories} accent="var(--lime)" sub="2 ระดับการศึกษา"/>
        <Stat label="กลุ่มเสี่ยงรวม" value={totals.risk} suffix="คน" accent="var(--bad)" trend={{ dir: "down", value: "ต้องช่วยเหลือ" }}/>
      </div>

      {/* Two-level breakdown */}
      {Object.values(PROGRAMS).map(level => (
        <div key={level.id} style={{ marginBottom: 22 }}>
          <div className="sec-title">
            <div style={{ display:'flex', alignItems:'baseline', gap: 12 }}>
              <h2 style={{ display:'flex', alignItems:'center', gap: 10 }}>
                <span style={{ display:'inline-block', width: 10, height: 28, borderRadius: 3, background: level.accent }}/>
                {level.label}
              </h2>
              <small>
                {level.categories.length} ประเภทวิชา · {level.categories.reduce((a, c) => a + c.majors.length, 0)} สาขา ·
                {" " + level.categories.reduce((a, c) => a + c.majors.reduce((b, m) => b + m.students, 0), 0)} คน
              </small>
            </div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))', gap: 14 }}>
            {level.categories.map(cat => {
              const popCat = cat.majors.reduce((a, m) => a + m.students, 0);
              const avgCat = cat.majors.reduce((a, m) => a + m.avg * m.students, 0) / popCat;
              const riskCat = cat.majors.reduce((a, m) => a + m.risk, 0);
              return (
                <div key={cat.id} className="card" style={{ padding: 18 }}>
                  <div style={{ display:'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
                    <span className="subj-dot" style={{ background: cat.color, width: 12, height: 12 }}/>
                    <div style={{ flex: 1, lineHeight: 1.2, minWidth: 0 }}>
                      <div style={{ fontWeight: 600, fontSize: 13.5 }}>{cat.name}</div>
                      <div className="dim" style={{ fontSize: 11 }}>{cat.majors.length} สาขา · {popCat} คน · เฉลี่ย {avgCat.toFixed(1)}</div>
                    </div>
                    {riskCat > 0 && <span className="pill bad"><Icon.alert width={10} height={10}/> {riskCat}</span>}
                  </div>

                  <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                    {cat.majors.map(m => {
                      const isActive = m.active;
                      const isHover = hoverMajor === m.id;
                      return (
                        <button key={m.id}
                          onMouseEnter={() => setHoverMajor(m.id)}
                          onMouseLeave={() => setHoverMajor(null)}
                          onClick={() => isActive && onDrillIn && onDrillIn()}
                          style={{
                            display: 'grid', gridTemplateColumns: '36px 1fr auto auto', gap: 12, alignItems: 'center',
                            padding: '10px 12px', borderRadius: 12,
                            background: isHover ? 'color-mix(in oklab, white 5%, transparent)' : 'transparent',
                            border: '1px solid ' + (isActive ? 'color-mix(in oklab, ' + cat.color + ' 50%, transparent)' : 'var(--line)'),
                            cursor: isActive ? 'pointer' : 'default',
                            textAlign: 'left', color: 'var(--fg-0)', font: 'inherit', fontFamily: 'var(--font-thai)',
                            transition: '.18s', position: 'relative',
                          }}>
                          <div style={{ width: 36, height: 36, borderRadius: 9, background: `linear-gradient(135deg, ${cat.color}, oklch(0.6 0.18 280))`,
                                        display: 'grid', placeItems: 'center', color: 'white', fontWeight: 800, fontFamily: 'var(--font-sans)', fontSize: 11, letterSpacing: '.05em' }}>
                            {m.short}
                          </div>
                          <div style={{ minWidth: 0, lineHeight: 1.2 }}>
                            <div style={{ fontSize: 13, fontWeight: 500, display: 'flex', alignItems: 'center', gap: 8 }}>
                              {m.name}
                              {isActive && <span className="pill" style={{ background: 'color-mix(in oklab, var(--lime) 22%, transparent)', color: 'var(--lime)', fontSize: 10 }}>เปิดสอนอยู่</span>}
                            </div>
                            <div className="dim" style={{ fontSize: 11 }}>{m.students} คน · {m.classes} ห้อง</div>
                          </div>
                          <div style={{ textAlign: 'right', minWidth: 70 }}>
                            <div className="num" style={{ fontSize: 14, fontWeight: 700 }}>{m.avg.toFixed(1)}</div>
                            <div className="dim" style={{ fontSize: 10 }}>คะแนน</div>
                          </div>
                          <div style={{ textAlign: 'right', minWidth: 54 }}>
                            <div className="num" style={{ fontSize: 14, fontWeight: 700, color: m.att >= 90 ? 'var(--good)' : m.att >= 85 ? 'var(--warn)' : 'var(--bad)' }}>{m.att}%</div>
                            <div className="dim" style={{ fontSize: 10 }}>เข้าเรียน</div>
                          </div>
                          {isActive && (
                            <Icon.arrow width={14} height={14} style={{ position: 'absolute', right: -22, top: '50%', transform: 'translateY(-50%)', color: cat.color, opacity: isHover ? 1 : 0, transition: '.18s' }}/>
                          )}
                        </button>
                      );
                    })}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      ))}

      <div className="card" style={{ padding: 16, display:'flex', alignItems: 'center', gap: 12, background: 'color-mix(in oklab, var(--magenta) 8%, transparent)' }}>
        <Icon.sparkle width={16} height={16} style={{ color: 'oklch(0.85 0.18 320)' }}/>
        <div style={{ fontSize: 12.5, color: 'var(--fg-1)' }}>
          คลิกที่สาขาที่มีป้าย <span className="pill" style={{ background: 'color-mix(in oklab, var(--lime) 22%, transparent)', color: 'var(--lime)', fontSize: 10 }}>เปิดสอนอยู่</span> เพื่อดูข้อมูลเชิงลึก (ภาคการศึกษานี้กำลังเปิดข้อมูลเชิงลึกเฉพาะ เทคโนโลยีธุรกิจดิจิทัล ปวส.)
        </div>
      </div>
    </div>
  );
}

function TeacherDirectory({ offerings, data }) {
  const { TEACHERS, SUBJECTS, STUDENTS } = window.VRP_DATA;
  const [selected, setSelected] = useState(TEACHERS[0].id);
  const [query, setQuery] = useState("");

  // Build per-teacher stats from offerings
  const teacherStats = useMemo(() => {
    return TEACHERS.map(t => {
      const mine = offerings.filter(o => o.teacherId === t.id);
      const credits = mine.reduce((a, o) => a + o.credits, 0);
      const students = mine.reduce((a, o) => a + o.students, 0);
      const majors = new Set(mine.map(o => o.majorId)).size;
      // If teacher teaches any of the 9 active DBT subjects, compute real avg from DATA
      const activeSubs = mine.filter(o => SUBJECTS.find(s => s.th === o.name || s.id === o.code));
      let realAvg = null, realAtt = null, realRisk = 0;
      if (activeSubs.length > 0) {
        const matched = activeSubs.map(o => SUBJECTS.find(s => s.th === o.name)).filter(Boolean);
        let totalSum = 0, attSum = 0, count = 0;
        STUDENTS.forEach(st => matched.forEach(sub => {
          const r = data[st.id][sub.id];
          totalSum += totalScore(r.scores);
          attSum += attendanceRate(r.attendance);
          count++;
        }));
        if (count > 0) {
          realAvg = totalSum / count;
          realAtt = attSum / count;
          realRisk = STUDENTS.filter(st => matched.some(sub => totalScore(data[st.id][sub.id].scores) < 50)).length;
        }
      }
      return { teacher: t, offerings: mine, credits, students, majors, realAvg, realAtt, realRisk };
    });
  }, [offerings, data]);

  const filtered = teacherStats.filter(s => {
    if (!query) return true;
    const q = query.toLowerCase();
    return s.teacher.name.toLowerCase().includes(q) ||
           s.teacher.spec.toLowerCase().includes(q) ||
           s.teacher.email.toLowerCase().includes(q);
  });

  const sel = teacherStats.find(s => s.teacher.id === selected);
  const totals = useMemo(() => ({
    total: TEACHERS.length,
    avgLoad: (teacherStats.reduce((a, s) => a + s.credits, 0) / TEACHERS.length).toFixed(1),
    fullTime: teacherStats.filter(s => s.credits >= 9).length,
  }), [teacherStats]);

  return (
    <div className="fade-in">
      {/* Hero */}
      <div className="hero-card" style={{ marginBottom: 18 }}>
        <div>
          <div className="eyebrow">ทรัพยากรบุคคล · คณาจารย์</div>
          <h2>อาจารย์ผู้สอนในวิทยาลัย</h2>
          <p>ดูรายละเอียดอาจารย์แต่ละท่าน · ภาระการสอน รายวิชาที่รับผิดชอบ และผลการเรียนของนักศึกษาในความดูแล</p>
          <div className="hero-stats">
            <div className="hero-stat"><b><AnimNum value={totals.total}/></b><small>อาจารย์ทั้งหมด</small></div>
            <div className="hero-stat"><b><AnimNum value={Number(totals.avgLoad)} decimals={1}/></b><small>หน่วยกิตเฉลี่ย</small></div>
            <div className="hero-stat"><b><AnimNum value={totals.fullTime}/></b><small>เต็มภาระงาน</small></div>
          </div>
        </div>
        <div style={{ display:'grid', placeItems:'center' }}>
          {sel && <Avatar name={sel.teacher.name} seed={sel.teacher.avatar} size={140}/>}
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '320px 1fr', gap: 14, alignItems: 'start' }}>
        {/* List */}
        <div className="card" style={{ padding: 0, overflow: 'hidden', position: 'sticky', top: 0, maxHeight: 'calc(100vh - 220px)', display: 'flex', flexDirection: 'column' }}>
          <div style={{ padding: 14, borderBottom: '1px solid var(--line)' }}>
            <div style={{ position: 'relative' }}>
              <Icon.search width={14} height={14} style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--fg-3)' }}/>
              <input className="input" style={{ paddingLeft: 34 }} placeholder="ค้นหาอาจารย์ / ความเชี่ยวชาญ" value={query} onChange={e => setQuery(e.target.value)}/>
            </div>
          </div>
          <div style={{ overflowY: 'auto', flex: 1 }}>
            {filtered.map(s => {
              const active = s.teacher.id === selected;
              return (
                <button key={s.teacher.id} onClick={() => setSelected(s.teacher.id)}
                  style={{
                    width: '100%', display: 'grid', gridTemplateColumns: '36px 1fr auto', gap: 10,
                    alignItems: 'center', padding: '10px 14px', border: 0,
                    background: active ? 'linear-gradient(90deg, color-mix(in oklab, var(--magenta) 14%, transparent), transparent)' : 'transparent',
                    borderLeft: '2px solid ' + (active ? 'var(--magenta)' : 'transparent'),
                    color: 'var(--fg-0)', textAlign: 'left', cursor: 'pointer', fontFamily: 'var(--font-thai)',
                    transition: '.15s',
                  }}>
                  <Avatar name={s.teacher.name} seed={s.teacher.avatar} size={36}/>
                  <div style={{ minWidth: 0, lineHeight: 1.2 }}>
                    <div style={{ fontSize: 13, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{s.teacher.name}</div>
                    <div className="dim" style={{ fontSize: 11 }}>{s.offerings.length} รายวิชา · {s.credits} นก.</div>
                  </div>
                  <span className="pill info" style={{ fontSize: 10 }}>{s.teacher.spec}</span>
                </button>
              );
            })}
            {filtered.length === 0 && (
              <div style={{ padding: 30, textAlign: 'center', color: 'var(--fg-3)', fontSize: 13 }}>ไม่พบอาจารย์ที่ค้นหา</div>
            )}
          </div>
        </div>

        {/* Detail */}
        {sel && (
          <div className="fade-in" key={sel.teacher.id} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {/* Profile card */}
            <div className="card glow" style={{ padding: 22, display: 'grid', gridTemplateColumns: '88px 1fr auto', gap: 18, alignItems: 'center' }}>
              <Avatar name={sel.teacher.name} seed={sel.teacher.avatar} size={88}/>
              <div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
                  <h2 style={{ fontSize: 22 }}>{sel.teacher.name}</h2>
                  <span className="pill info">{sel.teacher.spec}</span>
                </div>
                <div className="muted" style={{ fontSize: 13, display: 'flex', gap: 16, flexWrap: 'wrap' }}>
                  <span className="eng">📧 {sel.teacher.email}</span>
                  <span>รหัส: <span className="eng mono">{sel.teacher.id}</span></span>
                  <span>สอนใน {sel.majors} สาขา</span>
                </div>
                <div style={{ display: 'flex', gap: 16, marginTop: 12 }}>
                  <div>
                    <div className="dim" style={{ fontSize: 10, letterSpacing: '.15em', textTransform: 'uppercase' }}>รายวิชา</div>
                    <div className="num" style={{ fontSize: 22, fontWeight: 700 }}>{sel.offerings.length}</div>
                  </div>
                  <div>
                    <div className="dim" style={{ fontSize: 10, letterSpacing: '.15em', textTransform: 'uppercase' }}>หน่วยกิต</div>
                    <div className="num" style={{ fontSize: 22, fontWeight: 700 }}>{sel.credits}</div>
                  </div>
                  <div>
                    <div className="dim" style={{ fontSize: 10, letterSpacing: '.15em', textTransform: 'uppercase' }}>นักศึกษาในความดูแล</div>
                    <div className="num" style={{ fontSize: 22, fontWeight: 700 }}>{sel.students}</div>
                  </div>
                  {sel.realAvg !== null && (
                    <>
                      <div style={{ width: 1, background: 'var(--line)' }}/>
                      <div>
                        <div className="dim" style={{ fontSize: 10, letterSpacing: '.15em', textTransform: 'uppercase' }}>คะแนนเฉลี่ย (ปวส. DBT)</div>
                        <div className="num" style={{ fontSize: 22, fontWeight: 700, color: sel.realAvg >= 70 ? 'var(--good)' : sel.realAvg >= 60 ? 'var(--warn)' : 'var(--bad)' }}>{sel.realAvg.toFixed(1)}</div>
                      </div>
                      <div>
                        <div className="dim" style={{ fontSize: 10, letterSpacing: '.15em', textTransform: 'uppercase' }}>เข้าเรียนเฉลี่ย</div>
                        <div className="num" style={{ fontSize: 22, fontWeight: 700 }}>{Math.round(sel.realAtt * 100)}%</div>
                      </div>
                    </>
                  )}
                </div>
              </div>
              <div>
                <Donut value={Math.min(1, sel.credits / 18)}
                       label={sel.credits + ""} sub="ภาระงาน" size={120} thickness={12}/>
              </div>
            </div>

            {/* Workload bar */}
            <div className="card" style={{ padding: 18 }}>
              <div style={{ display:'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 10 }}>
                <h3>ภาระการสอน · ภาคเรียนปัจจุบัน</h3>
                <span className="dim" style={{ fontSize: 11 }}>เป้าหมาย 12–18 หน่วยกิต/ภาคเรียน</span>
              </div>
              <HBar value={sel.credits} max={24} color={sel.credits > 18 ? 'linear-gradient(90deg, oklch(0.7 0.22 30), oklch(0.65 0.24 25))' : 'var(--grad-hero)'}/>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6, fontSize: 11, color: 'var(--fg-3)' }}>
                <span>0</span><span className={sel.credits < 12 ? "" : "dim"}>12 (ต่ำสุด)</span><span className={sel.credits > 18 ? "" : "dim"}>18 (สูงสุด)</span><span>24</span>
              </div>
              {sel.credits > 18 && (
                <div style={{ marginTop: 10, padding: '8px 12px', borderRadius: 10, background: 'color-mix(in oklab, var(--bad) 14%, transparent)', fontSize: 12, color: 'oklch(0.85 0.12 25)', display: 'flex', gap: 8, alignItems: 'center' }}>
                  <Icon.alert width={14} height={14}/> ภาระงานเกินเกณฑ์ ควรปรับลดในภาคเรียนถัดไป
                </div>
              )}
              {sel.credits < 12 && (
                <div style={{ marginTop: 10, padding: '8px 12px', borderRadius: 10, background: 'color-mix(in oklab, var(--warn) 14%, transparent)', fontSize: 12, color: 'var(--warn)', display: 'flex', gap: 8, alignItems: 'center' }}>
                  <Icon.alert width={14} height={14}/> ภาระงานต่ำกว่าเกณฑ์ขั้นต่ำ
                </div>
              )}
            </div>

            {/* Subjects table */}
            <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
              <div style={{ padding: '14px 20px', borderBottom: '1px solid var(--line)', display:'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <h3>รายวิชาที่สอน</h3>
                <span className="dim" style={{ fontSize: 12 }}>{sel.offerings.length} รายวิชา</span>
              </div>
              {sel.offerings.length === 0 ? (
                <div style={{ padding: 40, textAlign: 'center', color: 'var(--fg-3)' }}>
                  ไม่ได้รับผิดชอบรายวิชาในภาคเรียนนี้
                </div>
              ) : (
                <table className="tbl">
                  <thead>
                    <tr>
                      <th>รหัส</th>
                      <th>รายวิชา</th>
                      <th>สาขา</th>
                      <th>ตารางเรียน</th>
                      <th style={{ textAlign: 'right' }}>นก.</th>
                      <th style={{ textAlign: 'right' }}>นศ.</th>
                    </tr>
                  </thead>
                  <tbody>
                    {sel.offerings.map(o => (
                      <tr key={o.id}>
                        <td className="eng mono" style={{ fontSize: 11, color: 'var(--fg-2)' }}>{o.code}</td>
                        <td style={{ fontSize: 13 }}>{o.name}</td>
                        <td>
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                            <span className="subj-dot" style={{ background: o.majorColor }}/>
                            <span style={{ fontSize: 12 }}>{o.levelCode} {o.majorName}</span>
                          </div>
                        </td>
                        <td style={{ fontSize: 12 }}>
                          <div>{o.schedule}</div>
                          <div className="dim eng" style={{ fontSize: 11 }}>{o.room}</div>
                        </td>
                        <td className="num" style={{ textAlign: 'right' }}>{o.credits}</td>
                        <td className="num" style={{ textAlign: 'right' }}>{o.students}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function ExecutiveDashboard({ data, riskScore, riskAttendance, setRiskScore, setRiskAttendance, view, setView, offerings }) {
  const { SUBJECTS, STUDENTS } = window.VRP_DATA;
  const [selectedSubject, setSelectedSubject] = useState("ALL");

  // Compute everything
  const dataset = useMemo(() => {
    const perStudent = STUDENTS.map(s => {
      const subjects = SUBJECTS.map(sub => {
        const r = data[s.id][sub.id];
        return { sub, total: totalScore(r.scores), att: attendanceRate(r.attendance), grade: grade(totalScore(r.scores)) };
      });
      const avgScore = subjects.reduce((a, x) => a + x.total, 0) / subjects.length;
      const avgAtt = subjects.reduce((a, x) => a + x.att, 0) / subjects.length;
      const gpa = subjects.reduce((a, x) => a + x.grade.gpa * x.sub.credits, 0) / subjects.reduce((a, x) => a + x.sub.credits, 0);
      const failed = subjects.filter(x => x.total < 50).length;
      return { student: s, subjects, avgScore, avgAtt, gpa, failed,
               atRisk: avgScore < riskScore || avgAtt < riskAttendance / 100 };
    });
    const perSubject = SUBJECTS.map(sub => {
      const rows = STUDENTS.map(s => ({ ...data[s.id][sub.id] }));
      const totals = rows.map(r => totalScore(r.scores));
      const atts = rows.map(r => attendanceRate(r.attendance));
      const avg = totals.reduce((a, b) => a + b, 0) / totals.length;
      const avgAtt = atts.reduce((a, b) => a + b, 0) / atts.length;
      const pass = totals.filter(t => t >= 50).length;
      const dist = { A: 0, "B+": 0, B: 0, "C+": 0, C: 0, "D+": 0, D: 0, F: 0 };
      totals.forEach(t => dist[grade(t).letter]++);
      return { sub, avg, avgAtt, pass, fail: totals.length - pass, dist };
    });

    return { perStudent, perSubject };
  }, [data, riskScore, riskAttendance]);

  const totalRisk = dataset.perStudent.filter(p => p.atRisk).length;
  const overallAvg = dataset.perSubject.reduce((a, s) => a + s.avg, 0) / dataset.perSubject.length;
  const overallAtt = dataset.perSubject.reduce((a, s) => a + s.avgAtt, 0) / dataset.perSubject.length;
  const overallPass = dataset.perSubject.reduce((a, s) => a + s.pass, 0) / (STUDENTS.length * SUBJECTS.length);

  return (
    <div className="fade-in">
      {view === "college" && <CollegeOverview onDrillIn={() => setView && setView("major")} />}
      {view === "teachers" && <TeacherDirectory offerings={offerings} data={data} />}
      {view === "major" && (
      <>
      {/* Hero */}
      <div className="hero-card" style={{ marginBottom: 18 }}>
        <div>
          <div className="eyebrow">เจาะรายสาขา · ปวส. เทคโนโลยีธุรกิจดิจิทัล · ชั้นปี 2</div>
          <h2>ภาคต้น 2569 · 9 รายวิชา · {STUDENTS.length} คน</h2>
          <p>วิเคราะห์ภาพรวมการเรียนของผู้เรียนทั้งระดับชั้น พร้อมระบบแจ้งเตือนนักศึกษากลุ่มเสี่ยงแบบเรียลไทม์ เพื่อให้คณาจารย์ช่วยเหลือได้ทันเวลา</p>
          <div style={{ display: 'flex', gap: 14, marginTop: 18, flexWrap: 'wrap' }}>
            <div style={{ display:'flex', alignItems:'center', gap: 8 }}>
              <Icon.alert width={16} height={16} style={{ color: 'oklch(0.82 0.17 70)' }}/>
              <div className="muted" style={{ fontSize: 12 }}>เกณฑ์เสี่ยง: คะแนนเฉลี่ย &lt; {riskScore} หรือเข้าเรียน &lt; {riskAttendance}%</div>
            </div>
          </div>
        </div>
        <div style={{ display:'grid', placeItems:'center' }}>
          <Donut
            value={1 - totalRisk / STUDENTS.length}
            label={STUDENTS.length - totalRisk + ""}
            sub={"ปลอดภัย · " + totalRisk + " เสี่ยง"} size={170} thickness={16}/>
        </div>
      </div>

      {/* Stat grid */}
      <div className="stat-grid" style={{ marginBottom: 18 }}>
        <Stat label="คะแนนเฉลี่ยรวม" value={Number(overallAvg.toFixed(1))} suffix="/100" accent="var(--magenta)"
              trend={{ dir: "up", value: "+2.3 เทียบเทอมก่อน" }}/>
        <Stat label="อัตราการเข้าเรียน" value={Number((overallAtt * 100).toFixed(1))} suffix="%" accent="var(--cyan)"
              trend={{ dir: overallAtt >= 0.85 ? "up" : "down", value: (overallAtt * 100).toFixed(1) + "% เฉลี่ย" }}/>
        <Stat label="ผ่านเกณฑ์" value={Number((overallPass * 100).toFixed(0))} suffix="%" accent="var(--lime)"
              sub={`${Math.round(overallPass * STUDENTS.length * SUBJECTS.length)} รายวิชา-ผู้เรียน`}/>
        <Stat label="กลุ่มเสี่ยง" value={totalRisk} suffix="คน" accent="var(--bad)"
              trend={{ dir: "down", value: totalRisk > 5 ? "ต้องเฝ้าระวัง" : "ดูแลใกล้ชิด" }}/>
      </div>

      {/* Per-subject analytics */}
      <div className="sec-title">
        <h2>ภาพรวมรายวิชา</h2>
        <small>คลิกเพื่อกรองรายชื่อนักศึกษาด้านล่าง</small>
      </div>
      <div className="grid-3" style={{ marginBottom: 18 }}>
        {dataset.perSubject.map(({ sub, avg, avgAtt, pass, fail, dist }) => {
          const isActive = selectedSubject === sub.id;
          return (
            <div key={sub.id} className="card" style={{ cursor: 'pointer', borderColor: isActive ? sub.color : undefined, boxShadow: isActive ? `0 0 0 1px ${sub.color}, 0 12px 30px -10px ${sub.color}` : undefined }}
                 onClick={() => setSelectedSubject(isActive ? "ALL" : sub.id)}>
              <div style={{ display:'flex', alignItems:'center', gap: 10, marginBottom: 10 }}>
                <span className="subj-dot" style={{ background: sub.color, width: 14, height: 14 }}/>
                <div style={{ flex: 1, lineHeight: 1.15, minWidth: 0 }}>
                  <div style={{ fontWeight: 600, fontSize: 13, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{sub.th}</div>
                  <div className="dim eng" style={{ fontSize: 11 }}>{sub.id} · {sub.en}</div>
                </div>
              </div>
              <div style={{ display:'flex', alignItems:'baseline', gap: 8, marginBottom: 4 }}>
                <span className="num" style={{ fontSize: 28, fontWeight: 700 }}>{avg.toFixed(1)}</span>
                <span className="dim" style={{ fontSize: 11 }}>คะแนนเฉลี่ย</span>
              </div>
              <HBar value={avg} color={`linear-gradient(90deg, ${sub.color}, oklch(0.75 0.18 220))`}/>
              <div style={{ display:'flex', justifyContent:'space-between', marginTop: 10, fontSize: 12 }}>
                <span className="muted">เข้าเรียน <b className="num" style={{ color: 'var(--fg-0)' }}>{(avgAtt * 100).toFixed(0)}%</b></span>
                <span className="muted">ผ่าน <b className="num" style={{ color: 'var(--good)' }}>{pass}</b> / <b className="num" style={{ color: 'var(--bad)' }}>{fail}</b> ไม่ผ่าน</span>
              </div>
              {/* Grade distribution */}
              <div style={{ display:'flex', gap: 2, marginTop: 10, height: 6, borderRadius: 6, overflow: 'hidden' }}>
                {Object.entries(dist).map(([k, v]) => {
                  if (v === 0) return null;
                  const tone = grade({A:80, "B+":75, B:70, "C+":65, C:60, "D+":55, D:50, F:0}[k]).tone;
                  const c = tone === "good" ? "var(--good)" : tone === "warn" ? "var(--warn)" : "var(--bad)";
                  return <div key={k} title={`${k}: ${v} คน`} style={{ flex: v, background: c, opacity: k === "F" ? 1 : .8 }}/>;
                })}
              </div>
            </div>
          );
        })}
      </div>

      {/* Risk threshold controls */}
      <div className="card" style={{ marginBottom: 18, padding: 18 }}>
        <div style={{ display:'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 16 }}>
          <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
            <div style={{ width: 38, height: 38, borderRadius: 10, background: 'color-mix(in oklab, var(--amber) 20%, transparent)', display:'grid', placeItems:'center', color: 'var(--amber)' }}>
              <Icon.alert width={20} height={20}/>
            </div>
            <div style={{ lineHeight: 1.2 }}>
              <div style={{ fontWeight: 600, fontSize: 14 }}>เกณฑ์ตรวจจับนักศึกษากลุ่มเสี่ยง</div>
              <div className="muted" style={{ fontSize: 12 }}>ระบบจะแจ้งเตือนเมื่อค่าใดค่าหนึ่งต่ำกว่าเกณฑ์</div>
            </div>
          </div>
          <div style={{ display:'flex', gap: 24, alignItems:'center', flex: 1, justifyContent: 'flex-end', flexWrap: 'wrap' }}>
            <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
              <label style={{ fontSize: 12, color: 'var(--fg-2)' }}>คะแนนเฉลี่ย &lt;</label>
              <input type="range" min="30" max="80" value={riskScore} onChange={e => setRiskScore(Number(e.target.value))} style={{ width: 140, accentColor: 'oklch(0.72 0.25 340)' }}/>
              <span className="num" style={{ fontWeight: 700, width: 32, textAlign: 'right' }}>{riskScore}</span>
            </div>
            <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
              <label style={{ fontSize: 12, color: 'var(--fg-2)' }}>เข้าเรียน &lt;</label>
              <input type="range" min="50" max="100" value={riskAttendance} onChange={e => setRiskAttendance(Number(e.target.value))} style={{ width: 140, accentColor: 'oklch(0.75 0.18 200)' }}/>
              <span className="num" style={{ fontWeight: 700, width: 44, textAlign: 'right' }}>{riskAttendance}%</span>
            </div>
          </div>
        </div>
      </div>

      {/* Student leaderboard / risk list */}
      <div className="grid-2">
        <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
          <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--line)', display:'flex', justifyContent: 'space-between', alignItems:'center' }}>
            <div>
              <h3>นักศึกษากลุ่มเสี่ยง</h3>
              <div className="muted" style={{ fontSize: 12 }}>จัดเรียงจากคะแนนต่ำสุด · ต้องการความช่วยเหลือเร่งด่วน</div>
            </div>
            <span className="pill bad"><Icon.alert width={12} height={12}/> {totalRisk} คน</span>
          </div>
          <table className="tbl">
            <thead>
              <tr>
                <th>นักศึกษา</th>
                <th style={{ textAlign: 'right' }}>คะแนน</th>
                <th style={{ textAlign: 'right' }}>เข้าเรียน</th>
                <th>ตก</th>
              </tr>
            </thead>
            <tbody>
              {dataset.perStudent.filter(p => p.atRisk).sort((a, b) => a.avgScore - b.avgScore).map(p => (
                <tr key={p.student.id}>
                  <td>
                    <div style={{ display:'flex', alignItems:'center', gap: 10 }}>
                      <Avatar name={p.student.firstName + " " + p.student.lastName} seed={p.student.avatarSeed} size={30}/>
                      <div style={{ lineHeight: 1.2 }}>
                        <div style={{ fontSize: 13 }}>{p.student.firstName} <span className="dim">({p.student.nickname})</span></div>
                        <div className="dim eng" style={{ fontSize: 11 }}>{p.student.code} · {p.student.classroom}</div>
                      </div>
                    </div>
                  </td>
                  <td style={{ textAlign: 'right' }}>
                    <div className="num" style={{ fontWeight: 700, color: p.avgScore < riskScore ? 'var(--bad)' : 'inherit' }}>{p.avgScore.toFixed(1)}</div>
                  </td>
                  <td style={{ textAlign: 'right' }}>
                    <div className="num" style={{ color: p.avgAtt * 100 < riskAttendance ? 'var(--bad)' : 'inherit' }}>{(p.avgAtt * 100).toFixed(0)}%</div>
                  </td>
                  <td><span className="pill bad">{p.failed} วิชา</span></td>
                </tr>
              ))}
              {totalRisk === 0 && (
                <tr><td colSpan="4" style={{ textAlign: 'center', padding: 28, color: 'var(--fg-2)' }}>
                  <Icon.check width={22} height={22} style={{ color: 'var(--good)', verticalAlign: '-6px', marginRight: 6 }}/>
                  ยอดเยี่ยม! ยังไม่มีนักศึกษาที่อยู่ในเกณฑ์เสี่ยง
                </td></tr>
              )}
            </tbody>
          </table>
        </div>

        <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
          <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--line)' }}>
            <h3>นักศึกษาดีเด่น</h3>
            <div className="muted" style={{ fontSize: 12 }}>คะแนนเฉลี่ยสูงสุดในระดับชั้น</div>
          </div>
          <table className="tbl">
            <thead>
              <tr>
                <th>อันดับ</th>
                <th>นักศึกษา</th>
                <th style={{ textAlign: 'right' }}>GPA</th>
                <th style={{ textAlign: 'right' }}>คะแนน</th>
              </tr>
            </thead>
            <tbody>
              {dataset.perStudent.slice().sort((a, b) => b.avgScore - a.avgScore).slice(0, 8).map((p, i) => (
                <tr key={p.student.id}>
                  <td>
                    <div style={{ display:'flex', alignItems:'center', gap: 6 }}>
                      {i < 3 && <Icon.star width={14} height={14} style={{ color: ["oklch(0.85 0.18 75)", "oklch(0.80 0.04 280)", "oklch(0.65 0.12 60)"][i] }}/>}
                      <span className="num dim">{String(i + 1).padStart(2, "0")}</span>
                    </div>
                  </td>
                  <td>
                    <div style={{ display:'flex', alignItems:'center', gap: 10 }}>
                      <Avatar name={p.student.firstName + " " + p.student.lastName} seed={p.student.avatarSeed} size={30}/>
                      <div style={{ lineHeight: 1.2 }}>
                        <div style={{ fontSize: 13 }}>{p.student.firstName} <span className="dim">({p.student.nickname})</span></div>
                        <div className="dim eng" style={{ fontSize: 11 }}>{p.student.code} · {p.student.classroom}</div>
                      </div>
                    </div>
                  </td>
                  <td style={{ textAlign: 'right' }}><div className="num" style={{ fontWeight: 700 }}>{p.gpa.toFixed(2)}</div></td>
                  <td style={{ textAlign: 'right' }}><div className="num" style={{ fontWeight: 700, color: 'var(--good)' }}>{p.avgScore.toFixed(1)}</div></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      </>)}
    </div>
  );
}

window.ExecutiveDashboard = ExecutiveDashboard;
window.CollegeOverview = CollegeOverview;
