/* AAU CRM — Operations: Khóa học · Lịch khai giảng (lớp + lịch tháng) · chỉnh sửa + đồng bộ aau.vn */

const GROUP_C = id => (AAU.courseGroupById(id) || {}).color || '#616161';
const fillColor = t => (t === 'ok' ? '#0e7c4a' : t === 'warn' ? '#d97706' : '#c4320a');
const DOW_VN = ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'];
const PATTERNS = [
  { pat: ['2', '4', '6'], label: 'Thứ 2 · 4 · 6' },
  { pat: ['3', '5', '7'], label: 'Thứ 3 · 5 · 7' },
  { pat: ['6', '7', 'CN'], label: 'Thứ 6 · 7 · CN' },
  { pat: ['7', 'CN'], label: 'Thứ 7 · CN' },
  { pat: ['2', '4'], label: 'Thứ 2 · 4' },
  { pat: ['3', '5'], label: 'Thứ 3 · 5' },
  { pat: ['2', '3', '4', '5', '6'], label: 'Thứ 2 → 6' },
];

function useOps() {
  const [, force] = React.useReducer(x => x + 1, 0);
  React.useEffect(() => OpsStore.subscribe(force), []);
  return OpsStore;
}
function classFill(c) {
  const fill = Math.round(c.enrolled / c.cap * 100);
  const slots = Math.max(0, c.cap - c.enrolled);
  const days = AAU.daysToStart(c);
  const tone = fill >= 80 ? 'ok' : fill >= 50 ? 'warn' : 'bad';
  const almostFull = slots <= 2;
  const lowFill = c.status === 'enrolling' && fill < 50 && days <= 22;
  return { fill, slots, days, tone, almostFull, lowFill };
}
function fmtFieldVal(k, v) {
  if (v == null || v === '') return '—';
  if (k === 'price') return AAU.fmtVND(v);
  if (k === 'start') return AAU.fmtDate(v);
  if (k === 'status') return v === 'active' ? 'Đang mở' : 'Sắp ra mắt';
  if (k === 'group') return (AAU.courseGroupById(v) || {}).label || v;
  if (k === 'brochure') return 'link Drive';
  if (k === 'desc') return String(v).slice(0, 40) + '…';
  return String(v);
}

function GroupTag({ id }) {
  const g = AAU.courseGroupById(id); if (!g) return null;
  return <span className="badge" style={{ background: g.color + '1f', color: g.color, fontWeight: 600 }}>{g.label}</span>;
}
function ClassStatusBadge({ c }) {
  if (c.status === 'in_progress') return <Badge tone="info">Đang học · buổi {c.doneCount}/{c.sessions.length}</Badge>;
  return <Badge tone="success">Đang tuyển</Badge>;
}
function FillBar({ c, h = 6 }) {
  const { fill, tone } = classFill(c);
  return <div className="fillbar" style={{ height: h }}><span style={{ width: Math.min(100, fill) + '%', background: fillColor(tone) }} /></div>;
}
function WebChip() { return <span className="web-chip"><Icon name="checkCircle" size={11} />Đã đăng web</span>; }
function DiffChip() { return <Badge tone="warning"><Icon name="refresh" size={11} />Lệch web</Badge>; }
function InsAvatar({ id, size = 24 }) {
  const i = AAU.instructorById(id); if (!i) return null;
  return <Avatar name={i.name} color={i.color} size={size} />;
}

