/* STUDY space — per-subject chapter revision tracker, wired to Supabase
   (study_chapters). Each chapter has 4 revision ticks, a 1-line note and a
   100%-done flag. Catalog (CBSE Class 10, Sanskrit = Manika) auto-seeds on
   first open. Mirrors the NotesSpace/FilesSpace shell.

   Realtime is MERGED per-row from the change payload (not a full reload), and
   echoes of our own in-flight edits are ignored — so rapid ticks and in-progress
   notes are never clobbered. */

function StudySpace({ tabs, utils }) {
  const DB = window.VaultDB;
  const CATALOG = (window.STUDY_CATALOG || { subjects: [] }).subjects;

  const [chapters, setChapters] = React.useState([]);   // [{id,subject,name,sort,rev1..4,note,done,is_custom}]
  const [ready, setReady] = React.useState(null);        // null=loading, false=needs migration, true=ok
  const [seeding, setSeeding] = React.useState(false);
  const [subject, setSubject] = React.useState(null);
  const [query, setQuery] = React.useState('');
  const [filter, setFilter] = React.useState('all');     // all | todo | mastered
  const [adding, setAdding] = React.useState(false);
  const [newName, setNewName] = React.useState('');
  const seededRef = React.useRef(false);
  const noteTimers = React.useRef({});
  const pending = React.useRef({});   // id -> count of in-flight writes (suppress self-echo)
  const editingId = React.useRef(null); // id of the row whose note is focused

  const fromRow = (r) => ({
    id: r.id, subject: r.subject, name: r.name, sort: r.sort || 0,
    rev1: !!r.rev1, rev2: !!r.rev2, rev3: !!r.rev3, rev4: !!r.rev4,
    note: r.note || '', done: !!r.done, is_custom: !!r.is_custom,
  });

  // catalog meta lookup (color + order)
  const meta = React.useMemo(() => {
    const m = {}; CATALOG.forEach((s, i) => { m[s.name] = { color: s.color, order: i }; }); return m;
  }, [CATALOG]);
  const subjColor = (name) => (meta[name] && meta[name].color) || '#9aa0aa';
  const subjOrder = (name) => (meta[name] ? meta[name].order : 999);

  // Load + seed
  React.useEffect(() => {
    let alive = true;
    (async () => {
      try {
        await DB.init();
        if (!DB.study.ready()) { if (alive) setReady(false); return; }
        let rows = await DB.study.list();
        if (rows.length === 0 && !seededRef.current) {
          seededRef.current = true;
          const seed = [];
          CATALOG.forEach(s => (s.chapters || []).forEach((ch, i) => seed.push({ subject: s.name, name: ch, sort: i, is_custom: false })));
          if (seed.length) { if (alive) setSeeding(true); await DB.study.addMany(seed); rows = await DB.study.list(); }
        }
        if (!alive) return;
        setChapters(rows.map(fromRow));
        setSeeding(false);
        setReady(true);
      } catch (e) { if (alive) { setSeeding(false); setReady(false); } }
    })();

    // Merge realtime changes per-row; never blow away local optimistic state.
    const unsub = DB.subscribe((table, payload) => {
      if (table !== 'study') return;
      // payload-less signal = focus/visibility resync → full reload
      if (!payload) { DB.study.list().then(rs => setChapters(rs.map(fromRow))).catch(() => {}); return; }
      const ev = payload.eventType || payload.event;
      const row = payload.new, old = payload.old;
      if (ev === 'INSERT' && row) {
        setChapters(prev => prev.some(c => c.id === row.id) ? prev : [...prev, fromRow(row)]);
      } else if (ev === 'UPDATE' && row) {
        if (pending.current[row.id] || editingId.current === row.id) return; // our own edit wins
        setChapters(prev => prev.map(c => c.id === row.id ? fromRow(row) : c));
      } else if (ev === 'DELETE' && old) {
        setChapters(prev => prev.filter(c => c.id !== old.id));
      }
    });
    return () => { alive = false; unsub(); };
  }, []);

  // Subjects present, in catalog order (unknown subjects appended)
  const subjects = React.useMemo(() => {
    const names = Array.from(new Set(chapters.map(c => c.subject)));
    names.sort((a, b) => subjOrder(a) - subjOrder(b) || a.localeCompare(b));
    return names;
  }, [chapters, meta]);

  React.useEffect(() => {
    if (subject == null && subjects.length) setSubject(subjects[0]);
    else if (subject != null && subjects.length && !subjects.includes(subject)) setSubject(subjects[0]);
  }, [subjects]);

  const revCount = (c) => (c.rev1 ? 1 : 0) + (c.rev2 ? 1 : 0) + (c.rev3 ? 1 : 0) + (c.rev4 ? 1 : 0);
  const stats = (name) => {
    const list = chapters.filter(c => c.subject === name);
    const done = list.filter(c => c.done).length;
    const revs = list.reduce((a, c) => a + revCount(c), 0);
    return { total: list.length, done, revs, revMax: list.length * 4 };
  };

  // ── persistence: optimistic state + suppressed self-echo ──
  const bump = (id, d) => { pending.current[id] = Math.max(0, (pending.current[id] || 0) + d); };
  const persist = (id, p) => {
    bump(id, 1);
    DB.study.update(id, p).catch(() => {}).finally(() => { setTimeout(() => bump(id, -1), 600); });
  };
  const patch = (id, p) => {
    setChapters(prev => prev.map(c => c.id === id ? { ...c, ...p } : c));
    persist(id, p);
  };
  const toggleRev = (c, n) => patch(c.id, { ['rev' + n]: !c['rev' + n] });
  const toggleDone = (c) => patch(c.id, { done: !c.done });
  const setNote = (c, val) => {
    setChapters(prev => prev.map(x => x.id === c.id ? { ...x, note: val } : x));
    bump(c.id, 1); // hold off realtime echoes while typing
    clearTimeout(noteTimers.current[c.id]);
    noteTimers.current[c.id] = setTimeout(() => {
      DB.study.update(c.id, { note: val }).catch(() => {}).finally(() => setTimeout(() => bump(c.id, -1), 400));
    }, 500);
  };
  const removeChapter = (c) => {
    if (!confirm('Delete chapter "' + c.name + '"?')) return;
    setChapters(prev => prev.filter(x => x.id !== c.id));
    DB.study.remove(c.id).catch(() => {});
  };
  const addChapter = async () => {
    const nm = newName.trim(); if (!nm || !subject) return;
    const sort = chapters.filter(c => c.subject === subject).length;
    setNewName(''); setAdding(false);
    try { const row = await DB.study.add({ subject, name: nm, sort, is_custom: true }); setChapters(prev => prev.some(x => x.id === row.id) ? prev : [...prev, fromRow(row)]); }
    catch (e) {}
  };

  // ── Topbar ──
  const overall = { done: chapters.filter(c => c.done).length, total: chapters.length };
  const topbar = React.createElement(SpaceTopbar, { tabs, utils },
    React.createElement('div', { className: 'cal-nav-title', style: { fontWeight: 700 } }, 'Study'),
    React.createElement('div', { className: 'cal-spacer' }),
    ready === true ? React.createElement('div', { className: 'study-overall', title: 'Chapters marked 100% complete' },
      React.createElement('span', { className: 'study-overall-num' }, overall.done + '/' + overall.total),
      React.createElement('span', { className: 'study-overall-lbl' }, 'mastered')) : null,
    React.createElement('div', { className: 'search-wrap' },
      React.createElement(Icons.search, { size: 15 }),
      React.createElement('input', { className: 'search-input', placeholder: 'Search all chapters', value: query, onChange: (e) => setQuery(e.target.value) })));

  if (ready === false) {
    return React.createElement('div', { className: 'space-root' }, topbar,
      React.createElement('div', { className: 'empty-pane' },
        React.createElement(Icons.fileText, { size: 40, sw: 1.5 }),
        React.createElement('div', { className: 'et' }, 'Study needs a one-time setup'),
        React.createElement('div', { className: 'es', style: { maxWidth: 440 } }, 'Run STUDY_MIGRATION.sql in the Supabase SQL editor to create the study_chapters table, then reload. Your CBSE Class 10 chapters seed automatically.')));
  }
  if (ready === null) {
    return React.createElement('div', { className: 'space-root' }, topbar,
      React.createElement('div', { className: 'empty-pane' }, React.createElement('div', { className: 'es' }, seeding ? 'Setting up your chapters…' : 'Loading…')));
  }

  const q = query.trim().toLowerCase();
  const searching = !!q;
  let list;
  if (searching) {
    list = chapters
      .filter(c => c.name.toLowerCase().includes(q) || c.subject.toLowerCase().includes(q))
      .sort((a, b) => subjOrder(a.subject) - subjOrder(b.subject) || a.sort - b.sort);
  } else {
    list = chapters
      .filter(c => c.subject === subject && (filter === 'all' || (filter === 'mastered' ? c.done : !c.done)))
      .sort((a, b) => a.sort - b.sort || a.name.localeCompare(b.name));
  }
  const accent = subjColor(searching ? (list[0] && list[0].subject) : subject);

  // ── Sidebar: subjects ──
  const side = React.createElement('aside', { className: 'cal-side study-side' },
    React.createElement('div', { className: 'side-section-label' }, 'Subjects'),
    React.createElement('div', { className: 'study-subjects' },
      subjects.map(name => {
        const st = stats(name);
        const pct = st.revMax ? Math.round((st.revs / st.revMax) * 100) : 0;
        const on = !searching && name === subject;
        return React.createElement('button', {
          key: name, className: 'subj' + (on ? ' on' : ''), style: { '--sc': subjColor(name) },
          title: name + ' — ' + st.done + ' mastered, ' + st.revs + '/' + st.revMax + ' revisions',
          onClick: () => { setSubject(name); setQuery(''); },
        },
          React.createElement('span', { className: 'subj-dot' + (st.total && st.done === st.total ? ' full' : '') }),
          React.createElement('span', { className: 'subj-name' }, name),
          React.createElement('span', { className: 'subj-count' }, st.done + '/' + st.total),
          React.createElement('span', { className: 'subj-bar' }, React.createElement('span', { className: 'subj-bar-fill', style: { width: pct + '%' } })));
      })));

  // ── chapter row ──
  const chapterRow = (c) => React.createElement('div', { key: c.id, className: 'chap-row' + (c.done ? ' done' : '') },
    React.createElement('div', { className: 'chap-name' },
      searching ? React.createElement('span', { className: 'chap-subj', style: { '--sc': subjColor(c.subject) }, title: c.subject }, c.subject) : null,
      React.createElement('span', { className: 'chap-title' }, c.name),
      c.is_custom ? React.createElement('span', { className: 'chap-tag' }, 'custom') : null),
    React.createElement('div', { className: 'chap-revs' },
      [1, 2, 3, 4].map(n => React.createElement('button', {
        key: n, className: 'rev' + (c['rev' + n] ? ' on' : ''),
        title: 'Revision ' + n, onClick: () => toggleRev(c, n),
      }, n))),
    React.createElement('input', {
      className: 'chap-note', placeholder: 'note…', value: c.note,
      onFocus: () => { editingId.current = c.id; },
      onBlur: () => {
        if (editingId.current === c.id) editingId.current = null;
        clearTimeout(noteTimers.current[c.id]);
        DB.study.update(c.id, { note: c.note }).catch(() => {}).finally(() => setTimeout(() => bump(c.id, -1), 300));
      },
      onChange: (e) => setNote(c, e.target.value),
    }),
    React.createElement('button', {
      className: 'chap-done' + (c.done ? ' on' : ''), title: c.done ? 'Mastered — click to unset' : 'Mark 100% complete', onClick: () => toggleDone(c),
    }, React.createElement(Icons.check, { size: 14, sw: 3 })),
    React.createElement('button', { className: 'chap-del', title: 'Delete chapter', onClick: () => removeChapter(c) },
      React.createElement(Icons.x, { size: 14 })));

  // ── Main ──
  const st = searching ? null : stats(subject);
  const main = React.createElement('main', { className: 'study-main', style: { '--sc': accent } },
    React.createElement('div', { className: 'study-main-head' },
      React.createElement('div', { className: 'study-head-left' },
        React.createElement('h2', { className: 'study-subj-title' }, searching ? 'Search' : (subject || '—')),
        React.createElement('span', { className: 'study-subj-sub' }, searching
          ? (list.length + (list.length === 1 ? ' result' : ' results') + ' for “' + query.trim() + '”')
          : (st.total + ' chapters · ' + st.done + ' mastered · ' + st.revs + '/' + st.revMax + ' revisions'))),
      searching ? null : React.createElement('div', { className: 'study-filters' },
        [['all', 'All'], ['todo', 'To revise'], ['mastered', 'Mastered']].map(([k, label]) =>
          React.createElement('button', { key: k, className: 'sf' + (filter === k ? ' on' : ''), onClick: () => setFilter(k) }, label)))),
    React.createElement('div', { className: 'study-legend' },
      React.createElement('span', { className: 'lg-chap' }, 'Chapter'),
      React.createElement('span', { className: 'lg-revs' }, 'Revisions'),
      React.createElement('span', { className: 'lg-note' }, 'Note'),
      React.createElement('span', { className: 'lg-done' }, '100%'),
      React.createElement('span', { className: 'lg-del' })),
    React.createElement('div', { className: 'study-rows' },
      list.length === 0
        ? React.createElement('div', { className: 'study-empty' },
            searching ? 'No chapters match.' : (filter === 'mastered' ? 'Nothing mastered yet.' : filter === 'todo' ? 'All chapters mastered. 🎉' : 'No chapters yet — add one below.'))
        : list.map(chapterRow)),
    searching ? null : (adding
      ? React.createElement('div', { className: 'chap-add open' },
          React.createElement('input', {
            className: 'chap-add-input', autoFocus: true, placeholder: 'New chapter name…', value: newName,
            onChange: (e) => setNewName(e.target.value),
            onKeyDown: (e) => { if (e.key === 'Enter') addChapter(); if (e.key === 'Escape') { setAdding(false); setNewName(''); } },
          }),
          React.createElement('button', { className: 'btn-solid', onClick: addChapter }, React.createElement(Icons.check, { size: 14, sw: 2.5 }), 'Add'),
          React.createElement('button', { className: 'btn-ghost', onClick: () => { setAdding(false); setNewName(''); } }, 'Cancel'))
      : React.createElement('button', { className: 'chap-add-btn', onClick: () => setAdding(true) },
          React.createElement(Icons.plus, { size: 15, sw: 2.5 }), 'Add chapter')));

  return React.createElement('div', { className: 'space-root' }, topbar,
    React.createElement('div', { className: 'space-body' }, side, main));
}

Object.assign(window, { StudySpace });
