// Lynxe — extra pages & overlays:
// SubjectPage, LecturePage, AccountPage, NotificationsPanel, SearchPalette

const { useState: xUseState, useEffect: xUseEffect, useMemo: xUseMemo, useRef: xUseRef } = React;

/* ============== SUBJECT PAGE ============== */
function SubjectPage({ subjectId, goto }) {
  const subject = SUBJ_BY_ID[subjectId];
  if (!subject) return (
    <>
      <Topbar crumbs={['Subjects', 'Unknown']} />
      <div className="content"><div className="empty">Subject not found.</div></div>
    </>
  );

  const lectures = LECTURES.filter(l => l.subject === subjectId);
  const missions = MISSIONS.filter(m => m.subject === subjectId);
  const posts = CLASSROOM_POSTS.filter(p => p.subject === subjectId);
  const tasks = TODAY_TASKS.filter(t => t.subject === subjectId);

  return (
    <>
      <Topbar
        crumbs={[
          <span key="b" style={{ cursor: 'pointer' }} onClick={() => goto('dashboard')}>Subjects</span>,
          subject.short || subject.name,
        ]}
        actions={<>
          <button className="btn ghost" onClick={() => goto('new-lecture', { subject: subjectId })}>
            <I.Plus size={11} /> New lecture
          </button>
        </>}
      />
      <div className="content">
        <div style={{ maxWidth: 980, margin: '0 auto', padding: '32px 28px 80px' }}>
          <div className="hstack" style={{ gap: 10, marginBottom: 6 }}>
            <span className="subj-dot" style={{ background: subject.hex, width: 10, height: 10 }} />
            <div style={{ fontSize: 24, fontWeight: 500, letterSpacing: '-0.02em' }}>{subject.name}</div>
          </div>
          <div className="muted" style={{ fontSize: 13, marginBottom: 24 }}>
            {lectures.length} lecture{lectures.length===1?'':'s'} · {missions.length} mission{missions.length===1?'':'s'} · {posts.length} classroom post{posts.length===1?'':'s'}
          </div>

          {missions.length > 0 && (
            <Section title="Missions">
              <div className="mission-grid">
                {missions.map(m => (
                  <div key={m.id} className="mission-card" onClick={() => goto('mission', { id: m.id })}>
                    <div className="hstack" style={{ marginBottom: 8, gap: 6 }}>
                      <Badge>{m.type}</Badge>
                      <span style={{ marginLeft: 'auto', fontSize: 11.5, color: m.daysLeft <= 7 ? 'var(--warn)' : 'var(--fg-3)' }}>{m.daysLeft}d</span>
                    </div>
                    <div style={{ fontSize: 13, fontWeight: 500, marginBottom: 4 }}>{m.title}</div>
                    <div className="muted" style={{ fontSize: 11.5, lineHeight: 1.5, marginBottom: 12, minHeight: 32 }}>{m.description}</div>
                    <div className="progress"><div className="progress-fill" style={{ width: `${m.progress*100}%` }} /></div>
                  </div>
                ))}
              </div>
            </Section>
          )}

          <Section title="Lectures">
            {lectures.length === 0
              ? <div className="empty">No lectures recorded yet.</div>
              : lectures.map(l => (
                  <div key={l.id} className="lec-row" onClick={() => openNotion(l.notionUrl)}>
                    <div className="bar" style={{ background: subject.hex }} />
                    <div style={{ minWidth: 0 }}>
                      <div className="lec-title ellipsis">{l.title}</div>
                      <div className="lec-meta" style={{ marginTop: 3 }}>
                        <span>{l.date}</span><span className="faint">·</span><span>{l.duration}</span>
                      </div>
                    </div>
                    {l.status === 'processing'
                      ? <span className="hstack dim" style={{ fontSize: 11, gap: 5 }}><span className="spinner" /> Processing</span>
                      : <span className="badge"><span className="nc-mark" style={{ width: 9, height: 9, fontSize: 7 }}>N</span> Notion</span>}
                    <I.External size={11} className="faint" />
                  </div>
                ))
            }
          </Section>

          <Section title="Recent classroom posts">
            {posts.length === 0
              ? <div className="empty">No posts yet.</div>
              : posts.slice(0, 6).map(p => (
                  <div key={p.id} className="lec-row" style={{ gridTemplateColumns: '2px 1fr auto auto' }} onClick={() => goto('classroom', { focus: p.id })}>
                    <div className="bar" style={{ background: subject.hex }} />
                    <div style={{ minWidth: 0 }}>
                      <div className="lec-title ellipsis">{p.title}</div>
                      <div className="lec-meta" style={{ marginTop: 3 }}><span>{p.teacher}</span><span className="faint">·</span><span>{p.date}</span></div>
                    </div>
                    <Badge>{p.type}</Badge>
                    <I.ChevronRight size={12} className="faint" />
                  </div>
                ))
            }
          </Section>
        </div>
      </div>
    </>
  );
}