/* ============================= KHÓA HỌC ============================= */
function CourseCatalog() {
  useOps();
  const [grp, setGrp] = useState('all');
  const [view, setView] = useState(() => localStorage.getItem('aau_course_view') || 'grid');
  const [course, setCourse] = useState(null);
  const [sync, setSync] = useState(false);
  const setV = v => { setView(v); localStorage.setItem('aau_course_view', v); };
  const courses = AAU.courses.filter(c => grp === 'all' || c.group === grp);
  const diffIds = new Set(OpsStore.courseDiffs().map(d => d.id));
  const courseObj = course && AAU.courseById(course.id);

  const totalStudents = AAU.classes.reduce((s, c) => s + c.enrolled, 0);
  const openClasses = AAU.classes.filter(c => c.status === 'enrolling').length;
  const activeCourses = AAU.courses.filter(c => c.status === 'active').length;
  const totalCourses = AAU.courses.length;
  const soonCourses = AAU.courses.filter(c => c.status === 'coming_soon').length;

  return (
    <div className="page wide">
      <PageHead title="Khóa học" subtitle={totalCourses + ' chương trình chuyên sâu F&B · đồng bộ aau.vn/cac-khoa-hoc'}
        actions={<>
          <Button icon="refresh" onClick={() => setSync(true)}>Đồng bộ web{diffIds.size ? ' (' + diffIds.size + ')' : ''}</Button>
          <Button variant="primary" icon="plus">Thêm khóa</Button>
        </>} />
      <div className="grid gc4 mb16">
        <KPI label="Tổng khóa học" value={totalCourses} sub={activeCourses + ' đang mở · ' + soonCourses + ' sắp ra mắt'} icon="graduation" />
        <KPI label="Lớp đang tuyển" value={openClasses} sub="trên 8 lớp khai giảng" icon="calendar" />
        <KPI label="Học viên đang học" value={totalStudents} delta={12} icon="users" />
        <KPI label="Chỗ còn trống" value={AAU.classes.reduce((s, c) => s + Math.max(0, c.cap - c.enrolled), 0)} sub="tất cả lớp đang mở" icon="target" />
      </div>
      <div className="row jcsb aic mb16 wrap g8">
        <PillTabs value={grp} onChange={setGrp} options={[{ value: 'all', label: 'Tất cả (' + totalCourses + ')' }, ...AAU.courseGroups.map(g => ({ value: g.id, label: g.label + ' (' + AAU.courses.filter(c => c.group === g.id).length + ')' }))]} />
        <Seg value={view} onChange={setV} options={[{ value: 'grid', label: '▦ Lưới' }, { value: 'list', label: '☰ Danh sách' }]} />
      </div>
      {view === 'grid'
        ? <div className="grid gc3">{courses.map(c => <CourseCard key={c.id} c={c} diff={diffIds.has(c.id)} onOpen={() => setCourse(c)} />)}</div>
        : <CourseList courses={courses} diffIds={diffIds} onOpen={setCourse} />}
      {courseObj && <CourseDrawer course={courseObj} hasDiff={diffIds.has(courseObj.id)} onClose={() => setCourse(null)} />}
      {sync && <SyncModal scope="course" onClose={() => setSync(false)} />}
    </div>
  );
}

function CourseCard({ c, diff, onOpen }) {
  const cls = AAU.classesByCourse(c.id);
  const soon = c.status === 'coming_soon';
  return (
    <Card pad className="crow" style={{ display: 'flex', flexDirection: 'column' }}>
      <div onClick={onOpen} style={{ flex: 1, cursor: 'pointer' }}>
        <div className="row jcsb aic mb10"><GroupTag id={c.group} /><div className="row aic g6">{diff && <DiffChip />}{soon ? <Badge tone="warning">Sắp ra mắt</Badge> : <Badge tone="success" dot>Đang mở</Badge>}</div></div>
        <div className="t15 fw7" style={{ minHeight: 42, lineHeight: 1.3 }}>{c.name}</div>
        <div className="t11 subtle mb8" style={{ textTransform: 'uppercase', letterSpacing: '.04em' }}>{c.en}</div>
        <div className="t12 muted mb12" style={{ minHeight: 50, lineHeight: 1.45 }}>{c.desc}</div>
        <div className="row jcsb aic">
          <span className="t17 fw7 tnum">{c.price ? AAU.fmtVNDm(c.price) : 'Đang cập nhật'}</span>
          <span className="t12 subtle">{c.sessions} buổi · {c.hours}h</span>
        </div>
      </div>
      <div className="divider mt12 mb12" />
      {soon
        ? <div className="row aic g6 t12 sla-warn"><Icon name="bell" size={13} />Mở đăng ký nhận tin khi ra mắt</div>
        : cls.length
          ? <div className="col g8" onClick={onOpen} style={{ cursor: 'pointer' }}>
            <div className="t11 fw7 subtle">{cls.length} LỚP ĐANG KHAI GIẢNG</div>
            {cls.slice(0, 2).map(k => { const f = classFill(k); return (
              <div key={k.id}>
                <div className="row jcsb t12 mb4"><span className="fw6">{k.batch}</span><span className="muted">KG {AAU.fmtDate(k.start)}</span></div>
                <FillBar c={k} />
                <div className="row jcsb t11 subtle" style={{ marginTop: 4 }}><span>{k.enrolled}/{k.cap} HV</span><span className={'sla-' + f.tone}>còn {f.slots} chỗ</span></div>
              </div>
            ); })}
          </div>
          : <div className="row aic g6 t12 subtle"><Icon name="calendar" size={13} />Chưa có lịch khai giảng</div>}
    </Card>
  );
}

