// ChapterLibrary — three vertically-stacked chapter slots (or empty drop zones).
// Each filled slot is a card; the quizzes for that chapter render inline in
// an expandable section that is open by default.

const { useState: useLibState } = React;

function ChapterLibrary({
  chapters, quizzes, density,
  onUpload, onRename, onDelete,
  onNewQuiz, onStartQuiz, onDeleteQuiz, onRenameQuiz,
}) {
  const t = window.LexTokens;
  // Track which chapters the user has opened. Default state is collapsed —
  // the user expands a chapter to see its quizzes.
  const [expanded, setExpanded] = useLibState(new Set());
  const [confirmDelete, setConfirmDelete] = useLibState(null); // chapterId
  const [blockedSlot, setBlockedSlot] = useLibState(null); // index of blocked drop
  const [dragSlot, setDragSlot] = useLibState(null);

  const slots = [0, 1, 2].map(i => chapters[i] || null);
  const filled = chapters.length;
  const isCompact = density === 'compact';

  function toggle(id) {
    setExpanded(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  }

  function handleDrop(e, slotIndex) {
    e.preventDefault();
    setDragSlot(null);
    if (filled >= 3 && !slots[slotIndex]) {
      setBlockedSlot(slotIndex);
      setTimeout(() => setBlockedSlot(null), 2400);
      return;
    }
    const file = e.dataTransfer.files?.[0];
    if (!file) return;
    onUpload(file);
  }

  function handlePick(e) {
    const file = e.target.files?.[0];
    if (file) onUpload(file);
    e.target.value = '';
  }

  return (
    <div style={{ ...styles.wrap, padding: isCompact ? '28px 36px' : '40px 48px' }}>
      <div style={{ ...styles.slotsCol, gap: isCompact ? 14 : 22 }}>
        {slots.map((ch, i) => {
          if (!ch) {
            return (
              <EmptySlot
                key={'empty_' + i}
                index={i}
                isOver={dragSlot === i}
                isBlocked={blockedSlot === i}
                disabled={filled >= 3}
                onDragOver={e => { e.preventDefault(); setDragSlot(i); }}
                onDragLeave={() => setDragSlot(null)}
                onDrop={e => handleDrop(e, i)}
                onPick={handlePick}
                compact={isCompact}
              />
            );
          }

          const chQuizzes = quizzes[ch.id] || [];
          const isCollapsed = !expanded.has(ch.id);
          return (
            <ChapterCard
              key={ch.id}
              chapter={ch}
              quizzes={chQuizzes}
              collapsed={isCollapsed}
              compact={isCompact}
              onToggle={() => toggle(ch.id)}
              onRename={(name) => onRename(ch.id, name)}
              onDelete={() => setConfirmDelete(ch.id)}
              onNewQuiz={() => onNewQuiz(ch.id)}
              onStartQuiz={(qz) => onStartQuiz(ch.id, qz.id)}
              onDeleteQuiz={(qz) => onDeleteQuiz(ch.id, qz.id)}
              onRenameQuiz={(qz, name) => onRenameQuiz(ch.id, qz.id, name)}
            />
          );
        })}
      </div>

      {confirmDelete && (
        <Modal onClose={() => setConfirmDelete(null)} title="Delete this chapter?">
          <p style={styles.modalP}>
            All quizzes generated from <strong>{chapters.find(c => c.id === confirmDelete)?.displayName}</strong> will be removed.
            This frees up one of your three chapter slots.
          </p>
          <div style={styles.modalActions}>
            <button style={styles.btnGhost} onClick={() => setConfirmDelete(null)}>Cancel</button>
            <button
              style={styles.btnDanger}
              onClick={() => { onDelete(confirmDelete); setConfirmDelete(null); }}
            >Delete chapter</button>
          </div>
        </Modal>
      )}
    </div>
  );
}

// ── Empty slot ──────────────────────────────────────────────────────────────
function EmptySlot({ index, isOver, isBlocked, disabled, onDragOver, onDragLeave, onDrop, onPick, compact }) {
  const labels = ['Chapter slot 1', 'Chapter slot 2', 'Chapter slot 3'];
  return (
    <label
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      style={{
        ...styles.emptySlot,
        padding: compact ? '22px 26px' : '34px 30px',
        ...(isOver    ? styles.emptySlotOver    : {}),
        ...(isBlocked ? styles.emptySlotBlocked : {}),
        ...(disabled  ? styles.emptySlotDisabled : {}),
      }}
    >
      <input type="file" accept="application/pdf,.pdf" onChange={onPick} style={{display:'none'}} disabled={disabled} />
      <div style={styles.emptyIcon}>{isBlocked ? '✕' : '+'}</div>
      <div style={styles.emptyLabel}>
        {isBlocked
          ? 'Slot full — delete a chapter first'
          : disabled
            ? `${labels[index]} unavailable until you delete one`
            : labels[index]}
      </div>
      <div style={styles.emptyHint}>
        {isBlocked || disabled ? ' ' : 'Drag a PDF here, or click to choose.'}
      </div>
    </label>
  );
}

// ── Filled chapter card ─────────────────────────────────────────────────────
function ChapterCard({ chapter, quizzes, collapsed, compact, onToggle, onRename, onDelete, onNewQuiz, onStartQuiz, onDeleteQuiz, onRenameQuiz }) {
  const [editing, setEditing] = useLibState(false);
  const [draftName, setDraftName] = useLibState(chapter.displayName);

  function commit() {
    const v = (draftName || '').trim();
    if (v && v !== chapter.displayName) onRename(v);
    else setDraftName(chapter.displayName);
    setEditing(false);
  }
  function cancel() {
    setDraftName(chapter.displayName);
    setEditing(false);
  }

  return (
    <article style={styles.card}>
      <div style={{ ...styles.cardHead, padding: compact ? '16px 22px' : '22px 28px' }}>
        <div style={styles.cardHeadMain}>
          <div style={styles.cardTitleRow}>
            {editing ? (
              <input
                autoFocus
                value={draftName}
                onChange={e => setDraftName(e.target.value)}
                onBlur={commit}
                onKeyDown={e => {
                  if (e.key === 'Enter') { e.preventDefault(); commit(); }
                  if (e.key === 'Escape') { e.preventDefault(); cancel(); }
                }}
                style={styles.titleInput}
              />
            ) : (
              <h2
                style={{ ...styles.cardTitle, cursor: 'text' }}
                onClick={() => setEditing(true)}
                title="Click to rename"
              >{chapter.displayName}</h2>
            )}
            {!editing && (
              <button style={styles.iconBtn} title="Rename" onClick={() => setEditing(true)}>
                <PencilIcon />
              </button>
            )}
          </div>
          <div style={styles.cardMeta}>
            <span>pp. {chapter.pageStart}–{chapter.pageEnd}</span>
            <span style={styles.dot}>·</span>
            <span>{chapter.pageCount} pages indexed</span>
            {chapter.cases?.length > 0 && (
              <>
                <span style={styles.dot}>·</span>
                <span>{chapter.cases.length} case{chapter.cases.length === 1 ? '' : 's'} detected</span>
              </>
            )}
          </div>
        </div>
        <div style={styles.cardHeadActions}>
          <button style={styles.btnPrimary} onClick={onNewQuiz}>+ New quiz</button>
          <button style={styles.iconBtnDanger} onClick={onDelete} title="Delete chapter"><TrashIcon /></button>
          <button style={styles.collapseBtn} onClick={onToggle} title={collapsed ? 'Expand' : 'Collapse'}>
            <Chevron open={!collapsed} />
          </button>
        </div>
      </div>

      {!collapsed && (
        <div style={styles.quizList}>
          {quizzes.length === 0 ? (
            <div style={styles.quizEmpty}>
              No quizzes yet for this chapter. <button style={styles.linkInline} onClick={onNewQuiz}>Create your first quiz →</button>
            </div>
          ) : (
            quizzes.map(qz => (
              <QuizRow key={qz.id} chapter={chapter} quiz={qz}
                onStart={() => onStartQuiz(qz)}
                onDelete={() => onDeleteQuiz(qz)}
                onRename={(name) => onRenameQuiz(qz, name)}
              />
            ))
          )}
        </div>
      )}
    </article>
  );
}

function QuizRow({ chapter, quiz, onStart, onDelete, onRename }) {
  const styleLabel  = quiz.config.style === 'fact' ? 'Fact' : quiz.config.style === 'mixed' ? 'Mixed' : 'Application';
  const stylePillKind = quiz.config.style === 'fact' ? 'gold' : quiz.config.style === 'mixed' ? 'green' : 'blue';
  const scopeLabel  = describeScope(quiz.config.scope, chapter);
  const declared    = quiz.config.count;
  // Defensive clamp: stale fixtures or localStorage might claim more answered
  // than the quiz actually has questions. Use the actual question count
  // (when present) as the source of truth for total + clamping.
  const qLen        = quiz.questions?.length || 0;
  const total       = qLen > 0 ? qLen : declared;
  const answered    = Math.min(quiz.progress?.answered || 0, total);
  const correct     = Math.min(quiz.progress?.correct  || 0, answered);
  const isComplete  = total > 0 && answered >= total;

  const [editing, setEditing]   = useLibState(false);
  const [draft,   setDraft]     = useLibState(quiz.name);
  const [hover,   setHover]     = useLibState(false);

  function commit() {
    const v = (draft || '').trim();
    if (v && v !== quiz.name) onRename(v);
    else setDraft(quiz.name);
    setEditing(false);
  }
  function cancel() { setDraft(quiz.name); setEditing(false); }

  // Status pill content — replaces the old "{N} questions" pill and the
  // right-hand standalone status text. One source of truth, one place to look.
  const statusKind = isComplete ? 'status-done' : (answered > 0 ? 'status-progress' : 'ghost');
  const statusText = isComplete
    ? `${correct}/${total} correct`
    : `${answered}/${total} answered`;

  // Whole row is the click target. Rename + delete suppress propagation so
  // they don't open the quiz.
  const rowStyle = {
    ...styles.quizRow,
    cursor: editing ? 'default' : 'pointer',
    background: hover && !editing ? 'rgba(42,96,73,0.04)' : 'transparent',
  };
  function onRowClick(e) {
    if (editing) return;
    onStart();
  }

  return (
    <div
      style={rowStyle}
      onClick={onRowClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
    >
      <div style={styles.quizMain}>
        <div style={styles.quizNameRow}>
          {editing ? (
            <input
              autoFocus
              value={draft}
              onChange={e => setDraft(e.target.value)}
              onBlur={commit}
              onClick={e => e.stopPropagation()}
              onKeyDown={e => {
                if (e.key === 'Enter')  { e.preventDefault(); commit(); }
                if (e.key === 'Escape') { e.preventDefault(); cancel(); }
              }}
              style={styles.quizNameInput}
            />
          ) : (
            <span style={styles.quizName}>{quiz.name}</span>
          )}
          {!editing && (
            <button
              style={styles.iconBtn}
              title="Rename quiz"
              onClick={e => { e.stopPropagation(); setEditing(true); }}
            >
              <PencilIcon />
            </button>
          )}
        </div>
        <div style={styles.quizMeta}>
          <Pill kind={stylePillKind}>{styleLabel}</Pill>
          <Pill kind="ghost">{scopeLabel}</Pill>
          <Pill kind={statusKind}>{statusText}</Pill>
        </div>
      </div>
      <div style={styles.quizActions}>
        <button
          style={styles.iconBtnDangerSm}
          onClick={e => { e.stopPropagation(); onDelete(); }}
          title="Delete quiz"
        ><TrashIcon size={14} /></button>
      </div>
    </div>
  );
}

function describeScope(scope, chapter) {
  if (!scope) return 'Whole chapter';
  if (scope.kind === 'pages')   return `pp. ${scope.from}–${scope.to}`;
  if (scope.kind === 'topic')   return `topic: ${scope.topic}`;
  if (scope.kind === 'case')    {
    const c = chapter.cases?.find(x => x.id === scope.caseId);
    return c ? `case: ${c.name}` : 'a case';
  }
  return 'Whole chapter';
}

// ── Bits ────────────────────────────────────────────────────────────────────
function Pill({ kind, children }) {
  const t = window.LexTokens;
  const map = {
    gold:  { bg:'#FBF3DC', fg:'#7A5A0F', bd:'#F0E2B6' },
    blue:  { bg:'#E8F0F8', fg:'#234A6B', bd:'#CFDFEC' },
    green: { bg: t.okSoft, fg: t.forestDk, bd: 'rgba(42,96,73,0.25)' },
    ghost: { bg:'transparent', fg: t.muted, bd: t.rule },
    'status-progress': { bg: '#FFF6E0', fg: '#7A5A0F', bd: '#F0E2B6' },
    'status-done':     { bg: t.okSoft,    fg: t.forestDk, bd: 'rgba(42,96,73,0.25)' },
  }[kind || 'ghost'];
  return (
    <span style={{
      display:'inline-flex', alignItems:'center', gap:4,
      padding:'1px 7px', borderRadius:999, fontSize:10.5, fontWeight:600, lineHeight:1.5,
      background: map.bg, color: map.fg, border: `1px solid ${map.bd}`,
      letterSpacing:'.2px',
    }}>{children}</span>
  );
}

function Chevron({ open }) {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" style={{ transform: open ? 'rotate(180deg)' : 'rotate(0)', transition:'transform .15s' }}>
      <path d="M3 5 L7 9 L11 5" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}
function PencilIcon() {
  return (
    <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
      <path d="M11.5 2.5 L13.5 4.5 L5 13 L2.5 13.5 L3 11 L11.5 2.5 Z" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/>
    </svg>
  );
}
function TrashIcon({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <path d="M3 4 H13 M6 4 V3 A1 1 0 0 1 7 2 H9 A1 1 0 0 1 10 3 V4 M4.5 4 L5.5 13.5 H10.5 L11.5 4 M7 7 V11 M9 7 V11"
        stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

// ── Generic modal ───────────────────────────────────────────────────────────
function Modal({ title, subtitle, children, onClose }) {
  const t = window.LexTokens;
  return (
    <div style={styles.overlay} onClick={onClose}>
      <div style={styles.modal} onClick={e => e.stopPropagation()}>
        <div style={styles.modalHead}>
          <div>
            <div style={styles.modalTitle}>{title}</div>
            {subtitle && <div style={styles.modalSubtitle}>{subtitle}</div>}
          </div>
          <button style={styles.iconBtn} onClick={onClose} aria-label="Close">✕</button>
        </div>
        <div style={styles.modalBody}>{children}</div>
      </div>
    </div>
  );
}

// ── Styles ──────────────────────────────────────────────────────────────────
const t = window.LexTokens;
const styles = {
  wrap:        { maxWidth: 940, margin: '0 auto', width: '100%' },

  slotsCol:    { display:'flex', flexDirection:'column' },

  // Empty slot
  emptySlot:   { display:'flex', flexDirection:'column', alignItems:'flex-start', justifyContent:'center', gap:6, border:`1.5px dashed ${t.rule}`, borderRadius:14, background: t.cream, cursor:'pointer', transition:'border-color .15s, background .15s, transform .15s' },
  emptySlotOver:{ borderColor: t.forest, background: t.forestSft },
  emptySlotBlocked:{ borderColor: t.crimson, background:'#FBEFEC', cursor:'not-allowed' },
  emptySlotDisabled:{ opacity: 0.55, cursor:'not-allowed' },
  emptyIcon:   { width:32, height:32, borderRadius:'50%', background: t.paper, border:`1px solid ${t.rule}`, color: t.forest, fontSize:18, fontWeight:600, display:'flex', alignItems:'center', justifyContent:'center', marginBottom:4, fontFamily:'system-ui' },
  emptyLabel:  { fontFamily: t.serifDisp, fontSize: 18, fontWeight:600, color: t.ink },
  emptyHint:   { fontSize: 13, color: t.muted, fontFamily: t.serifBody },

  // Card
  card:        { background: t.paper, border:`1px solid ${t.rule}`, borderRadius:14, boxShadow: t.shadow, overflow:'hidden' },
  cardHead:    { display:'flex', alignItems:'flex-start', justifyContent:'space-between', gap:18, borderBottom:`1px solid ${t.ruleSoft}` },
  cardHeadMain:{ flex:1, minWidth:0 },
  cardTitleRow:{ display:'flex', alignItems:'center', gap:8, marginBottom:6 },
  cardTitle:   { fontFamily: t.serifDisp, fontSize: 22, fontWeight: 700, color: t.ink, margin: 0, letterSpacing:'-0.2px' },
  titleInput:  { fontFamily: t.serifDisp, fontSize: 22, fontWeight: 700, color: t.ink, letterSpacing:'-0.2px', background:'transparent', border:'none', borderBottom:`2px solid ${t.forest}`, padding:'2px 4px', margin:'-2px 0', outline:'none', minWidth: 240, fontStyle:'italic' },
  cardMeta:    { display:'flex', alignItems:'center', gap:8, flexWrap:'wrap', fontSize:12.5, color: t.muted, fontFamily: t.serifBody },
  dot:         { opacity: .5 },
  cardHeadActions:{ display:'flex', alignItems:'center', gap:8, flexShrink:0 },

  // Quiz list
  quizList:    { padding:'8px 14px 14px' },
  quizEmpty:   { padding:'18px 16px', fontSize:13.5, color: t.muted, fontFamily: t.serifBody, fontStyle:'italic' },
  quizRow:     { display:'flex', alignItems:'center', gap:14, padding:'12px 14px', borderRadius:10, transition:'background .12s' },
  quizMain:    { flex:1, minWidth:0 },
  quizNameRow: { display:'flex', alignItems:'center', gap:6, marginBottom:5 },
  quizName:    { fontFamily: t.serifDisp, fontSize: 16, fontWeight:600, color: t.ink },
  quizNameInput:{ fontFamily: t.serifDisp, fontSize: 16, fontWeight:600, color: t.ink, background:'transparent', border:'none', borderBottom:`2px solid ${t.forest}`, padding:'1px 4px', margin:'-1px 0', outline:'none', minWidth: 220, fontStyle:'italic' },
  quizMeta:    { display:'flex', flexWrap:'wrap', gap:6, alignItems:'center' },
  quizActions: { display:'flex', alignItems:'center', gap:8 },
  linkInline:  { background:'none', border:'none', color: t.forest, fontWeight:600, cursor:'pointer', fontSize:'inherit', fontFamily:'inherit', padding:0, textDecoration:'underline', textUnderlineOffset:3 },

  // Buttons
  btnPrimary:  { padding:'10px 18px', background: t.forest, color:'white', border:'none', borderRadius:8, fontSize:13.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit', letterSpacing:'.2px' },
  btnPrimarySm:{ padding:'7px 14px', background: t.forest, color:'white', border:'none', borderRadius:6, fontSize:12.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit' },
  btnGhost:    { padding:'10px 18px', background:'none', color: t.ink, border:`1px solid ${t.rule}`, borderRadius:8, fontSize:13.5, fontWeight:500, cursor:'pointer', fontFamily:'inherit' },
  btnDanger:   { padding:'10px 18px', background: t.crimson, color:'white', border:'none', borderRadius:8, fontSize:13.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit' },
  iconBtn:     { width:28, height:28, padding:0, background:'none', border:`1px solid transparent`, borderRadius:6, color: t.muted, cursor:'pointer', display:'inline-flex', alignItems:'center', justifyContent:'center' },
  iconBtnDanger:{ width:32, height:32, padding:0, background:'none', border:`1px solid ${t.rule}`, borderRadius:6, color: t.muted, cursor:'pointer', display:'inline-flex', alignItems:'center', justifyContent:'center' },
  iconBtnDangerSm:{ width:28, height:28, padding:0, background:'none', border:`1px solid ${t.rule}`, borderRadius:6, color: t.muted, cursor:'pointer', display:'inline-flex', alignItems:'center', justifyContent:'center' },
  collapseBtn: { width:32, height:32, padding:0, background: t.cream, border:`1px solid ${t.rule}`, borderRadius:6, color: t.ink, cursor:'pointer', display:'inline-flex', alignItems:'center', justifyContent:'center' },

  // Modal
  overlay:     { position:'fixed', inset:0, background:'rgba(26,23,20,.45)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:999, backdropFilter:'blur(2px)' },
  modal:       { background: t.paper, borderRadius:14, width:'94%', maxWidth: 540, boxShadow: t.shadowLg, overflow:'hidden', maxHeight:'92vh', display:'flex', flexDirection:'column' },
  modalHead:   { display:'flex', alignItems:'flex-start', justifyContent:'space-between', padding:'18px 24px', borderBottom:`1px solid ${t.ruleSoft}`, background: t.cream, flexShrink:0 },
  modalTitle:  { fontFamily: t.serifDisp, fontSize: 18, fontWeight:700, color: t.ink, lineHeight:1.2 },
  modalSubtitle:{ fontFamily: t.serifBody, fontSize: 12.5, color: t.muted, marginTop:3, fontStyle:'italic' },
  modalBody:   { padding:'22px 24px 22px', overflowY:'auto' },
  modalP:      { fontFamily: t.serifBody, fontSize:14, color: t.ink2, lineHeight:1.6, margin:'0 0 14px' },
  modalActions:{ display:'flex', gap:8, justifyContent:'flex-end', marginTop:8 },
  input:       { width:'100%', boxSizing:'border-box', padding:'10px 14px', borderRadius:8, border:`1.5px solid ${t.rule}`, fontFamily: t.serifBody, fontSize:14.5, color: t.ink, background: t.paper, outline:'none' },
};

Object.assign(window, { ChapterLibrary, Modal, Pill, Chevron, PencilIcon, TrashIcon });