function Section({ title, children }) {
  return (
    <div style={{ marginBottom: 28 }}>
      <div style={{ fontSize: 11, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 500, marginBottom: 8 }}>{title}</div>
      {children}
    </div>
  );
}

/* ============== LECTURE PAGE — REMOVED ==============
   Lecture notes now open directly in Notion. We keep this stub so any stale
   route still resolves cleanly (immediately bouncing to Notion).
*/
function LecturePage({ lectureId, goto }) {
  const lecture = LECTURES.find(l => l.id === lectureId);
  xUseEffect(() => {
    if (lecture && lecture.notionUrl) window.open(lecture.notionUrl, '_blank', 'noopener');
    goto('notes');
  }, []);
  return null;
}

/* ============== ACCOUNT PAGE ============== */
function AccountPage({ goto }) {
  const [name, setName] = xUseState('Sahishnu Y.');
  const [email, setEmail] = xUseState('sahishnu@lynxe.app');
  const [school, setSchool] = xUseState('Riverside High');
  const [year, setYear] = xUseState('Year 12');
  const [saved, setSaved] = xUseState(false);

  return (
    <>
      <Topbar
        crumbs={[
          <span key="b" style={{ cursor: 'pointer' }} onClick={() => goto('settings')}>Settings</span>,
          'Account',
        ]}
      />
      <div className="content">
        <div className="settings-page">
          <div style={{ marginBottom: 28 }}>
            <div style={{ fontSize: 22, fontWeight: 500, letterSpacing: '-0.018em' }}>Account</div>
            <div className="dim" style={{ fontSize: 12.5, marginTop: 2 }}>Manage your profile and identity.</div>
          </div>

          <div className="hstack" style={{ marginBottom: 24, gap: 14 }}>
            <div style={{ width: 60, height: 60, borderRadius: 30, background: 'var(--bg-3)', border: '1px solid var(--border-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20, fontWeight: 500 }}>SY</div>
            <div>
              <button className="btn">Upload photo</button>
              <div className="dim" style={{ fontSize: 11, marginTop: 6 }}>JPG or PNG, max 2 MB.</div>
            </div>
          </div>

          <div className="settings-section" style={{ paddingTop: 0, borderTop: 'none', marginTop: 0 }}>
            <div className="settings-section-title">Profile</div>
            <FormRow label="Name"><input className="input" value={name} onChange={e => { setName(e.target.value); setSaved(false); }} /></FormRow>
            <FormRow label="Email"><input className="input" value={email} onChange={e => { setEmail(e.target.value); setSaved(false); }} /></FormRow>
            <FormRow label="School"><input className="input" value={school} onChange={e => { setSchool(e.target.value); setSaved(false); }} /></FormRow>
            <FormRow label="Year level">
              <select className="input" value={year} onChange={e => { setYear(e.target.value); setSaved(false); }}>
                {['Year 7','Year 8','Year 9','Year 10','Year 11','Year 12'].map(y => <option key={y}>{y}</option>)}
              </select>
            </FormRow>
          </div>

          <div className="hstack" style={{ marginTop: 18, gap: 8 }}>
            <button className="btn primary" onClick={() => setSaved(true)}>Save changes</button>
            <button className="btn ghost" onClick={() => goto('settings')}>Cancel</button>
            {saved && <span className="hstack dim" style={{ fontSize: 12, gap: 4, color: 'var(--ok)' }}><I.Check size={11} strokeWidth={2.6} /> Saved</span>}
          </div>
        </div>
      </div>
    </>
  );
}

function FormRow({ label, children }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '140px 1fr', gap: 16, alignItems: 'center', padding: '10px 0', borderBottom: '1px solid var(--border)' }}>
      <div className="dim" style={{ fontSize: 12.5 }}>{label}</div>
      <div>{children}</div>
    </div>
  );
}