function CourseList({ courses, diffIds, onOpen }) {
  return (
    <Card pad={false}>
      <table className="tbl" style={{ width: '100%', borderCollapse: 'collapse' }}>
        <thead><tr style={{ textAlign: 'left', fontSize: 11.5, color: 'var(--p-text-subdued)', textTransform: 'uppercase', letterSpacing: '.04em' }}>
          <th style={{ padding: '10px 16px' }}>Khóa học</th><th>Nhóm</th><th>Buổi</th><th style={{ textAlign: 'right' }}>Học phí</th><th>Lớp đang mở</th><th style={{ textAlign: 'right', paddingRight: 16 }}>HV / Chỗ</th>
        </tr></thead>
        <tbody>{courses.map(c => {
          const cls = AAU.classesByCourse(c.id);
          const soon = c.status === 'coming_soon';
          const hv = cls.reduce((s, k) => s + k.enrolled, 0), cap = cls.reduce((s, k) => s + k.cap, 0);
          return (
            <tr key={c.id} className="crow" onClick={() => onOpen(c)} style={{ borderTop: '1px solid var(--p-border-secondary)', fontSize: 13 }}>
              <td style={{ padding: '11px 16px' }}><div className="row aic g6"><span className="fw6">{c.name}</span>{diffIds.has(c.id) && <DiffChip />}</div><div className="t11 subtle">{c.code} · {c.en}</div></td>
              <td><GroupTag id={c.group} /></td>
              <td className="tnum">{c.sessions} buổi · {c.hours}h</td>
              <td className="tnum fw6" style={{ textAlign: 'right' }}>{c.price ? AAU.fmtVND(c.price) : '—'}</td>
              <td>{soon ? <Badge tone="warning">Sắp ra mắt</Badge> : cls.length ? cls.map(k => k.batch).join(', ') : <span className="subtle">—</span>}</td>
              <td className="tnum" style={{ textAlign: 'right', paddingRight: 16 }}>{cap ? <b>{hv}</b> : '—'}{cap ? <span className="subtle"> / {cap}</span> : ''}</td>
            </tr>
          );
        })}</tbody>
      </table>
    </Card>
  );
}

function CourseEditForm({ c, onDone }) {
  const [f, setF] = useState({ name: c.name, en: c.en || '', code: c.code, group: c.group, sessions: c.sessions, hours: c.hours, price: c.price || 0, status: c.status, targetStudents: c.targetStudents, desc: c.desc });
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = () => { OpsStore.updateCourse(c.id, { name: f.name, en: f.en, code: f.code, group: f.group, sessions: +f.sessions, hours: +f.hours, price: +f.price, status: f.status, targetStudents: +f.targetStudents, desc: f.desc }); onDone(); };
  return (
    <div className="col g12">
      <Field label="Tên khóa"><Input value={f.name} onChange={v => set('name', v)} /></Field>
      <Field label="Tên tiếng Anh"><Input value={f.en} onChange={v => set('en', v)} /></Field>
      <div className="grid gc2">
        <Field label="Mã khóa"><Input value={f.code} onChange={v => set('code', v)} /></Field>
        <Field label="Nhóm"><Select value={f.group} onChange={v => set('group', v)} options={AAU.courseGroups.map(g => ({ value: g.id, label: g.label }))} /></Field>
        <Field label="Số buổi"><Input type="number" value={f.sessions} onChange={v => set('sessions', v)} /></Field>
        <Field label="Số giờ"><Input type="number" value={f.hours} onChange={v => set('hours', v)} /></Field>
        <Field label="Học phí (đ)"><Input type="number" value={f.price} onChange={v => set('price', v)} /></Field>
        <Field label="Sĩ số mục tiêu / lớp"><Input type="number" value={f.targetStudents} onChange={v => set('targetStudents', v)} /></Field>
      </div>
      <Field label="Trạng thái"><Select value={f.status} onChange={v => set('status', v)} options={[{ value: 'active', label: 'Đang mở' }, { value: 'coming_soon', label: 'Sắp ra mắt' }]} /></Field>
      <Field label="Mô tả"><textarea className="input" rows={3} value={f.desc} onChange={e => set('desc', e.target.value)} style={{ resize: 'vertical' }} /></Field>
      <div className="row g8"><Button variant="primary" icon="save" onClick={save}>Lưu thay đổi</Button><Button onClick={onDone}>Hủy</Button></div>
    </div>
  );
}

