/* global React, Icon, Avatar, Dropdown, Button */
// Schools.ArtemenkoCRM — Расписание (read-only mirror of teacher calendars,
// styled to match the teacher cabinet: warm bg, indigo/lavender tiles).
// Exports: Schedule (page), TeacherCalendar (embeddable), expandSchedule (helper).

const WDAYS = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'];
const WDAYS_MINI = ['П', 'В', 'С', 'Ч', 'П', 'С', 'В'];
const MONTHS_GEN = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'];
const MONTHS_NOM = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
const MONTHS_ABBR = ['янв', 'фев', 'мар', 'апр', 'мая', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
const HOUR_START = 0, HOUR_END = 23, HOUR_PX = 54;

// Teacher-cabinet design tokens (scoped to this section).
const T = {
  bg: '#faf6ef', bgSoft: '#f4efe5', card: '#ffffff', card2: '#fbf8f2', border: '#eae3d5',
  text: '#2a2622', text2: '#595048', dim: '#8a7f73', faint: '#b8ae9f',
  brand: '#3d3a8e', brandHover: '#5754ae', brandSoft: '#e8e6f7', brandInk: '#2d2b6e',
  lavSoft: '#e5e2f8', lavInk: '#4a4790',
  rSm: 6, rMd: 10, rLg: 14,
  shadow1: '0 1px 2px rgba(60,50,40,.04), 0 1px 1px rgba(60,50,40,.03)',
  shadow: '0 4px 12px rgba(60,50,40,.06), 0 2px 4px rgba(60,50,40,.04)',
};

function mondayOf(d) { const x = new Date(d); const dow = (x.getDay() + 6) % 7; x.setDate(x.getDate() - dow); x.setHours(0, 0, 0, 0); return x; }
const fmtH = (h) => `${String(Math.floor(h)).padStart(2, '0')}:${h % 1 ? '30' : '00'}`;
const sameDay = (a, b) => a.toDateString() === b.toDateString();

// Expand a teacher's weekly template into dated lesson rows across [fromISO, toISO].
// Returns rows with { ...event, dateISO, dateLabel, month, year, weekday }.
function expandSchedule(teacherId, fromISO, toISO) {
  const tmpl = (window.CRM_DATA.SCHEDULE && window.CRM_DATA.SCHEDULE[teacherId]) || [];
  if (!tmpl.length) return [];
  const from = new Date(fromISO + 'T00:00:00');
  const to = new Date(toISO + 'T00:00:00');
  const out = [];
  for (let d = new Date(from); d <= to; d.setDate(d.getDate() + 1)) {
    const dow = (d.getDay() + 6) % 7;
    const y = d.getFullYear(), m = d.getMonth(), day = d.getDate();
    tmpl.filter(e => e.day === dow).forEach(e => {
      out.push({ ...e, dateISO: `${y}-${String(m + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`, dateLabel: `${day} ${MONTHS_ABBR[m]}`, month: m, year: y, weekday: dow });
    });
  }
  return out;
}

function TCard({ children, style }) {
  return <div style={{ background: T.card, border: '1px solid ' + T.border, borderRadius: T.rLg, boxShadow: T.shadow1, ...style }}>{children}</div>;
}

function MiniCal({ weekStart, today, onPick }) {
  const [vm, setVm] = React.useState(new Date(weekStart.getFullYear(), weekStart.getMonth(), 1));
  React.useEffect(() => { setVm(new Date(weekStart.getFullYear(), weekStart.getMonth(), 1)); }, [weekStart.getFullYear(), weekStart.getMonth()]);
  const y = vm.getFullYear(), m = vm.getMonth();
  const firstDow = (new Date(y, m, 1).getDay() + 6) % 7;
  const days = new Date(y, m + 1, 0).getDate();
  const weekDays = Array.from({ length: 7 }, (_, i) => { const d = new Date(weekStart); d.setDate(d.getDate() + i); return d; });
  const inWeek = (d) => weekDays.some(w => sameDay(w, d));
  const nav = (delta) => setVm(new Date(y, m + delta, 1));
  return (
    <TCard style={{ padding: 16, overflow: 'hidden' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
        <span style={{ fontSize: 12.5, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', color: T.text2 }}>{MONTHS_NOM[m]} {y}</span>
        <div style={{ display: 'flex', gap: 2 }}>
          <button onClick={() => nav(-1)} className="sch-nav" style={miniNavBtn}>‹</button>
          <button onClick={() => nav(1)} className="sch-nav" style={miniNavBtn}>›</button>
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, minmax(0, 1fr))', gap: 2, marginBottom: 4 }}>
        {WDAYS_MINI.map((w, i) => <div key={i} style={{ textAlign: 'center', fontSize: 10, fontWeight: 700, color: T.faint, minWidth: 0 }}>{w}</div>)}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, minmax(0, 1fr))', gap: 2 }}>
        {(() => {
          const cells = [];
          const prevDays = new Date(y, m, 0).getDate();
          for (let i = 0; i < firstDow; i++) cells.push(new Date(y, m - 1, prevDays - firstDow + 1 + i));
          for (let i = 1; i <= days; i++) cells.push(new Date(y, m, i));
          while (cells.length % 7) cells.push(new Date(y, m + 1, cells.length - firstDow - days + 1));
          return cells.map((d, i) => {
            const isToday = sameDay(d, today), wk = inWeek(d), other = d.getMonth() !== m;
            return (
              <button key={i} onClick={() => onPick(d)} className="mini-day" style={{
                height: 28, minWidth: 0, padding: 0, overflow: 'hidden', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 12,
                fontWeight: isToday ? 700 : 500, borderRadius: 7,
                background: isToday ? T.brand : wk ? T.brandSoft : 'transparent',
                color: isToday ? '#fff' : other ? T.faint : wk ? T.brandInk : T.text,
              }}>{d.getDate()}</button>
            );
          });
        })()}
      </div>
    </TCard>
  );
}
const miniNavBtn = { width: 24, height: 24, borderRadius: 6, border: '1px solid ' + T.border, background: T.card, cursor: 'pointer', color: T.dim, fontSize: 14, lineHeight: 1 };

// Reusable teacher calendar (nav row + rail + week/month grid). Caller provides the
// outer warm-bg container. `embedded` trims the stats card + notes panel for cards.
function TeacherCalendar({ teacherId, today, embedded, onToast }) {
  const { SCHEDULE, LESSON_STATUS } = window.CRM_DATA;
  const tday = today || new Date(2026, 4, 31);
  const [weekStart, setWeekStart] = React.useState(mondayOf(today || new Date(2026, 4, 25)));
  const [statuses, setStatuses] = React.useState([]); // мультивыбор статусов проведения; [] = все
  const [mode, setMode] = React.useState('week');
  const [slide, setSlide] = React.useState('');
  const toast = onToast || (() => {});
  // Сетка дня — полные сутки 00:00–23:59; при открытии прокручиваем к рабочим часам (08:00).
  const weekScrollRef = React.useRef(null);
  React.useEffect(() => {
    if (mode === 'week' && weekScrollRef.current) weekScrollRef.current.scrollTop = (8 - HOUR_START) * HOUR_PX;
  }, [mode, teacherId]);

  // Реальные занятия преподавателя — из API (GET /teachers/:id/lessons за окно ±3 мес).
  const teacherName = (() => { const s = (window.CRM_DATA.STAFF || []).find(x => x.id === teacherId); return s ? s.name : null; })();
  const [realEvents, setRealEvents] = React.useState([]);
  React.useEffect(() => {
    if (teacherId == null || !window.apiCall) { setRealEvents([]); return; }
    let alive = true;
    const iso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
    const from = new Date(); from.setMonth(from.getMonth() - 3);
    const to = new Date(); to.setMonth(to.getMonth() + 3);
    window.apiCall('/teachers/' + teacherId + '/lessons?from=' + iso(from) + '&to=' + iso(to))
      .then((r) => { if (alive) setRealEvents(r.lessons || []); })
      .catch(() => { if (alive) setRealEvents([]); });
    return () => { alive = false; };
  }, [teacherId]);
  // Статус ПРОВЕДЕНИЯ занятия (для админа: насколько упорядочен график) — не статус оплаты.
  //  conducted = занятие состоялось (Оплачено/В долг → «Проведено»), noshow, cancelled, planned.
  const conductOf = (st) => (st === 'paid' || st === 'debt') ? 'conducted' : st;
  const CONDUCT = {
    conducted: { label: 'Проведено', dot: 'var(--green)', bd: '#00b48f', bg: 'rgba(0,180,143,0.16)', fg: '#047358' },
    noshow: { label: 'Не пришёл', dot: '#ec9b2a', bd: '#ec9b2a', bg: 'rgba(236,155,42,0.18)', fg: '#8a5408' },
    cancelled: { label: 'Отменено', dot: '#ef4467', bd: '#ef4467', bg: 'rgba(239,68,103,0.14)', fg: '#9b1737' },
    planned: { label: 'Запланировано', dot: '#6d52ff', bd: '#6d52ff', bg: 'rgba(109,82,255,0.14)', fg: '#3a2a99' },
  };
  const CONDUCT_KEYS = ['conducted', 'noshow', 'cancelled', 'planned'];
  const events = realEvents.filter(e => !statuses.length || statuses.indexOf(conductOf(e.status)) >= 0);
  const toggleStatus = (k) => setStatuses(s => s.indexOf(k) >= 0 ? s.filter(x => x !== k) : [...s, k]);
  const isoOf = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;

  const weekEnd = new Date(weekStart); weekEnd.setDate(weekEnd.getDate() + 6);
  const days = Array.from({ length: 7 }, (_, i) => { const d = new Date(weekStart); d.setDate(d.getDate() + i); return d; });

  const nav = (delta) => { setSlide(delta > 0 ? 'l' : 'r'); const d = new Date(weekStart); d.setDate(d.getDate() + delta * 7); setWeekStart(d); setTimeout(() => setSlide(''), 260); };
  const goToday = () => setWeekStart(mondayOf(tday));
  const pickDay = (d) => setWeekStart(mondayOf(d));

  // Статистика боковой панели — по занятиям ТЕКУЩЕЙ недели (реальные даты).
  const weekISOs = days.map(isoOf);
  const all = realEvents.filter(e => weekISOs.indexOf(e.dateISO) >= 0);
  const lessons = all.length;
  const hours = all.reduce((a, e) => a + (e.end - e.start), 0);
  const counts = { conducted: 0, noshow: 0, cancelled: 0, planned: 0 };
  all.forEach(e => { const k = conductOf(e.status); if (counts[k] != null) counts[k]++; });

  const titleRange = `${weekStart.getDate()} — ${weekEnd.getDate()} ${MONTHS_GEN[weekEnd.getMonth()]}`;
  const monthLabel = MONTHS_NOM[weekStart.getMonth()] + ' ' + weekStart.getFullYear();
  const hourRows = Array.from({ length: HOUR_END - HOUR_START + 1 }, (_, i) => HOUR_START + i);
  const todayInWeek = tday >= weekStart && tday <= new Date(weekEnd.getFullYear(), weekEnd.getMonth(), weekEnd.getDate(), 23, 59);
  const centerMax = embedded ? 520 : 'calc(100vh - 248px)';
  const railW = embedded ? 212 : 230;

  return (
    <React.Fragment>
      {/* Nav row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap', marginBottom: 16, background: T.card, border: '1px solid ' + T.border, borderRadius: T.rLg, boxShadow: T.shadow1, padding: '12px 16px' }}>
        <button onClick={goToday} className="sch-nav" style={{ padding: '7px 15px', borderRadius: T.rSm, border: '1px solid ' + T.border, background: T.card, cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 13.5, fontWeight: 600, color: T.text2, boxShadow: T.shadow1 }}>Сегодня</button>
        <div style={{ display: 'flex', gap: 4 }}>
          {['‹', '›'].map((c, i) => <button key={c} onClick={() => nav(i === 0 ? -1 : 1)} className="sch-nav" style={{ width: 32, height: 32, borderRadius: T.rSm, border: '1px solid ' + T.border, background: T.card, cursor: 'pointer', color: T.text2, fontSize: 18, lineHeight: 1 }}>{c}</button>)}
        </div>
        <div style={{ flex: 'none', minWidth: 132 }}>
          <div style={{ fontSize: 18, fontWeight: 800, letterSpacing: '-0.4px', color: T.text, whiteSpace: 'nowrap' }}>{monthLabel}</div>
          <div style={{ fontSize: 11.5, color: T.dim, textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 700, whiteSpace: 'nowrap' }}>{titleRange}</div>
        </div>
        <div style={{ flex: 1 }} />
        <div style={{ display: 'inline-flex', background: T.bgSoft, borderRadius: T.rSm, padding: 3, gap: 2 }}>
          {[{ id: 'week', label: 'Неделя' }, { id: 'month', label: 'Месяц' }].map(t => (
            <button key={t.id} onClick={() => setMode(t.id)} style={{
              padding: '6px 16px', border: 'none', borderRadius: 5, cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: 600,
              background: mode === t.id ? T.card : 'transparent', color: mode === t.id ? T.brandInk : T.dim, boxShadow: mode === t.id ? T.shadow1 : 'none',
              transition: 'background 160ms, color 160ms',
            }}>{t.label}</button>
          ))}
        </div>
      </div>

      <div style={{ display: 'flex', gap: embedded ? 12 : 16, alignItems: 'flex-start' }}>
        {/* Left rail */}
        <div style={{ width: railW, flex: 'none', display: 'flex', flexDirection: 'column', gap: 14 }}>
          <MiniCal weekStart={weekStart} today={tday} onPick={pickDay} />
          {!embedded && (
            <TCard style={{ padding: 16 }}>
              <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: T.dim, marginBottom: 12 }}>Эта неделя</div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                <Stat label="Занятий" value={lessons} />
                <Stat label="Часов" value={hours} />
                <Stat label="Доход" value="0 ₽" small />
                <Stat label="Свободно" value={`${147} ч`} small />
              </div>
            </TCard>
          )}
          <TCard style={{ padding: 16 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
              <span style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: T.dim }}>Статусы</span>
              {statuses.length > 0 && <button onClick={() => setStatuses([])} style={{ border: 'none', background: 'none', cursor: 'pointer', color: T.brand, fontSize: 12, fontWeight: 600 }}>сбросить</button>}
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              {CONDUCT_KEYS.map(k => {
                const s = CONDUCT[k]; const on = statuses.indexOf(k) >= 0;
                return (
                  <button key={k} onClick={() => toggleStatus(k)} style={{
                    display: 'flex', alignItems: 'center', gap: 9, padding: '7px 8px', border: 'none', cursor: 'pointer',
                    borderRadius: T.rSm, background: on ? T.bgSoft : 'transparent', textAlign: 'left',
                    fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: on ? 600 : 500, color: T.text2, transition: 'background 140ms',
                  }}>
                    <span style={{ width: 16, height: 16, borderRadius: 4, flex: 'none', border: '1.5px solid ' + (on ? s.bd : T.border), background: on ? s.bd : 'transparent', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>{on && <Icon name="check" size={11} strokeWidth={3} style={{ color: '#fff' }} />}</span>
                    <span style={{ width: 9, height: 9, borderRadius: '50%', background: s.dot, flex: 'none' }} />
                    <span style={{ flex: 1 }}>{s.label}</span>
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: T.dim }}>{counts[k]}</span>
                  </button>
                );
              })}
            </div>
          </TCard>
        </div>

        {/* Center: week or month */}
        <TCard style={{ flex: 1, overflow: 'hidden', minWidth: 0 }}>
          {mode === 'week' ? (
            <div ref={weekScrollRef} className="cal-scroll" style={{ overflowX: 'auto', overflowY: 'auto', maxHeight: centerMax }}>
              <div style={{ minWidth: 760 }}>
                <div style={{ display: 'grid', gridTemplateColumns: '52px repeat(7, 1fr)', borderBottom: '1px solid ' + T.border, position: 'sticky', top: 0, background: T.card2, zIndex: 4 }}>
                  <div style={{ padding: '12px 0', fontSize: 10, fontWeight: 700, color: T.dim, textAlign: 'center' }}>ВРЕМЯ</div>
                  {days.map((d, i) => {
                    const isToday = sameDay(d, tday);
                    return (
                      <div key={i} style={{ padding: '9px 4px', textAlign: 'center', borderLeft: '1px solid ' + T.border }}>
                        <div style={{ fontSize: 10, fontWeight: 700, color: isToday ? T.brand : T.dim }}>{WDAYS[i]}</div>
                        <div style={{ marginTop: 3, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 26, height: 26, borderRadius: '50%', fontSize: 14, fontWeight: 700, color: isToday ? '#fff' : T.text, background: isToday ? T.brand : 'transparent' }}>{d.getDate()}</div>
                      </div>
                    );
                  })}
                </div>
                <div className={slide ? (slide === 'l' ? 'om-slide-l' : 'om-slide-r') : ''} style={{ display: 'grid', gridTemplateColumns: '52px repeat(7, 1fr)' }}>
                  <div>
                    {hourRows.map(h => <div key={h} style={{ height: HOUR_PX, fontSize: 11, color: T.faint, fontFamily: 'var(--font-mono)', textAlign: 'right', paddingRight: 7, transform: 'translateY(-6px)' }}>{fmtH(h)}</div>)}
                  </div>
                  {days.map((d, di) => {
                    const isToday = sameDay(d, tday);
                    return (
                    <div key={di} style={{ position: 'relative', borderLeft: '1px solid ' + T.border, background: isToday ? 'rgba(61,58,142,0.025)' : 'transparent' }}>
                      {hourRows.map(h => <div key={h} style={{ height: HOUR_PX, borderTop: h === HOUR_START ? 'none' : '1px solid ' + T.border }} />)}
                      {todayInWeek && isToday && (
                        <div style={{ position: 'absolute', left: 0, right: 0, top: (13.5 - HOUR_START) * HOUR_PX, height: 2, background: '#ef4467', zIndex: 3 }}>
                          <span style={{ position: 'absolute', left: -4, top: -3, width: 8, height: 8, borderRadius: '50%', background: '#ef4467' }} />
                        </div>
                      )}
                      {events.filter(e => e.dateISO === isoOf(d)).map((e, ei) => {
                        const s = LESSON_STATUS[e.status];
                        const top = (e.start - HOUR_START) * HOUR_PX;
                        const h = (e.end - e.start) * HOUR_PX;
                        const strike = e.status === 'cancelled';
                        return (
                          <div key={ei} title={`${fmtH(e.start)}–${fmtH(e.end)} · ${e.who} · ${s.label}`} className="cal-ev cal-ev-in"
                            onClick={() => toast(`${e.who} · ${fmtH(e.start)}–${fmtH(e.end)} · ${s.label}`)}
                            style={{
                              position: 'absolute', top: top + 1, left: 3, right: 3, height: h - 2, overflow: 'hidden',
                              background: s.bg, borderLeft: '3px solid ' + s.bd, borderRadius: T.rSm, padding: '4px 7px',
                              boxSizing: 'border-box', cursor: 'pointer', opacity: strike ? 0.7 : 1, animationDelay: Math.min(ei * 35, 350) + 'ms',
                              transition: 'transform 120ms var(--ease), box-shadow 120ms var(--ease)',
                            }}
                            onMouseEnter={ev => { ev.currentTarget.style.transform = 'translateY(-1px)'; ev.currentTarget.style.boxShadow = T.shadow; }}
                            onMouseLeave={ev => { ev.currentTarget.style.transform = 'none'; ev.currentTarget.style.boxShadow = 'none'; }}>
                            <div style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: s.fg, opacity: 0.8, textDecoration: strike ? 'line-through' : 'none' }}>{fmtH(e.start)} — {fmtH(e.end)}</div>
                            <div style={{ fontSize: 12, fontWeight: 600, color: s.fg, marginTop: 1, display: 'flex', alignItems: 'center', gap: 4, textDecoration: strike ? 'line-through' : 'none' }}>
                              <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 }}>{e.who}</span>
                              {e.group && <span style={{ fontSize: 9, fontWeight: 700, padding: '0 4px', borderRadius: 3, background: T.lavSoft, color: T.lavInk, flex: 'none' }}>гр</span>}
                            </div>
                          </div>
                        );
                      })}
                    </div>
                    );
                  })}
                </div>
              </div>
            </div>
          ) : (
            <MonthView weekStart={weekStart} today={tday} events={events} LESSON_STATUS={LESSON_STATUS} onPickWeek={(d) => { setWeekStart(mondayOf(d)); setMode('week'); }} />
          )}
        </TCard>

        {/* Right: notes (full page only) */}
        {!embedded && (
          <div style={{ width: 210, flex: 'none' }}>
            <TCard style={{ padding: 18, textAlign: 'center' }}>
              <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: T.dim, textAlign: 'left', marginBottom: 14 }}>Заметки на неделю</div>
              <div style={{ width: 40, height: 40, borderRadius: 10, background: T.bgSoft, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: T.faint, marginBottom: 10 }}>
                <Icon name="sticky-note" size={20} />
              </div>
              <div style={{ fontSize: 13, fontWeight: 600, color: T.text2 }}>Заметок нет</div>
              <div style={{ fontSize: 12, color: T.dim, marginTop: 4, lineHeight: 1.45 }}>Преподаватель ведёт заметки в своём кабинете — здесь они только просматриваются.</div>
            </TCard>
          </div>
        )}
      </div>
    </React.Fragment>
  );
}