/* ============== NOTIFICATIONS PANEL ============== */
function NotificationsPanel({ onClose, goto }) {
  const [items, setItems] = xUseState(() => buildNotifications());
  const [loading, setLoading] = xUseState(
    () => !window.MISSIONS?.length && !window.CLASSROOM_POSTS?.length && !window.LECTURES?.length
  );

  xUseEffect(() => {
    if (!loading) return;
    Promise.all([
      fnGetCached('missions').then(r => { window.MISSIONS = (r.missions || []).map(transformMission); }),
      fnGetCached('lecture-sessions').then(r => { window.LECTURES = (r.sessions || []).map(transformLecture); }),
      dbGetCached('classroom_posts?order=synced_at.desc&limit=100').then(rows => { window.CLASSROOM_POSTS = rows.map(transformPost); }),
      fnGetCached('today-tasks').then(r => { window.TODAY_TASKS = (r.tasks || []).map(transformTask); }),
    ])
      .catch(() => {})
      .finally(() => { setItems(buildNotifications()); setLoading(false); });
  }, []);

  const handleClick = (n) => {
    onClose();
    if (n.external) window.open(n.externalUrl, '_blank', 'noopener');
    else goto(n.route[0], n.route[1]);
  };

  return (
    <>
      <div className="orch-overlay" onClick={onClose} />
      <div className="orch-panel">
        <div className="mv-col-head" style={{ height: 40 }}>
          <span className="hstack" style={{ gap: 6, color: 'var(--fg)', textTransform: 'none', letterSpacing: 0, fontSize: 12.5, fontWeight: 500 }}>
            <I.Bell size={12} /> Notifications
          </span>
          <button className="icon-btn" style={{ marginLeft: 'auto' }} onClick={onClose}><I.X size={12} /></button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto' }}>
          {loading && <div className="empty" style={{ padding: 32 }}><span className="spinner" /> Loading&hellip;</div>}
          {!loading && items.map(n => {
            const Icon = I[n.icon] || I.Bell;
            const subj = SUBJ_BY_ID[n.subject];
            return (
              <div
                key={n.id}
                className="hstack"
                style={{ padding: '11px 14px', borderBottom: '1px solid var(--border)', gap: 10, cursor: 'pointer', alignItems: 'flex-start' }}
                onClick={() => handleClick(n)}
              >
                <div style={{ width: 24, height: 24, borderRadius: 6, background: 'var(--bg-2)', border: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, color: 'var(--fg-2)' }}>
                  <Icon size={12} />
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="hstack" style={{ gap: 6 }}>
                    {subj && <span className="subj-dot" style={{ background: subj.hex }} />}
                    <span style={{ fontSize: 12.5, fontWeight: 500 }} className="ellipsis">{n.title}</span>
                    {n.time && <span className="dim" style={{ fontSize: 10.5, marginLeft: 'auto', flexShrink: 0 }}>{n.time}</span>}
                  </div>
                  <div className="dim" style={{ fontSize: 12, marginTop: 2, lineHeight: 1.45 }}>{n.body}</div>
                </div>
              </div>
            );
          })}
          {!loading && items.length === 0 && (
            <div className="empty" style={{ padding: 48 }}>All caught up.</div>
          )}
        </div>
      </div>
    </>
  );
}