function CourseDrawer({ course, hasDiff, onClose }) {
  const [edit, setEdit] = useState(false);
  const cls = AAU.classesByCourse(course.id);
  return (
    <Drawer title={course.name} width={560} onClose={onClose}
      footer={edit ? null : <>
        {course.slug && <Button icon="externalLink" onClick={() => window.open(AAU.courseUrl(course), '_blank')}>Trang web</Button>}
        <Button icon="edit" onClick={() => setEdit(true)}>Chỉnh sửa</Button>
        <Button variant="primary" icon="plus">Mở lớp mới</Button>
      </>}>
      <div className="row jcsb aic mb12">
        <div className="row aic g8"><GroupTag id={course.group} /><Badge tone={course.status === 'active' ? 'success' : 'warning'}>{course.status === 'active' ? 'Đang mở' : 'Sắp ra mắt'}</Badge></div>
        {hasDiff && <div className="row aic g6"><DiffChip /><Button size="sm" icon="refresh" onClick={() => OpsStore.pullCourse(course.id)}>Lấy theo web</Button></div>}
      </div>
      {edit ? <CourseEditForm c={course} onDone={() => setEdit(false)} /> : <>
        <div className="t11 subtle mb8" style={{ textTransform: 'uppercase' }}>{course.code} · {course.en}</div>
        <div className="t13 muted mb16" style={{ lineHeight: 1.5 }}>{course.desc}</div>
        <div className="grid gc3 mb16">
          <KPI label="Học phí" value={course.price ? AAU.fmtVNDm(course.price) : '—'} />
          <KPI label="Thời lượng" value={course.sessions + ' buổi'} sub={course.hours + ' giờ'} />
          <KPI label="Sĩ số mục tiêu" value={course.targetStudents + ' HV'} sub="mỗi lớp" />
        </div>
        <div className="t12 fw7 subtle mb8">LỊCH KHAI GIẢNG ({cls.length})</div>
        {cls.length ? <div className="col g10">{cls.map(k => { const f = classFill(k); return (
          <div key={k.id} className="mini-class">
            <div className="row jcsb aic mb6"><div className="row aic g8"><span className="fw7 t13">{k.batch}</span><ClassStatusBadge c={k} /></div><WebChip /></div>
            <div className="row g16 t12 muted mb8 wrap">
              <span className="row aic g4"><Icon name="calendar" size={13} />{AAU.fmtDate(k.start)}{f.days > 0 ? ' · còn ' + f.days + ' ngày' : ''}</span>
              <span className="row aic g4"><Icon name="clock" size={13} />{k.patLabel} · {k.time}</span>
            </div>
            <FillBar c={k} />
            <div className="row jcsb t11 subtle" style={{ marginTop: 5 }}><span><b>{k.enrolled}</b>/{k.cap} HV · {f.fill}%</span><span className={'sla-' + f.tone}>còn {f.slots} chỗ</span></div>
          </div>
        ); })}</div> : <EmptyState icon="calendar" title="Chưa có lịch" desc="Khóa này chưa có lớp khai giảng." />}
      </>}
    </Drawer>
  );
}

/* ====================== LỚP / LỊCH KHAI GIẢNG ====================== */
function ClassesPage() {
  useOps();
  const [tab, setTab] = useState('list');
  const [cls, setCls] = useState(null);
  const [sync, setSync] = useState(false);
  const diffIds = new Set(OpsStore.classDiffs().map(d => d.id));
  const clsObj = cls && AAU.classById(cls.id);
  const enrolling = AAU.classes.filter(c => c.status === 'enrolling');
  const slotsLeft = AAU.classes.reduce((s, c) => s + Math.max(0, c.cap - c.enrolled), 0);
  const soon7 = AAU.classes.filter(c => { const d = AAU.daysToStart(c); return d >= 0 && d <= 7; }).length;
  const risk = AAU.classes.filter(c => classFill(c).lowFill).length;

  return (
    <div className="page wide">
      <PageHead title="Lịch khai giảng" subtitle="8 lớp T6–T7/2026 · TP.HCM · đồng bộ aau.vn/lich-khai-giang"
        actions={<>
          <Button icon="refresh" onClick={() => setSync(true)}>Đồng bộ web{diffIds.size ? ' (' + diffIds.size + ')' : ''}</Button>
          <Button variant="primary" icon="plus">Mở lớp mới</Button>
        </>} />
      <div className="grid gc4 mb16">
        <KPI label="Lớp đang tuyển" value={enrolling.length} sub="+ 1 lớp đang học" icon="calendar" />
        <KPI label="Chỗ còn trống" value={slotsLeft} sub="trên tổng sĩ số tối đa" icon="users" />
        <KPI label="Khai giảng ≤ 7 ngày" value={soon7} icon="clock" />
        <KPI label="Lớp nguy cơ ế" value={risk} sub="fill < 50% · cần đẩy MKT" icon="alert" />
      </div>
      <div className="row aic mb16"><Tabs value={tab} onChange={setTab} tabs={[{ value: 'list', label: 'Danh sách lớp' }, { value: 'cal', label: 'Lịch tháng' }]} /></div>
      {tab === 'list'
        ? <div className="grid gc2">{[...AAU.classes].sort((a, b) => a.start.localeCompare(b.start)).map(c => <ClassCard key={c.id} c={c} diff={diffIds.has(c.id)} onOpen={() => setCls(c)} />)}</div>
        : <CalendarView onOpenClass={setCls} />}
      {clsObj && <ClassDrawer c={clsObj} hasDiff={diffIds.has(clsObj.id)} onClose={() => setCls(null)} />}
      {sync && <SyncModal scope="class" onClose={() => setSync(false)} />}
    </div>
  );
}