function Schedule({ onToast }) {
  const { STAFF } = window.CRM_DATA;
  const teachers = STAFF.filter(s => s.role === 'teacher' && s.status !== 'fired');
  const [teacherId, setTeacherId] = React.useState(teachers[0] ? teachers[0].id : null);
  const teacher = STAFF.find(s => s.id === teacherId);

  return (
    <div style={{ background: T.bg, minHeight: '100%', padding: '18px 24px 36px', fontFamily: 'var(--font-sans)', color: T.text }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap', marginBottom: 16 }}>
        <div style={{ minWidth: 260 }}>
          <Dropdown value={teacherId} onChange={setTeacherId} width={260} searchable
            options={teachers.map(t => ({ value: t.id, label: t.name }))} placeholder="Преподаватель" />
        </div>
        {teacher && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <Avatar animal={teacher.animal} tone={teacher.tone} size={34} />
            <div>
              <div style={{ fontSize: 13.5, fontWeight: 600, color: T.text }}>{teacher.position}</div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: T.dim }}>{teacher.tg}</div>
            </div>
          </div>
        )}
        <div style={{ flex: 1 }} />
        <button onClick={() => onToast('Открываю кабинет преподавателя (интеграция)…')} style={{
          display: 'inline-flex', alignItems: 'center', gap: 7, padding: '9px 16px', borderRadius: T.rSm, cursor: 'pointer',
          background: T.brand, color: '#fff', border: 'none', fontFamily: 'var(--font-sans)', fontSize: 14, fontWeight: 600,
          boxShadow: 'inset 0 -2px 0 rgba(20,16,60,0.3)', transition: 'background 140ms',
        }} onMouseEnter={e => e.currentTarget.style.background = T.brandHover} onMouseLeave={e => e.currentTarget.style.background = T.brand}>
          <Icon name="external-link" size={16} />Перейти в аккаунт
        </button>
      </div>

      <TeacherCalendar key={teacherId} teacherId={teacherId} today={new Date()} onToast={onToast} />
    </div>
  );
}

