import { useState, useEffect, useRef, lazy, Suspense } from 'react'
import { useNavigate, Link } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
import api from '../api/client'
import ConfirmButton from '../components/ConfirmButton'
import Dialog from '../components/Dialog'
import { useDialog } from '../hooks/useDialog'

const TeachChat = lazy(() => import('../components/TeachChat'))

function InProgressSection() {
  const [inProgress, setInProgress] = useState([])
  const navigate = useNavigate()

  useEffect(() => {
    api.get('/attempts/in-progress').then(res => setInProgress(res.data)).catch(() => {})
  }, [])

  const deleteAttempt = async (attemptId) => {
    await api.delete(`/attempts/${attemptId}`)
    setInProgress(prev => prev.filter(a => a.attempt_id !== attemptId))
  }

  if (inProgress.length === 0) return null

  return (
    <div className="card" style={{ marginBottom: 16, borderLeft: '4px solid #f59e0b' }}>
      <h2 style={{ marginBottom: 12, fontSize: '1rem', color: '#92400e' }}>
        ⏸ In Progress ({inProgress.length})
      </h2>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {inProgress.map(a => (
          <div key={a.attempt_id} style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            padding: '10px 14px', background: 'var(--bg)', borderRadius: 8, gap: 12,
          }}>
            <div>
              <div style={{ fontWeight: 600, fontSize: '0.9rem' }}>{a.quiz_title}</div>
              <div style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>
                Started {new Date(a.started_at).toLocaleDateString()} · {a.total_questions} questions
              </div>
            </div>
            <div style={{ display: 'flex', gap: 8, flexShrink: 0 }}>
              <button className="btn btn-primary btn-sm" onClick={() => navigate(`/quizzes/${a.quiz_id}`)}>Resume</button>
              <ConfirmButton
                label="Delete" confirmLabel="Yes, delete"
                onConfirm={() => deleteAttempt(a.attempt_id)}
              />
            </div>
          </div>
        ))}
      </div>
    </div>
  )
}