function ClassCard({ c, diff, onOpen }) {
  const f = classFill(c);
  return (
    <Card pad>
      <div className="row jcsb ais mb8">
        <div>
          <div className="row aic g8 mb2"><span className="badge" style={{ background: GROUP_C(c.group) + '1f', color: GROUP_C(c.group), fontWeight: 600 }}>{c.cat}</span><ClassStatusBadge c={c} /></div>
          <div className="t15 fw7" style={{ lineHeight: 1.3 }}>{c.courseName}</div>
          <div className="t12 subtle">{c.batch}</div>
        </div>
        <div className="row aic g6">{diff && <DiffChip />}<WebChip /></div>
      </div>
      <div className="row g16 t12 muted mb6 wrap">
        <span className="row aic g4"><Icon name="calendar" size={13} />KG {AAU.fmtDate(c.start)}</span>
        <span className="row aic g4"><Icon name="clock" size={13} />{c.patLabel} · {c.time}</span>
      </div>
      <div className="row aic g8 t12 muted mb12"><InsAvatar id={c.lead} size={22} /><span>GV chính: <b style={{ color: 'var(--p-text)' }}>{AAU.instructorById(c.lead).name}</b></span></div>
      <div className="row jcsb t12 mb4"><span>Lấp đầy: <b>{c.enrolled}/{c.cap}</b> · còn <b>{f.slots}</b> chỗ</span><span className={'fw6 sla-' + f.tone}>{f.fill}%</span></div>
      <FillBar c={c} h={7} />
      <div className="row jcsb aic t11 subtle" style={{ marginTop: 6 }}>
        <span>Doanh thu: <b className="sla-ok">{AAU.fmtVNDm(c.revenueActual)}</b> / {AAU.fmtVNDm(c.revenueTarget)}</span>
        {f.days >= 0 ? <span>còn {f.days} ngày tới KG</span> : <span>đã khai giảng</span>}
      </div>
      {f.lowFill && <div className="row aic g6 t12 sla-bad mt12"><Icon name="alert" size={14} />Nguy cơ ế: {f.fill}%, còn {f.days} ngày — cần đẩy marketing</div>}
      {f.almostFull && c.status === 'enrolling' && <div className="row aic g6 t12 sla-warn mt12"><Icon name="fire" size={14} />Sắp đầy — còn {f.slots} chỗ{c.waitlist ? ' · ' + c.waitlist + ' người chờ' : ''}</div>}
      <div className="row g8 mt12">
        <Button size="sm" icon="calendar" onClick={onOpen}>Lịch buổi học</Button>
        <Button size="sm" icon="fileText" onClick={() => window.open(c.brochure, '_blank')}>Brochure</Button>
        <Button size="sm" icon="externalLink" onClick={() => window.open(c.registerUrl, '_blank')}>Đăng ký</Button>
      </div>
    </Card>
  );
}

function ClassEditForm({ c, onDone }) {
  const [f, setF] = useState({ batch: c.batch, cat: c.cat, start: c.start, patLabel: c.patLabel, time: c.time, cap: c.cap, enrolled: c.enrolled, n: c.n, lead: c.lead, alt: c.alt, roomId: c.roomId, brochure: c.brochure });
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = () => {
    const pp = PATTERNS.find(p => p.label === f.patLabel);
    OpsStore.updateClass(c.id, { batch: f.batch, cat: f.cat, start: f.start, patLabel: f.patLabel, pat: pp ? pp.pat : c.pat, time: f.time, cap: +f.cap, enrolled: +f.enrolled, n: +f.n, lead: f.lead, alt: f.alt, roomId: f.roomId, brochure: f.brochure });
    onDone();
  };
  const insOpts = AAU.instructors.map(i => ({ value: i.id, label: i.name }));
  return (
    <div className="col g12">
      <div className="callout-soft"><Icon name="alert" size={14} />Đổi ngày KG / lịch học / số buổi sẽ <b style={{ color: 'var(--p-text)' }}>tự sinh lại</b> lịch từng buổi (giữ chỉnh sửa riêng theo số buổi).</div>
      <div className="grid gc2">
        <Field label="Mã lớp"><Input value={f.batch} onChange={v => set('batch', v)} /></Field>
        <Field label="Danh mục (web)"><Input value={f.cat} onChange={v => set('cat', v)} /></Field>
        <Field label="Ngày khai giảng"><Input type="date" value={f.start} onChange={v => set('start', v)} /></Field>
        <Field label="Lịch học"><Select value={f.patLabel} onChange={v => set('patLabel', v)} options={PATTERNS.map(p => ({ value: p.label, label: p.label }))} /></Field>
        <Field label="Giờ học"><Input value={f.time} onChange={v => set('time', v)} /></Field>
        <Field label="Số buổi"><Input type="number" value={f.n} onChange={v => set('n', v)} /></Field>
        <Field label="Sĩ số tối đa"><Input type="number" value={f.cap} onChange={v => set('cap', v)} /></Field>
        <Field label="Đã ghi danh"><Input type="number" value={f.enrolled} onChange={v => set('enrolled', v)} /></Field>
        <Field label="GV chính"><Select value={f.lead} onChange={v => set('lead', v)} options={insOpts} /></Field>
        <Field label="GV phụ / khách"><Select value={f.alt} onChange={v => set('alt', v)} options={insOpts} /></Field>
      </div>
      <Field label="Phòng học mặc định"><Select value={f.roomId} onChange={v => set('roomId', v)} options={AAU.rooms.map(r => ({ value: r.id, label: r.name }))} /></Field>
      <Field label="Link Brochure"><Input value={f.brochure} onChange={v => set('brochure', v)} /></Field>
      <div className="row g8"><Button variant="primary" icon="save" onClick={save}>Lưu thay đổi</Button><Button onClick={onDone}>Hủy</Button></div>
    </div>
  );
}