function Stat({ label, value, small }) {
  return (
    <div>
      <div style={{ fontSize: 10.5, color: T.dim, textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 700 }}>{label}</div>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: small ? 16 : 22, fontWeight: 700, marginTop: 3, color: T.text }}>{value}</div>
    </div>
  );
}

function MonthView({ weekStart, today, events, LESSON_STATUS, onPickWeek }) {
  const y = weekStart.getFullYear(), m = weekStart.getMonth();
  const firstDow = (new Date(y, m, 1).getDay() + 6) % 7;
  const days = new Date(y, m + 1, 0).getDate();
  // map events to day-of-month via their weekday within the current week (approx demo)
  const cells = [];
  for (let i = 0; i < firstDow; i++) cells.push(null);
  for (let d = 1; d <= days; d++) cells.push(d);
  while (cells.length % 7) cells.push(null);
  const evForDom = (dom) => { const iso = `${y}-${String(m + 1).padStart(2, '0')}-${String(dom).padStart(2, '0')}`; return events.filter(e => e.dateISO === iso); };
  return (
    <div style={{ padding: 4 }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, minmax(0, 1fr))' }}>
        {WDAYS.map((w, i) => <div key={i} style={{ padding: '10px 0', textAlign: 'center', fontSize: 10.5, fontWeight: 700, color: T.dim, borderBottom: '1px solid ' + T.border }}>{w}</div>)}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, minmax(0, 1fr))' }}>
        {cells.map((dom, i) => {
          const isToday = dom && sameDay(new Date(y, m, dom), today);
          const evs = dom ? evForDom(dom) : [];
          return (
            <div key={i} onClick={() => dom && onPickWeek(new Date(y, m, dom))} style={{
              minHeight: 96, borderLeft: '1px solid ' + T.border, borderBottom: '1px solid ' + T.border, padding: 6,
              cursor: dom ? 'pointer' : 'default', background: dom ? T.card : T.card2,
            }}>
              {dom && <div style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 22, height: 22, borderRadius: '50%', fontSize: 12, fontWeight: 700, color: isToday ? '#fff' : T.text2, background: isToday ? T.brand : 'transparent', marginBottom: 4 }}>{dom}</div>}
              <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                {evs.slice(0, 3).map((e, ei) => { const s = LESSON_STATUS[e.status]; return (
                  <div key={ei} style={{ fontSize: 10.5, fontWeight: 600, color: s.fg, background: s.bg, borderLeft: '2px solid ' + s.bd, borderRadius: 3, padding: '1px 5px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{fmtH(e.start)} {e.who}</div>
                ); })}
                {evs.length > 3 && <div style={{ fontSize: 10.5, color: T.dim, fontWeight: 600, paddingLeft: 5 }}>+{evs.length - 3} ещё</div>}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { Schedule, TeacherCalendar, expandSchedule, SCHED_TOKENS: T });