function PastAttemptsSection() {
  const [open, setOpen] = useState(false)
  const [history, setHistory] = useState(null)
  const [loading, setLoading] = useState(false)
  const [deletingId, setDeletingId] = useState(null)

  const load = async () => {
    if (history !== null) { setOpen(v => !v); return }
    setLoading(true)
    try {
      const res = await api.get('/attempts/history')
      setHistory(res.data)
    } catch { setHistory([]) }
    finally { setLoading(false); setOpen(true) }
  }

  const deleteAttempt = async (attemptId) => {
    setDeletingId(attemptId)
    try {
      await api.delete(`/attempts/${attemptId}`)
      setHistory(prev =>
        prev
          .map(q => ({ ...q, attempts: q.attempts.filter(a => a.attempt_id !== attemptId) }))
          .filter(q => q.attempts.length > 0)
      )
    } catch { }
    finally { setDeletingId(null) }
  }

  const totalCompleted = history?.reduce((s, q) => s + q.attempts.length, 0) ?? 0

  return (
    <div className="card" style={{ marginBottom: 16 }}>
      <button onClick={load} style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        width: '100%', background: 'none', border: 'none', cursor: 'pointer',
        padding: 0, textAlign: 'left',
      }}>
        <h2 style={{ fontSize: '1rem', color: 'var(--text)', margin: 0 }}>
          ✅ Past Attempts {history !== null && `(${totalCompleted})`}
        </h2>
        <span style={{ color: 'var(--text-muted)', fontSize: '0.8rem' }}>
          {loading ? 'Loading...' : open ? '▲ Hide' : '▼ Show'}
        </span>
      </button>

      {open && history !== null && (
        <div style={{ marginTop: 12 }}>
          {history.length === 0 ? (
            <div style={{ color: 'var(--text-muted)', fontSize: '0.875rem' }}>No completed attempts yet.</div>
          ) : history.map(quiz => (
            <div key={quiz.quiz_id} style={{ marginBottom: 14 }}>
              <div style={{ fontWeight: 600, fontSize: '0.88rem', marginBottom: 6 }}>{quiz.title}</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
                {quiz.attempts.map((a) => (
                  <div key={a.attempt_id} style={{
                    display: 'flex', alignItems: 'center',
                    padding: '7px 12px', background: 'var(--bg)', borderRadius: 8,
                    fontSize: '0.82rem', gap: 8,
                  }}>
                    <span style={{ color: 'var(--text-muted)', flex: 1 }}>
                      {new Date(a.date).toLocaleDateString()} — {a.score}/{a.total}
                    </span>
                    <span style={{
                      fontWeight: 700, fontSize: '0.85rem',
                      color: a.percentage >= 80 ? 'var(--correct-fg)' : a.percentage >= 50 ? '#d97706' : 'var(--wrong-fg)',
                    }}>{a.percentage}%</span>
                    <a href={`/results/${a.attempt_id}`} style={{ color: 'var(--primary)', fontSize: '0.78rem', textDecoration: 'none', flexShrink: 0 }}>
                      Review →
                    </a>
                    <button
                      onClick={() => deleteAttempt(a.attempt_id)}
                      disabled={deletingId === a.attempt_id}
                      title="Delete this attempt"
                      style={{
                        background: 'none', border: 'none', cursor: 'pointer',
                        color: 'var(--wrong-fg)', fontSize: '0.78rem',
                        padding: '2px 4px', borderRadius: 4, flexShrink: 0,
                        opacity: deletingId === a.attempt_id ? 0.4 : 0.6,
                      }}
                      onMouseEnter={e => e.currentTarget.style.opacity = '1'}
                      onMouseLeave={e => e.currentTarget.style.opacity = deletingId === a.attempt_id ? '0.4' : '0.6'}
                    >
                      {deletingId === a.attempt_id ? '…' : '✕'}
                    </button>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  )
}

function HighlightText({ text, query }) {
  if (!query || !text) return <span>{text}</span>
  const idx = text.toLowerCase().indexOf(query.toLowerCase())
  if (idx === -1) return <span>{text}</span>
  return (
    <span>
      {text.slice(0, idx)}
      <mark style={{ background: '#fef08a', padding: '0 1px', borderRadius: 2 }}>{text.slice(idx, idx + query.length)}</mark>
      {text.slice(idx + query.length)}
    </span>
  )
}

function QuestionStudyModal({ question, query, onClose }) {
  const [answered, setAnswered] = useState(null)
  return (
    <>
      <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.55)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}
        onClick={e => e.target === e.currentTarget && onClose()}>
        <div style={{ background: 'var(--card-bg)', borderRadius: 'var(--card-radius)', padding: 24, maxWidth: 600, width: '100%', maxHeight: '90vh', overflowY: 'auto', boxShadow: '0 20px 60px rgba(0,0,0,0.3)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 12 }}>
            <span style={{ fontSize: '0.75rem', fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase' }}>Study Question</span>
            <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-muted)', fontSize: '1.2rem' }}>✕</button>
          </div>
          <p style={{ fontWeight: 600, fontSize: '0.95rem', lineHeight: 1.6, marginBottom: 16 }}>
            <HighlightText text={question.question_text} query={query} />
          </p>
          {question.image_path && (
            <div style={{ margin: '0 0 14px' }}>
              <img src={`/uploads/${question.image_path}`} alt="Question illustration"
                style={{ maxWidth: '100%', maxHeight: 280, borderRadius: 8, border: '1px solid var(--border)' }}
                onError={e => e.target.style.display = 'none'} />
            </div>
          )}
          {question.options && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 16 }}>
              {question.options.map((opt, i) => {
                const isSelected = answered === opt
                const hasAnswered = !!answered
                const isCorrectOpt = opt === question.correct_answer
                return (
                  <div key={i}
                    className={`option ${isSelected && !hasAnswered ? 'selected' : ''} ${hasAnswered && isCorrectOpt ? 'correct' : ''} ${hasAnswered && isSelected && !isCorrectOpt ? 'incorrect' : ''}`}
                    onClick={() => !hasAnswered && setAnswered(opt)}
                    style={{ cursor: hasAnswered ? 'default' : 'pointer' }}>
                    <span className="option-letter">{String.fromCharCode(65 + i)}</span>
                    <span style={{ flex: 1 }}><HighlightText text={opt} query={query} /></span>
                    {hasAnswered && isCorrectOpt && <span style={{ marginLeft: 'auto', fontSize: '0.8rem', fontWeight: 700, color: 'var(--correct-fg)' }}>✓ {isSelected ? 'Your answer' : 'Correct'}</span>}
                    {hasAnswered && isSelected && !isCorrectOpt && <span style={{ marginLeft: 'auto', fontSize: '0.8rem', fontWeight: 700, color: 'var(--wrong-fg)' }}>✗ Wrong</span>}
                  </div>
                )
              })}
            </div>
          )}
          {answered && question.explanation && (
            <div className="explanation"><strong>Explanation:</strong><div style={{ marginTop: 8 }}>{question.explanation}</div></div>
          )}
          {answered && (
            <div style={{ marginTop: 14, display: 'flex', gap: 8 }}>
              <button className="btn btn-secondary btn-sm" onClick={() => setAnswered(null)}>Try again</button>
              <button className="btn btn-secondary btn-sm" onClick={onClose}>Close</button>
            </div>
          )}
        </div>
      </div>
      {/* AI Tutor — z-index above the modal */}
      <Suspense fallback={null}>
        <TeachChat question={question} elevated />
      </Suspense>
    </>
  )
}

function QuizCard({ quiz, isModerator, categories, onDelete, onCategoryChange }) {
  const navigate = useNavigate()
  const [showCatMenu, setShowCatMenu] = useState(false)

  const assignCategory = async (catId) => {
    try {
      const params = catId == null ? {} : { category_id: catId }
      await api.patch(`/categories/quizzes/${quiz.id}`, null, { params })
      onCategoryChange(quiz.id, catId)
    } catch { }
    setShowCatMenu(false)
  }

  const togglePublish = async (e) => {
    e.stopPropagation()
    try {
      const newVal = quiz.is_published === 0
      await api.patch(`/quizzes/${quiz.id}/publish`, null, { params: { published: newVal } })
      onCategoryChange(quiz.id, quiz.category_id, newVal ? 1 : 0) // reuse callback to update state
    } catch { }
  }

  return (
    <div onClick={() => navigate(`/quizzes/${quiz.id}`)}
      style={{ background: 'var(--card-bg)', border: 'var(--card-border)', borderRadius: 'var(--card-radius)', padding: '20px 18px', cursor: 'pointer', transition: 'box-shadow 0.15s, transform 0.15s', display: 'flex', flexDirection: 'column', gap: 10, position: 'relative', boxShadow: 'var(--card-shadow)' }}
      onMouseEnter={e => { e.currentTarget.style.boxShadow = '0 4px 16px rgba(0,0,0,0.10)'; e.currentTarget.style.transform = 'translateY(-2px)' }}
      onMouseLeave={e => { e.currentTarget.style.boxShadow = 'var(--card-shadow)'; e.currentTarget.style.transform = 'none' }}>
      {isModerator && (
        <div style={{ position: 'absolute', top: 10, right: 10, display: 'flex', gap: 4 }} onClick={e => e.stopPropagation()}>
          <Link to={`/quizzes/${quiz.id}/edit`} title="Edit quiz"
            style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#cbd5e1', fontSize: '0.9rem', padding: '4px 6px', borderRadius: 4, textDecoration: 'none', display: 'flex', alignItems: 'center' }}
            onMouseEnter={e => e.currentTarget.style.color = 'var(--primary)'}
            onMouseLeave={e => e.currentTarget.style.color = '#cbd5e1'}>✏️</Link>
          <button title={quiz.is_published === 0 ? 'Hidden from users — click to publish' : 'Visible — click to hide'} onClick={togglePublish}
            style={{ background: 'none', border: 'none', cursor: 'pointer', color: quiz.is_published === 0 ? '#ef4444' : '#cbd5e1', fontSize: '0.9rem', padding: '4px 6px', borderRadius: 4 }}
            onMouseEnter={e => e.currentTarget.style.opacity = '0.7'} onMouseLeave={e => e.currentTarget.style.opacity = '1'}>
            {quiz.is_published === 0 ? '🙈' : '👁'}
          </button>
          <div style={{ position: 'relative' }} onClick={e => e.stopPropagation()}>
            <button title="Move to category" onClick={() => setShowCatMenu(v => !v)}
              style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#cbd5e1', fontSize: '0.9rem', padding: '4px 6px', borderRadius: 4 }}
              onMouseEnter={e => e.currentTarget.style.color = 'var(--primary)'}
              onMouseLeave={e => e.currentTarget.style.color = '#cbd5e1'}>🏷</button>
            {showCatMenu && (
              <div style={{ position: 'absolute', right: 0, top: '100%', background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: 4, zIndex: 100, minWidth: 160, boxShadow: '0 4px 16px rgba(0,0,0,0.15)' }}>
                <div onClick={() => assignCategory(null)} style={{ padding: '7px 12px', fontSize: '0.82rem', cursor: 'pointer', color: 'var(--text-muted)' }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--bg)'}
                  onMouseLeave={e => e.currentTarget.style.background = ''}>Uncategorized</div>
                {categories.map(cat => (
                  <div key={cat.id} onClick={() => assignCategory(cat.id)} style={{ padding: '7px 12px', fontSize: '0.82rem', cursor: 'pointer', fontWeight: quiz.category_id === cat.id ? 700 : 400, color: 'var(--text)' }}
                    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg)'}
                    onMouseLeave={e => e.currentTarget.style.background = ''}>{quiz.category_id === cat.id ? '✓ ' : ''}{cat.name}</div>
                ))}
              </div>
            )}
          </div>
          <ConfirmButton
            label="✕" confirmLabel="Move to Trash?" cancelLabel="✕"
            className="btn-sm" confirmClassName="btn btn-danger btn-sm"
            style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#cbd5e1', fontSize: '1rem', padding: '4px 6px' }}
            onConfirm={() => onDelete(quiz.id)}
          />
        </div>
      )}
      <div style={{ width: 40, height: 40, borderRadius: 10, background: quiz.mode === 'learning' ? '#d1fae5' : '#e0e7ff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.4rem' }}>
        {quiz.mode === 'learning' ? '📖' : '📝'}
      </div>
      <div style={{ paddingRight: isModerator ? 48 : 0 }}>
        <div style={{ fontWeight: 700, fontSize: '1rem', color: 'var(--text)', lineHeight: 1.3 }}>{quiz.title}</div>
      </div>
      <div style={{ marginTop: 'auto', display: 'flex', flexDirection: 'column', gap: 4 }}>
        <div style={{ fontSize: '0.82rem', color: '#64748b' }}>{quiz.questions_count} question{quiz.questions_count !== 1 ? 's' : ''}</div>
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <span style={{ fontSize: '0.75rem', fontWeight: 600, padding: '2px 8px', borderRadius: 20, background: quiz.mode === 'learning' ? '#d1fae5' : '#e0e7ff', color: quiz.mode === 'learning' ? '#065f46' : '#3730a3' }}>
            {quiz.mode === 'learning' ? 'Learning' : 'Timed'}
          </span>
          {quiz.time_limit_minutes && <span style={{ fontSize: '0.75rem', color: '#94a3b8' }}>{quiz.time_limit_minutes} min</span>}
        </div>
      </div>
    </div>
  )
}

export default function QuizzesPage() {
  const [quizzes, setQuizzes] = useState([])
  const [categories, setCategories] = useState([])
  const [loading, setLoading] = useState(true)
  const [searchQuery, setSearchQuery] = useState('')
  const [searchMode, setSearchMode] = useState('all')
  const [searchResults, setSearchResults] = useState(null)
  const [searching, setSearching] = useState(false)
  const [expandedSearch, setExpandedSearch] = useState(false)
  const [studyQuestion, setStudyQuestion] = useState(null)
  const [newCatName, setNewCatName] = useState('')
  const [addingCat, setAddingCat] = useState(false)
  const { dialogProps, openAlert } = useDialog()
  const debounceRef = useRef(null)
  const { user } = useAuth()
  const navigate = useNavigate()
  const isModerator = user?.role === 'admin' || user?.role === 'moderator'

  useEffect(() => {
    Promise.all([
      api.get('/quizzes/'),
      api.get('/categories/'),
    ]).then(([qRes, cRes]) => {
      setQuizzes(qRes.data)
      setCategories(cRes.data)
    }).catch(console.error).finally(() => setLoading(false))
  }, [])

  useEffect(() => {
    clearTimeout(debounceRef.current)
    if (searchQuery.trim().length < 2) { setSearchResults(null); return }
    setSearching(true)
    debounceRef.current = setTimeout(async () => {
      try {
        const res = await api.get('/quizzes/search', { params: { q: searchQuery.trim(), mode: searchMode } })
        setSearchResults(res.data)
      } catch { setSearchResults([]) }
      finally { setSearching(false) }
    }, 350)
    return () => clearTimeout(debounceRef.current)
  }, [searchQuery, searchMode])

  const deleteQuiz = async (quizId) => {
    try {
      await api.delete(`/quizzes/${quizId}`)
      setQuizzes(prev => prev.filter(q => q.id !== quizId))
      if (searchResults) setSearchResults(prev => prev.filter(r => r.quiz_id !== quizId))
    } catch (err) { console.error(err) }
  }

  const handleCategoryChange = (quizId, catId, isPublished) => {
    setQuizzes(prev => prev.map(q => q.id === quizId ? {
      ...q,
      category_id: catId !== undefined ? catId : q.category_id,
      is_published: isPublished !== undefined ? isPublished : q.is_published,
    } : q))
  }

  const addCategory = async () => {
    if (!newCatName.trim()) return
    try {
      const res = await api.post('/categories/', { name: newCatName.trim() })
      setCategories(prev => [...prev, res.data])
      setNewCatName('')
      setAddingCat(false)
    } catch (err) { await openAlert(err.response?.data?.detail || 'Failed to create category', { title: 'Error' }) }
  }

  const deleteCategory = async (catId) => {
    try {
      await api.delete(`/categories/${catId}`)
      setCategories(prev => prev.filter(c => c.id !== catId))
      setQuizzes(prev => prev.map(q => q.category_id === catId ? { ...q, category_id: null } : q))
    } catch { }
  }

  const isSearching = searchQuery.trim().length >= 2
  const allSearchQuestions = searchResults?.flatMap(r => r.matching_questions.map(q => ({ ...q, quiz_title: r.quiz_title }))) ?? []

  if (loading) return <div className="loading"><div className="spinner" /> Loading...</div>

  // Group quizzes by category
  const catMap = {}
  for (const cat of categories) catMap[cat.id] = { ...cat, quizzes: [] }
  const uncategorized = []
  for (const quiz of quizzes) {
    if (quiz.category_id && catMap[quiz.category_id]) catMap[quiz.category_id].quizzes.push(quiz)
    else uncategorized.push(quiz)
  }

  return (
    <div>
      <Dialog {...dialogProps} />
      {studyQuestion && (
        <QuestionStudyModal question={studyQuestion} query={searchQuery} onClose={() => setStudyQuestion(null)} />
      )}

      <div className="card" style={{ marginBottom: 16, borderLeft: '4px solid #229ed9', display: 'flex', justifyContent: 'space-between', gap: 14, alignItems: 'center', flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontWeight: 700, fontSize: '1rem', marginBottom: 4 }}>Use our Telegram bot</div>
          <div style={{ color: 'var(--text-muted)', fontSize: '0.9rem' }}>
            Start quick random quizzes, browse categories, and study questions from Telegram.
          </div>
        </div>
        <a
          href="https://t.me/pedshubbot"
          target="_blank"
          rel="noopener noreferrer"
          className="btn btn-primary"
          style={{ textDecoration: 'none', flexShrink: 0 }}
        >
          Open @pedshubbot
        </a>
      </div>

      {/* Search bar */}
      <div className="card" style={{ marginBottom: 16 }}>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
          <div style={{ flex: 1, minWidth: 200, position: 'relative' }}>
            <span style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', color: '#94a3b8' }}>🔍</span>
            <input type="text" placeholder="Search quizzes or questions..."
              value={searchQuery} onChange={e => { setSearchQuery(e.target.value); setExpandedSearch(false) }}
              style={{ width: '100%', padding: '9px 13px 9px 36px', border: '1px solid var(--border)', borderRadius: 8, fontSize: '0.9rem', background: 'var(--input-bg)', color: 'var(--text)' }} />
          </div>
          <div style={{ display: 'flex', gap: 4 }}>
            {[['all', 'All'], ['title', 'Title only'], ['questions', 'Questions only']].map(([val, label]) => (
              <button key={val} onClick={() => setSearchMode(val)} className={`btn btn-sm ${searchMode === val ? 'btn-primary' : 'btn-secondary'}`}>{label}</button>
            ))}
          </div>
        </div>
        {isSearching && (
          <div style={{ marginTop: 8, fontSize: '0.8rem', color: 'var(--text-muted)', display: 'flex', gap: 12, alignItems: 'center' }}>
            <span>{searching ? 'Searching...' : searchResults ? `${searchResults.length} quiz result${searchResults.length !== 1 ? 's' : ''}, ${allSearchQuestions.length} matching questions` : ''}</span>
            {!searching && allSearchQuestions.length > 0 && (
              <button className="btn btn-sm btn-secondary" onClick={() => setExpandedSearch(v => !v)}>
                {expandedSearch ? 'Show summary' : `View all ${allSearchQuestions.length} questions →`}
              </button>
            )}
          </div>
        )}
      </div>

      {/* Expanded full question search results */}
      {isSearching && expandedSearch && allSearchQuestions.length > 0 && (
        <div>
          <div style={{ marginBottom: 12, fontWeight: 600, fontSize: '0.95rem' }}>
            All matching questions for "{searchQuery}"
          </div>
          {allSearchQuestions.map((q, i) => (
            <div key={`${q.quiz_id}-${q.id}-${i}`} style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '12px 16px', marginBottom: 8, display: 'flex', gap: 12, alignItems: 'flex-start' }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: '0.72rem', color: 'var(--text-muted)', marginBottom: 4 }}>{q.quiz_title}</div>
                <div style={{ fontSize: '0.875rem', color: 'var(--text)', lineHeight: 1.5 }}>
                  <HighlightText text={q.question_text.slice(0, 200) + (q.question_text.length > 200 ? '…' : '')} query={searchQuery} />
                </div>
              </div>
              <button className="btn btn-sm btn-primary" onClick={() => setStudyQuestion(q)} style={{ flexShrink: 0 }}>Study</button>
            </div>
          ))}
        </div>
      )}

      {/* Search summary results (compact) */}
      {isSearching && !expandedSearch && searchResults !== null && (
        searchResults.length === 0 ? (
          <div className="card"><div className="empty-state">No matches for "{searchQuery}"</div></div>
        ) : searchResults.map(result => (
          <div key={result.quiz_id} className="card" style={{ marginBottom: 12 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: result.matching_questions.length > 0 ? 10 : 0 }}>
              <div style={{ cursor: 'pointer' }} onClick={() => navigate(`/quizzes/${result.quiz_id}`)}>
                <div style={{ fontWeight: 700, fontSize: '1rem', marginBottom: 2 }}>
                  <HighlightText text={result.quiz_title} query={result.match_type !== 'questions' ? searchQuery : ''} />
                </div>
                <div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>
                  {result.questions_count} questions
                  {result.match_type !== 'title' && ` · ${result.matching_questions.length} question match${result.matching_questions.length !== 1 ? 'es' : ''}`}
                </div>
              </div>
              {isModerator && (
                <ConfirmButton label="✕" confirmLabel="Trash?" cancelLabel="✕"
                  style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#cbd5e1', fontSize: '1rem', padding: '4px 8px' }}
                  onConfirm={() => deleteQuiz(result.quiz_id)} />
              )}
            </div>
            {result.matching_questions.slice(0, 2).map((q, i) => (
              <div key={q.id} style={{ padding: '8px 12px', background: 'var(--bg)', borderRadius: 6, marginBottom: 6, fontSize: '0.85rem', color: 'var(--text-muted)', borderLeft: '3px solid var(--primary)', display: 'flex', gap: 10, alignItems: 'center' }}>
                <div style={{ flex: 1 }}><HighlightText text={q.question_text.slice(0, 130) + (q.question_text.length > 130 ? '…' : '')} query={searchQuery} /></div>
                <button className="btn btn-sm btn-secondary" onClick={() => setStudyQuestion({ ...q, quiz_title: result.quiz_title })} style={{ flexShrink: 0 }}>Study</button>
              </div>
            ))}
            {result.matching_questions.length > 2 && (
              <button className="btn btn-sm btn-secondary" style={{ marginTop: 4 }} onClick={() => setExpandedSearch(true)}>
                +{result.matching_questions.length - 2} more — view all questions →
              </button>
            )}
          </div>
        ))
      )}

      {/* In-progress quizzes */}
      {!isSearching && <InProgressSection />}

      {/* Past attempts (loads on demand) */}
      {!isSearching && <PastAttemptsSection />}

      {/* Normal quiz grid */}
      {!isSearching && (
        <>
          {/* Category management (moderators) */}
          {isModerator && (
            <div className="card" style={{ marginBottom: 16 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: categories.length > 0 ? 12 : 0 }}>
                <h2 style={{ fontSize: '1rem' }}>Categories</h2>
                <button className="btn btn-sm btn-secondary" onClick={() => setAddingCat(v => !v)}>+ Add Category</button>
              </div>
              {addingCat && (
                <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
                  <input type="text" value={newCatName} onChange={e => setNewCatName(e.target.value)}
                    placeholder="Category name..." onKeyDown={e => e.key === 'Enter' && addCategory()}
                    style={{ flex: 1, padding: '7px 12px', border: '1px solid var(--border)', borderRadius: 8, fontSize: '0.875rem', background: 'var(--input-bg)', color: 'var(--text)' }} />
                  <button className="btn btn-primary btn-sm" onClick={addCategory}>Add</button>
                  <button className="btn btn-secondary btn-sm" onClick={() => { setAddingCat(false); setNewCatName('') }}>Cancel</button>
                </div>
              )}
              {categories.length > 0 && (
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                  {categories.map(cat => (
                    <div key={cat.id} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '4px 10px', background: 'var(--bg)', borderRadius: 20, border: '1px solid var(--border)', fontSize: '0.82rem' }}>
                      <span>{cat.name}</span>
                      <span style={{ color: 'var(--text-muted)' }}>({cat.quiz_count})</span>
                      <button onClick={() => deleteCategory(cat.id)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#cbd5e1', fontSize: '0.8rem', padding: '0 2px', lineHeight: 1 }}
                        onMouseEnter={e => e.currentTarget.style.color = '#ef4444'} onMouseLeave={e => e.currentTarget.style.color = '#cbd5e1'}>✕</button>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          {quizzes.length === 0 ? (
            <div className="card"><div className="empty-state">No quizzes yet. Upload a PDF and generate quizzes from sections.</div></div>
          ) : (
            <>
              {/* Categorised groups */}
              {Object.values(catMap).filter(c => c.quizzes.length > 0).map(cat => (
                <div key={cat.id} style={{ marginBottom: 24 }}>
                  <h3 style={{ fontSize: '0.9rem', fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 12 }}>
                    📁 {cat.name} <span style={{ fontWeight: 400 }}>({cat.quizzes.length})</span>
                  </h3>
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 16 }}>
                    {cat.quizzes.map(quiz => <QuizCard key={quiz.id} quiz={quiz} isModerator={isModerator} categories={categories} onDelete={deleteQuiz} onCategoryChange={handleCategoryChange} />)}
                  </div>
                </div>
              ))}

              {/* Uncategorised */}
              {uncategorized.length > 0 && (
                <div style={{ marginBottom: 24 }}>
                  {categories.length > 0 && (
                    <h3 style={{ fontSize: '0.9rem', fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 12 }}>
                      Uncategorized <span style={{ fontWeight: 400 }}>({uncategorized.length})</span>
                    </h3>
                  )}
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 16 }}>
                    {uncategorized.map(quiz => <QuizCard key={quiz.id} quiz={quiz} isModerator={isModerator} categories={categories} onDelete={deleteQuiz} onCategoryChange={handleCategoryChange} />)}
                  </div>
                </div>
              )}
            </>
          )}
        </>
      )}
    </div>
  )
}