function SessionEditModal({ c, s, onClose }) {
  const [f, setF] = useState({ date: s.date, time: s.time, topic: s.topic, instructor: s.instructor, roomId: s.roomId });
  const set = (k, v) => setF(x => ({ ...x, [k]: v }));
  const save = () => { OpsStore.updateSession(c.id, s.n, { date: f.date, time: f.time, topic: f.topic, instructor: f.instructor, roomId: f.roomId }); onClose(); };
  return (
    <Modal title={'Buổi ' + s.n + ' · ' + c.batch} width={460} onClose={onClose}
      footer={<><Button onClick={onClose}>Hủy</Button><Button variant="primary" icon="save" onClick={save}>Lưu buổi học</Button></>}>
      <div className="col g12">
        <Field label="Chủ đề buổi"><Input value={f.topic} onChange={v => set('topic', v)} /></Field>
        <div className="grid gc2">
          <Field label="Ngày"><Input type="date" value={f.date} onChange={v => set('date', v)} /></Field>
          <Field label="Giờ"><Input value={f.time} onChange={v => set('time', v)} /></Field>
        </div>
        <Field label="Giảng viên phụ trách"><Select value={f.instructor} onChange={v => set('instructor', v)} options={AAU.instructors.map(i => ({ value: i.id, label: i.name + ' — ' + i.title }))} /></Field>
        <Field label="Phòng học"><Select value={f.roomId} onChange={v => set('roomId', v)} options={AAU.rooms.map(r => ({ value: r.id, label: r.name }))} /></Field>
      </div>
    </Modal>
  );
}