/* ============== SEARCH PALETTE (⌘K) ============== */
function SearchPalette({ onClose, goto }) {
  const [q, setQ] = xUseState('');
  const [sel, setSel] = xUseState(0);
  const inputRef = xUseRef(null);

  xUseEffect(() => { inputRef.current && inputRef.current.focus(); }, []);

  const all = xUseMemo(() => {
    const out = [];
    out.push({ kind: 'page', label: 'Dashboard',   icon: 'Today',    route: ['dashboard']  });
    out.push({ kind: 'page', label: 'Today',       icon: 'Today',    route: ['today']      });
    out.push({ kind: 'page', label: 'Notes',       icon: 'Note',     route: ['notes']      });
    out.push({ kind: 'page', label: 'Classroom',   icon: 'Class',    route: ['classroom']  });
    out.push({ kind: 'page', label: 'Missions',    icon: 'Mission',  route: ['missions']   });
    out.push({ kind: 'page', label: 'Settings',    icon: 'Settings', route: ['settings']   });
    out.push({ kind: 'action', label: 'Start a new lecture', icon: 'Mic', route: ['new-lecture'] });
    VISIBLE_SUBJECTS.forEach(s => out.push({ kind: 'subject', label: s.name, icon: 'Folder', subjectHex: s.hex, route: ['subject', { id: s.id }] }));
    LECTURES.forEach(l => { const s = SUBJ_BY_ID[l.subject] || SUBJ_BY_ID.maths; out.push({ kind: 'lecture', label: l.title, sub: s.short + ' · ' + l.date + ' · Notion', subjectHex: s.hex, icon: 'External', external: true, externalUrl: l.notionUrl }); });
    MISSIONS.forEach(m => { const s = SUBJ_BY_ID[m.subject] || SUBJ_BY_ID.maths; out.push({ kind: 'mission', label: m.title, sub: s.short + ' · due ' + m.due, subjectHex: s.hex, icon: 'Mission', route: ['mission', { id: m.id }] }); });
    CLASSROOM_POSTS.forEach(p => { const s = SUBJ_BY_ID[p.subject] || SUBJ_BY_ID.maths; out.push({ kind: 'post', label: p.title, sub: s.short + ' · ' + p.teacher, subjectHex: s.hex, icon: 'Class', route: ['classroom', { focus: p.id }] }); });
    return out;
  }, []);

  const filtered = xUseMemo(() => {
    if (!q.trim()) return all.slice(0, 12);
    const t = q.toLowerCase();
    return all.filter(x => x.label.toLowerCase().includes(t) || (x.sub || '').toLowerCase().includes(t)).slice(0, 20);
  }, [q, all]);

  xUseEffect(() => { setSel(0); }, [q]);

  const choose = (i) => {
    const it = filtered[i];
    if (!it) return;
    onClose();
    if (it.external) window.open(it.externalUrl, '_blank', 'noopener');
    else goto(it.route[0], it.route[1]);
  };

  const onKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setSel(s => Math.min(s + 1, filtered.length - 1)); }
    else if (e.key === 'ArrowUp') { e.preventDefault(); setSel(s => Math.max(s - 1, 0)); }
    else if (e.key === 'Enter') { e.preventDefault(); choose(sel); }
    else if (e.key === 'Escape') { onClose(); }
  };

  // Group by kind
  const groups = xUseMemo(() => {
    const order = ['page', 'action', 'subject', 'mission', 'lecture', 'post'];
    const labels = { page: 'Pages', action: 'Actions', subject: 'Subjects', mission: 'Missions', lecture: 'Lectures', post: 'Classroom posts' };
    const map = {};
    filtered.forEach((it, idx) => { (map[it.kind] = map[it.kind] || []).push({ ...it, idx }); });
    return order.filter(k => map[k]).map(k => ({ key: k, label: labels[k], items: map[k] }));
  }, [filtered]);

  return (
    <div className="overlay" onClick={onClose} style={{ alignItems: 'flex-start', paddingTop: '12vh' }}>
      <div className="panel" style={{ width: 540, maxWidth: '92vw' }} onClick={e => e.stopPropagation()}>
        <div className="hstack" style={{ padding: '10px 12px', borderBottom: '1px solid var(--border)', gap: 8 }}>
          <I.Search size={13} className="dim" />
          <input
            ref={inputRef}
            value={q}
            onChange={e => setQ(e.target.value)}
            onKeyDown={onKey}
            placeholder="Search Lynxe&hellip;"
            style={{ flex: 1, fontSize: 14 }}
          />
          <span className="kbd">Esc</span>
        </div>
        <div style={{ maxHeight: 420, overflowY: 'auto', padding: 4 }}>
          {filtered.length === 0 && <div className="empty">No results.</div>}
          {groups.map(g => (
            <div key={g.key} style={{ marginBottom: 4 }}>
              <div style={{ padding: '8px 10px 4px', fontSize: 10.5, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 500 }}>{g.label}</div>
              {g.items.map(it => {
                const Icon = I[it.icon] || I.File;
                return (
                  <div
                    key={it.idx}
                    className="search-list-row"
                    style={{ borderRadius: 6, border: 'none', background: it.idx === sel ? 'var(--bg-2)' : 'transparent', gridTemplateColumns: '20px 1fr auto' }}
                    onMouseEnter={() => setSel(it.idx)}
                    onClick={() => choose(it.idx)}
                  >
                    <span className="dim" style={{ display: 'flex', alignItems: 'center' }}>
                      {it.subjectHex
                        ? <span className="subj-dot" style={{ background: it.subjectHex, width: 7, height: 7 }} />
                        : <Icon size={12} />}
                    </span>
                    <div style={{ minWidth: 0 }}>
                      <div className="ellipsis" style={{ fontSize: 12.5, color: 'var(--fg)' }}>{it.label}</div>
                      {it.sub && <div className="dim ellipsis" style={{ fontSize: 11 }}>{it.sub}</div>}
                    </div>
                    <I.ArrowRight size={11} className="faint" />
                  </div>
                );
              })}
            </div>
          ))}
        </div>
        <div className="hstack" style={{ padding: '6px 12px', borderTop: '1px solid var(--border)', fontSize: 11, color: 'var(--fg-3)', gap: 12 }}>
          <span><span className="kbd" style={{ marginRight: 4 }}>&#8629;</span> open</span>
          <span><span className="kbd" style={{ marginRight: 4 }}>&#8593;&#8595;</span> navigate</span>
          <span><span className="kbd" style={{ marginRight: 4 }}>esc</span> close</span>
          <span style={{ marginLeft: 'auto' }} className="dim">{filtered.length} result{filtered.length === 1 ? '' : 's'}</span>
        </div>
      </div>
    </div>
  );
}

window.SubjectPage = SubjectPage;
window.LecturePage = LecturePage;
window.AccountPage = AccountPage;
window.NotificationsPanel = NotificationsPanel;
window.SearchPalette = SearchPalette;