function ClassDrawer({ c, hasDiff, onClose }) {
  const [edit, setEdit] = useState(false);
  const [sess, setSess] = useState(null);
  const f = classFill(c);
  const wl = AAU.waitlistByClass(c.id);
  const insMap = {};
  c.sessions.forEach(s => { insMap[s.instructor] = (insMap[s.instructor] || 0) + 1; });
  return (
    <Drawer title={c.courseName} width={640} onClose={onClose}
      footer={edit ? null : <>
        <Button icon="fileText" onClick={() => window.open(c.brochure, '_blank')}>Brochure</Button>
        <Button icon="edit" onClick={() => setEdit(true)}>Chỉnh sửa lớp</Button>
        <Button variant="primary" icon="plus">Thêm học viên</Button>
      </>}>
      <div className="row jcsb aic mb12">
        <div className="row aic g8"><span className="badge" style={{ background: GROUP_C(c.group) + '1f', color: GROUP_C(c.group), fontWeight: 600 }}>{c.cat}</span><span className="fw7 t13">{c.batch}</span><ClassStatusBadge c={c} /></div>
        {hasDiff ? <div className="row aic g6"><DiffChip /><Button size="sm" icon="refresh" onClick={() => OpsStore.pullClass(c.id)}>Lấy theo web</Button></div> : <WebChip />}
      </div>

      {edit ? <ClassEditForm c={c} onDone={() => setEdit(false)} /> : <>
        <div className="grid gc4 mb16">
          <KPI label="Khai giảng" value={AAU.fmtDate(c.start)} sub={f.days >= 0 ? 'còn ' + f.days + ' ngày' : 'đã KG'} />
          <KPI label="Lấp đầy" value={f.fill + '%'} sub={c.enrolled + '/' + c.cap + ' · còn ' + f.slots} />
          <KPI label="Doanh thu" value={AAU.fmtVNDm(c.revenueActual)} sub={'mục tiêu ' + AAU.fmtVNDm(c.revenueTarget)} />
          <KPI label="Lịch" value={c.time} sub={c.patLabel} />
        </div>
        {f.lowFill && <div className="mkt-alert mb12" style={{ background: 'var(--p-critical-bg)', color: '#8e1f0b' }}><Icon name="alert" size={16} /><div className="t12">Lớp nguy cơ ế — mới {f.fill}%, còn {f.days} ngày. Đề xuất chạy retarget + ưu đãi early-bird.</div></div>}
        {f.almostFull && c.status === 'enrolling' && <div className="mkt-alert mb12" style={{ background: 'var(--p-warning-bg)', color: '#5e4200' }}><Icon name="fire" size={16} /><div className="t12">Sắp đầy — còn {f.slots} chỗ. {c.waitlist ? c.waitlist + ' người trong danh sách chờ.' : 'Cân nhắc mở thêm lớp.'}</div></div>}

        <div className="row jcsb aic mb4"><div className="t12 fw7 subtle">LỊCH TỪNG BUỔI · GIẢNG VIÊN PHỤ TRÁCH</div><span className="t11 subtle">bấm ✎ để sửa từng buổi</span></div>
        <Card pad>
          {c.sessions.map(s => { const ins = AAU.instructorById(s.instructor); const done = s.status === 'done'; return (
            <div key={s.n} className="sess-row">
              <span className="sess-n" style={{ background: done ? 'var(--p-success-bg)' : GROUP_C(c.group) + '18', color: done ? '#0e7c4a' : GROUP_C(c.group) }}>{done ? <Icon name="check" size={15} /> : s.n}</span>
              <div className="t12"><div className="fw6">{DOW_VN[new Date(s.date).getDay()]} · {AAU.fmtDate(s.date)}</div><div className="subtle">{s.time}</div></div>
              <div className="t12"><div className="fw6" style={{ lineHeight: 1.3 }}>{s.topic}</div><div className="subtle row aic g4"><Icon name="building" size={11} />{AAU.roomById(s.roomId).name}</div></div>
              <div className="row aic g6" style={{ justifyContent: 'flex-end' }}>
                <div className="row aic g6" title={ins.name}>
                  <Avatar name={ins.name} color={ins.color} size={24} />
                  <div className="t11" style={{ textAlign: 'right' }}><div className="fw6">{ins.name.replace('Thầy ', '').replace('Cô ', '')}</div>{done && s.present != null ? <div className="sla-ok">{s.present}/{c.enrolled} có mặt</div> : <div className="subtle">{ins.title.split('·')[0]}</div>}</div>
                </div>
                <IconButton name="edit" size={15} title="Sửa buổi" onClick={() => setSess(s)} />
              </div>
            </div>
          ); })}
        </Card>

        <div className="grid gc2 mt16">
          <Card title="Giảng viên đứng lớp">
            <div className="col g10">{Object.entries(insMap).map(([id, n]) => { const i = AAU.instructorById(id); return (
              <div key={id} className="row jcsb aic">
                <div className="row aic g8"><Avatar name={i.name} color={i.color} size={28} /><div className="t12"><div className="fw6">{i.name}</div><div className="subtle">{i.title}</div></div></div>
                <div className="t12" style={{ textAlign: 'right' }}><div className="fw6">{n} buổi</div><div className="subtle row aic g4"><Icon name="star" size={11} color="#f59e0b" />{i.rating}</div></div>
              </div>
            ); })}</div>
          </Card>
          <Card title={'Danh sách chờ' + (wl.length ? ' (' + wl.length + ')' : '')}>
            {wl.length ? <div className="col g8">{wl.map(w => (
              <div key={w.id} className="row jcsb aic t12">
                <div className="row aic g8"><ChannelDot ch={w.from} size={18} /><div><div className="fw6">{w.name}</div><div className="subtle">{w.phone}</div></div></div>
                <Button size="sm" icon="plus">Chuyển vào lớp</Button>
              </div>
            ))}</div> : <div className="t12 subtle">Chưa có ai trong danh sách chờ. Khi lớp đầy, lead mới sẽ vào đây.</div>}
          </Card>
        </div>
      </>}
      {sess && <SessionEditModal c={c} s={sess} onClose={() => setSess(null)} />}
    </Drawer>
  );
}

/* ============================ ĐỒNG BỘ WEB ============================ */
function SyncModal({ scope, onClose }) {
  useOps();
  const diffs = scope === 'course' ? OpsStore.courseDiffs() : OpsStore.classDiffs();
  const pull = scope === 'course' ? OpsStore.pullCourse : OpsStore.pullClass;
  const title = scope === 'course' ? 'Đồng bộ Khóa học ↔ aau.vn' : 'Đồng bộ Lịch khai giảng ↔ aau.vn';
  const page = scope === 'course' ? 'cac-khoa-hoc' : 'lich-khai-giang';
  return (
    <Modal title={title} width={660} onClose={onClose}
      footer={<>
        <span className="t12 subtle mla">Đồng bộ gần nhất: {OpsStore.lastSync()}</span>
        <Button onClick={onClose}>Đóng</Button>
        {diffs.length > 0 && <Button variant="primary" icon="refresh" onClick={() => { OpsStore.pullAll(); }}>Cập nhật tất cả theo web</Button>}
      </>}>
      <div className="callout-soft mb16"><Icon name="refresh" size={15} />Nguồn: <b style={{ color: 'var(--p-text)' }}>aau.vn/pages/{page}</b> (Shopify). Dưới đây là các mục CRM đang <b style={{ color: 'var(--p-text)' }}>lệch</b> so với web — chọn “Lấy theo web” để cập nhật.</div>
      {diffs.length === 0
        ? <EmptyState icon="checkCircle" title="Đã khớp với web" desc="Mọi thông tin CRM đang trùng khớp với aau.vn." />
        : <div className="col g12">{diffs.map(d => (
          <Card key={d.id} pad>
            <div className="row jcsb aic mb8"><div className="fw7 t14">{d.name}{d.batch ? ' · ' + d.batch : ''}</div><Button size="sm" icon="refresh" onClick={() => pull(d.id)}>Lấy theo web</Button></div>
            <div className="col g8">{d.fields.map(fl => (
              <div key={fl.key} className="row aic g10 t12" style={{ borderTop: '1px solid var(--p-border-secondary)', paddingTop: 8 }}>
                <span className="subtle" style={{ width: 100, flexShrink: 0 }}>{fl.label}</span>
                <span className="badge critical" style={{ textDecoration: 'line-through' }}>CRM: {fmtFieldVal(fl.key, fl.crm)}</span>
                <Icon name="arrowRight" size={13} />
                <span className="badge success">Web: {fmtFieldVal(fl.key, fl.web)}</span>
              </div>
            ))}</div>
          </Card>
        ))}</div>}
    </Modal>
  );
}

/* ============================ LỊCH THÁNG ============================ */
function monthGrid(year, month) {
  const first = new Date(year, month, 1);
  const start = (first.getDay() + 6) % 7;
  const dim = new Date(year, month + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < start; i++) cells.push(null);
  for (let d = 1; d <= dim; d++) cells.push(new Date(year, month, d));
  while (cells.length % 7) cells.push(null);
  const weeks = [];
  for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
  return weeks;
}

function CalendarView({ onOpenClass }) {
  const sessionsByDate = useMemo(() => {
    const map = {};
    AAU.classes.forEach(c => c.sessions.forEach(s => { (map[s.date] = map[s.date] || []).push({ ...s, cls: c }); }));
    return map;
  }, [AAU.classes.map(c => c.sessions.length + c.start).join()]);
  const conflicts = useMemo(() => {
    const out = {};
    Object.entries(sessionsByDate).forEach(([date, list]) => {
      const byIns = {};
      list.forEach(s => { (byIns[s.instructor] = byIns[s.instructor] || []).push(s); });
      const dup = Object.entries(byIns).filter(([, arr]) => arr.length >= 2).map(([id]) => id);
      if (dup.length) out[date] = dup;
    });
    return out;
  }, [sessionsByDate]);
  const conflictDays = Object.keys(conflicts).length;
  const todayISO = '2026-06-02';

  const Month = ({ year, month, label }) => (
    <Card title={label} pad>
      <div className="cal-head">{DOW_VN.slice(1).concat(DOW_VN[0]).map(d => <div key={d} className="cal-dow">{d}</div>)}</div>
      {monthGrid(year, month).map((wk, wi) => (
        <div className="cal-week" key={wi} style={{ marginTop: 8 }}>
          {wk.map((d, di) => {
            if (!d) return <div key={di} className="cal-cell empty" />;
            const iso = d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
            const list = (sessionsByDate[iso] || []).sort((a, b) => a.time.localeCompare(b.time));
            const conf = conflicts[iso];
            return (
              <div key={di} className={'cal-cell' + (iso === todayISO ? ' today' : '') + (conf ? ' conflict' : '')}>
                <div className="cal-date">{d.getDate()}</div>
                {list.map((s, i) => {
                  const warn = conf && conf.includes(s.instructor);
                  return <div key={i} className={'cal-chip' + (warn ? ' warn' : '')} style={{ background: GROUP_C(s.cls.group) }} title={s.cls.courseName + ' · ' + s.time + ' · ' + AAU.instructorById(s.instructor).name + (warn ? ' · TRÙNG LỊCH GV' : '')} onClick={() => onOpenClass(s.cls)}>{s.time.split('–')[0]} {s.cls.cat}</div>;
                })}
              </div>
            );
          })}
        </div>
      ))}
    </Card>
  );

  return (
    <div className="col g16">
      <div className="row aic g16 wrap">
        <div className="callout-soft" style={conflictDays ? { background: 'var(--p-warning-bg)', color: '#5e4200' } : null}>
          <Icon name={conflictDays ? 'alert' : 'checkCircle'} size={15} />
          {conflictDays ? conflictDays + ' ngày có giảng viên đứng ≥2 buổi (viền cam) — kiểm tra tránh trùng' : 'Không có giảng viên bị trùng lịch'}
        </div>
        <div className="row aic g12 t11 subtle wrap">{AAU.courseGroups.map(g => <span key={g.id} className="row aic g4"><span style={{ width: 10, height: 10, borderRadius: 3, background: g.color, display: 'inline-block' }} />{g.label}</span>)}</div>
      </div>
      <Month year={2026} month={5} label="Tháng 6, 2026" />
      <Month year={2026} month={6} label="Tháng 7, 2026" />
    </div>
  );
}

Object.assign(window, { CourseCatalog, ClassesPage });
