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

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

function stripHtml(html) {
  if (!html) return ''
  return html.replace(/<[^>]+>/g, ' ').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').replace(/\s+/g, ' ').trim()
}

const LESSON_TYPES = [
  { value: 'text', label: 'Text / Markdown', icon: '📝' },
  { value: 'video', label: 'Video', icon: '🎬' },
  { value: 'document', label: 'Document', icon: '📄' },
  { value: 'quiz', label: 'Quiz', icon: '✏️' },
  { value: 'live_session', label: 'Live Session', icon: '📡' },
  { value: 'scorm_package', label: 'SCORM Package', icon: '📦' },
]

const typeIcon = (type) => LESSON_TYPES.find(t => t.value === type)?.icon || '📝'

// --- Question Bank Mini-Browser ---
function QuestionBankBrowser({ courseId, onQuizCreated }) {
  const [categories, setCategories] = useState([])
  const [filterCatIds, setFilterCatIds] = useState([])
  const [tags, setTags] = useState({ subjects: [], diseases: [], keywords: [] })
  const [selectedTagIds, setSelectedTagIds] = useState([])
  const [showTags, setShowTags] = useState(false)
  const [search, setSearch] = useState('')
  const [questions, setQuestions] = useState([])
  const [total, setTotal] = useState(0)
  const [selected, setSelected] = useState(new Set())
  const [loading, setLoading] = useState(false)
  const [creating, setCreating] = useState(false)
  const [error, setError] = useState('')
  const debounceRef = useRef(null)

  useEffect(() => {
    api.get('/question-categories/').then(r => setCategories(r.data)).catch(() => {})
    api.get('/tags').then(r => setTags(r.data)).catch(() => {})
  }, [])

  const fetchQuestions = useCallback(async (q = search, catIds = filterCatIds, tagIds = selectedTagIds) => {
    setLoading(true)
    try {
      const params = { limit: 30 }
      if (q.trim()) params.q = q.trim()
      if (catIds.length > 0) params.category_ids = catIds.join(',')
      if (tagIds.length > 0) params.tag_ids = tagIds.join(',')
      const res = await api.get('/questions/bank', { params })
      setQuestions(res.data.questions || res.data || [])
      setTotal(res.data.total || 0)
    } catch {
      setQuestions([])
    } finally {
      setLoading(false)
    }
  }, [search, filterCatIds, selectedTagIds])

  const catIdsKey = filterCatIds.join(',')
  const tagIdsKey = selectedTagIds.join(',')
  useEffect(() => {
    clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => fetchQuestions(search, filterCatIds, selectedTagIds), 300)
    return () => clearTimeout(debounceRef.current)
  }, [search, catIdsKey, tagIdsKey])

  const toggleTag = (tagId) => setSelectedTagIds(prev => prev.includes(tagId) ? prev.filter(id => id !== tagId) : [...prev, tagId])

  const toggle = (qId) => {
    setSelected(prev => {
      const next = new Set(prev)
      next.has(qId) ? next.delete(qId) : next.add(qId)
      return next
    })
  }

  // Quiz settings
  const [quizTitle, setQuizTitle] = useState('')
  const [quizMode, setQuizMode] = useState('learning')
  const [quizTimeLimit, setQuizTimeLimit] = useState('')
  const [quizMaxAttempts, setQuizMaxAttempts] = useState('')
  const [quizQuestionsPerAttempt, setQuizQuestionsPerAttempt] = useState('')
  const [quizAllowReview, setQuizAllowReview] = useState(true)

  const createQuiz = async () => {
    if (selected.size === 0) return
    setCreating(true)
    setError('')
    try {
      const res = await api.post(`/courses/${courseId}/quiz`, {
        question_ids: [...selected],
        title: quizTitle.trim() || undefined,
        mode: quizMode,
        time_limit_minutes: quizTimeLimit ? parseInt(quizTimeLimit) : null,
        max_attempts: quizMaxAttempts ? parseInt(quizMaxAttempts) : null,
        questions_per_attempt: quizQuestionsPerAttempt ? parseInt(quizQuestionsPerAttempt) : null,
        allow_review: quizAllowReview,
      })
      setQuizTitle('')
      onQuizCreated(res.data.id)
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to create quiz')
    } finally {
      setCreating(false)
    }
  }

  // Inline add question
  const [showAddQ, setShowAddQ] = useState(false)
  const [newQ, setNewQ] = useState({ text: '', options: ['', '', '', ''], correctIdx: -1, explanation: '' })
  const [addingQ, setAddingQ] = useState(false)

  const submitNewQuestion = async () => {
    const validOpts = newQ.options.filter(o => o.trim())
    if (!newQ.text.trim() || validOpts.length < 2 || newQ.correctIdx < 0) return
    setAddingQ(true)
    try {
      const res = await api.post('/questions/create', {
        question_text: newQ.text,
        question_type: 'mcq',
        options: validOpts,
        correct_answer: newQ.options[newQ.correctIdx],
        explanation: newQ.explanation || null,
      })
      // Auto-select the new question
      setSelected(prev => new Set([...prev, res.data.id]))
      setNewQ({ text: '', options: ['', '', '', ''], correctIdx: -1, explanation: '' })
      setShowAddQ(false)
      fetchQuestions()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to add question')
    } finally {
      setAddingQ(false)
    }
  }

  const hasTags = tags.subjects?.length > 0 || tags.diseases?.length > 0 || tags.keywords?.length > 0

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 10, padding: 16, marginTop: 8, background: 'var(--bg)' }}>
      {/* Search */}
      <div style={{ position: 'relative', marginBottom: 10 }}>
        <span style={{ position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)', color: '#94a3b8', fontSize: '0.85rem' }}>🔍</span>
        <input
          type="text"
          value={search}
          onChange={e => setSearch(e.target.value)}
          placeholder="Search questions..."
          style={{ width: '100%', padding: '9px 12px 9px 32px', border: '1px solid var(--border)', borderRadius: 8, fontSize: '0.88rem', background: 'var(--input-bg)', color: 'var(--text)', boxSizing: 'border-box' }}
        />
      </div>

      {/* Category chips */}
      <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap', marginBottom: 10 }}>
        <button className={`btn btn-sm ${filterCatIds.length === 0 ? 'btn-primary' : 'btn-secondary'}`}
          onClick={() => setFilterCatIds([])} style={{ fontSize: '0.72rem', padding: '3px 10px' }}>All</button>
        {categories.map(cat => (
          <button key={cat.id} className={`btn btn-sm ${filterCatIds.includes(cat.id) ? 'btn-primary' : 'btn-secondary'}`}
            onClick={() => setFilterCatIds(prev => prev.includes(cat.id) ? prev.filter(c => c !== cat.id) : [...prev, cat.id])}
            style={{ fontSize: '0.72rem', padding: '3px 10px' }}>
            {cat.name} <span style={{ opacity: 0.6 }}>({cat.question_count})</span>
          </button>
        ))}
        {/* Active tag chips */}
        {selectedTagIds.map(tid => {
          const allTags = [...(tags.subjects || []), ...(tags.diseases || []), ...(tags.keywords || [])]
          const tag = allTags.find(t => t.id === tid)
          if (!tag) return null
          const color = (tags.subjects || []).find(t => t.id === tid) ? '#8b5cf6' : (tags.diseases || []).find(t => t.id === tid) ? '#ef4444' : '#0ea5e9'
          return (
            <button key={`tag-${tid}`} onClick={() => toggleTag(tid)}
              style={{ background: color, color: '#fff', border: 'none', fontSize: '0.72rem', padding: '3px 10px', borderRadius: 12, cursor: 'pointer', fontWeight: 600 }}>
              {tag.name} ✕
            </button>
          )
        })}
      </div>

      {/* Tag browser toggle */}
      {hasTags && (
        <div style={{ marginBottom: 10 }}>
          <button className="btn btn-sm btn-secondary" onClick={() => setShowTags(v => !v)}
            style={{ fontSize: '0.72rem', padding: '3px 10px' }}>
            Tags {showTags ? '▲' : '▼'}
          </button>
          {showTags && (
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: 8, marginTop: 8 }}>
              {[
                { key: 'subjects', label: 'Subjects', color: '#8b5cf6', items: tags.subjects || [] },
                { key: 'diseases', label: 'Diseases', color: '#ef4444', items: tags.diseases || [] },
                { key: 'keywords', label: 'Keywords', color: '#0ea5e9', items: tags.keywords || [] },
              ].map(sec => {
                if (sec.items.length === 0) return null
                return (
                  <div key={sec.key} style={{ background: 'var(--card-bg)', borderRadius: 8, padding: 8, border: '1px solid var(--border)' }}>
                    <div style={{ fontSize: '0.68rem', fontWeight: 700, color: sec.color, textTransform: 'uppercase', marginBottom: 4 }}>{sec.label}</div>
                    <div style={{ maxHeight: 120, overflowY: 'auto' }}>
                      {sec.items.map(tag => {
                        const sel = selectedTagIds.includes(tag.id)
                        return (
                          <button key={tag.id} onClick={() => toggleTag(tag.id)}
                            style={{ display: 'block', width: '100%', textAlign: 'left', background: sel ? sec.color : 'transparent',
                              color: sel ? '#fff' : 'var(--text)', border: 'none', borderRadius: 4, padding: '2px 6px',
                              fontSize: '0.72rem', cursor: 'pointer', marginBottom: 1 }}>
                            {tag.name} <span style={{ opacity: 0.5 }}>({tag.count})</span>
                          </button>
                        )
                      })}
                    </div>
                  </div>
                )
              })}
            </div>
          )}
        </div>
      )}

      {/* Results count */}
      <div style={{ fontSize: '0.75rem', color: 'var(--text-muted)', marginBottom: 6 }}>
        {total > 0 ? `${total} questions found` : ''} {selected.size > 0 ? `· ${selected.size} selected` : ''}
      </div>

      {/* Question list */}
      <div style={{ maxHeight: 420, overflowY: 'auto', marginBottom: 10 }}>
        {loading && questions.length === 0 && <div style={{ color: 'var(--text-muted)', fontSize: '0.85rem', padding: 12 }}>Loading...</div>}
        {!loading && questions.length === 0 && (
          <div style={{ color: 'var(--text-muted)', fontSize: '0.85rem', padding: 12 }}>No questions found.</div>
        )}
        {questions.map(q => {
          const isSelected = selected.has(q.id)
          const plainText = stripHtml(q.question_text)
          return (
            <div key={q.id} onClick={() => toggle(q.id)} style={{
              padding: '12px 14px', marginBottom: 6, borderRadius: 10, cursor: 'pointer',
              background: isSelected ? 'var(--option-sel-bg)' : 'var(--card-bg)',
              border: `2px solid ${isSelected ? 'var(--primary)' : 'var(--border)'}`,
              transition: 'all 0.15s',
            }}>
              {/* Top row: checkbox + category + source */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                <input type="checkbox" checked={isSelected} onChange={() => {}}
                  style={{ accentColor: 'var(--primary)', flexShrink: 0, width: 16, height: 16 }} />
                {q.question_category_name && (
                  <span style={{ fontSize: '0.7rem', fontWeight: 600, padding: '2px 8px', borderRadius: 10, background: 'var(--primary)', color: '#fff' }}>
                    {q.question_category_name}
                  </span>
                )}
                {q.quiz_title && <span style={{ fontSize: '0.7rem', color: 'var(--text-muted)' }}>{q.quiz_title}</span>}
              </div>

              {/* Question text */}
              <div style={{ fontSize: '0.88rem', color: 'var(--text)', lineHeight: 1.6, marginBottom: q.options ? 8 : 0 }}>
                {plainText.length > 220 ? plainText.slice(0, 220) + '...' : plainText}
              </div>

              {/* Options — each on its own row */}
              {q.options && q.options.length > 0 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                  {q.options.map((opt, i) => (
                    <div key={i} style={{
                      display: 'flex', alignItems: 'baseline', gap: 6,
                      fontSize: '0.8rem', color: 'var(--text-muted)', lineHeight: 1.4,
                    }}>
                      <span style={{
                        fontWeight: 700, fontSize: '0.72rem', color: 'var(--primary)',
                        background: 'var(--option-sel-bg)', borderRadius: 4, padding: '1px 5px',
                        flexShrink: 0,
                      }}>{String.fromCharCode(65 + i)}</span>
                      <span>{opt.length > 80 ? opt.slice(0, 80) + '...' : opt}</span>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )
        })}
      </div>

      {error && <div className="alert alert-error" style={{ marginBottom: 8, fontSize: '0.85rem' }}>{error}</div>}

      {/* Add question inline */}
      {showAddQ && (
        <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, marginBottom: 10, background: 'var(--card-bg)' }}>
          <div style={{ fontSize: '0.82rem', fontWeight: 600, marginBottom: 8 }}>Add New Question</div>
          <textarea value={newQ.text} onChange={e => setNewQ(q => ({ ...q, text: e.target.value }))}
            placeholder="Question text..." rows={2}
            style={{ width: '100%', padding: '8px 10px', border: '1px solid var(--border)', borderRadius: 6, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.85rem', resize: 'vertical', boxSizing: 'border-box', marginBottom: 8 }} />
          {newQ.options.map((opt, i) => (
            <div key={i} style={{ display: 'flex', gap: 6, alignItems: 'center', marginBottom: 4 }}>
              <button onClick={() => setNewQ(q => ({ ...q, correctIdx: i }))}
                style={{ width: 24, height: 24, borderRadius: '50%', border: `2px solid ${newQ.correctIdx === i ? 'var(--correct-fg)' : 'var(--border)'}`,
                  background: newQ.correctIdx === i ? 'var(--correct-fg)' : 'transparent', color: newQ.correctIdx === i ? '#fff' : 'var(--text-muted)',
                  fontSize: '0.7rem', fontWeight: 700, cursor: 'pointer', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                {String.fromCharCode(65 + i)}
              </button>
              <input value={opt} onChange={e => { const opts = [...newQ.options]; opts[i] = e.target.value; setNewQ(q => ({ ...q, options: opts })) }}
                placeholder={`Option ${String.fromCharCode(65 + i)}`}
                style={{ flex: 1, padding: '6px 10px', border: `1px solid ${newQ.correctIdx === i ? 'var(--correct-bd)' : 'var(--border)'}`, borderRadius: 6,
                  background: newQ.correctIdx === i ? 'var(--correct-bg)' : 'var(--input-bg)', color: 'var(--text)', fontSize: '0.82rem' }} />
            </div>
          ))}
          <textarea value={newQ.explanation} onChange={e => setNewQ(q => ({ ...q, explanation: e.target.value }))}
            placeholder="Explanation (optional)" rows={1}
            style={{ width: '100%', padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.82rem', resize: 'vertical', boxSizing: 'border-box', marginTop: 6 }} />
          <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
            <button className="btn btn-primary btn-sm" onClick={submitNewQuestion} disabled={addingQ || !newQ.text.trim() || newQ.correctIdx < 0}>
              {addingQ ? 'Adding...' : 'Add Question'}
            </button>
            <button className="btn btn-secondary btn-sm" onClick={() => setShowAddQ(false)}>Cancel</button>
          </div>
        </div>
      )}

      {/* Quiz settings */}
      {selected.size > 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 10, padding: '10px 12px', background: 'var(--card-bg)', borderRadius: 8, border: '1px solid var(--border)' }}>
          <input type="text" value={quizTitle} onChange={e => setQuizTitle(e.target.value)}
            placeholder="Quiz title (optional)" style={{ padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.85rem', background: 'var(--input-bg)', color: 'var(--text)', width: '100%' }} />
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
          <select value={quizMode} onChange={e => setQuizMode(e.target.value)}
            style={{ padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.82rem', background: 'var(--input-bg)', color: 'var(--text)' }}>
            <option value="learning">Study mode</option>
            <option value="timed">Timed exam</option>
          </select>
          {quizMode === 'timed' && (
            <input type="number" min={1} value={quizTimeLimit} onChange={e => setQuizTimeLimit(e.target.value)}
              placeholder="Time (min)" style={{ width: 90, padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.82rem', background: 'var(--input-bg)', color: 'var(--text)' }} />
          )}
          <input type="number" min={1} value={quizMaxAttempts} onChange={e => setQuizMaxAttempts(e.target.value)}
            placeholder="Max attempts" title="Leave blank for unlimited"
            style={{ width: 110, padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.82rem', background: 'var(--input-bg)', color: 'var(--text)' }} />
          <input type="number" min={1} max={selected.size} value={quizQuestionsPerAttempt} onChange={e => setQuizQuestionsPerAttempt(e.target.value)}
            placeholder={`Questions per try (${selected.size} pool)`} title="Random subset each attempt. Leave blank for all."
            style={{ width: 180, padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.82rem', background: 'var(--input-bg)', color: 'var(--text)' }} />
          <label style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: '0.82rem', color: 'var(--text)', cursor: 'pointer', whiteSpace: 'nowrap' }}>
            <input type="checkbox" checked={quizAllowReview} onChange={e => setQuizAllowReview(e.target.checked)} />
            Allow review
          </label>
          </div>
        </div>
      )}

      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        <button
          className="btn btn-primary btn-sm"
          onClick={createQuiz}
          disabled={selected.size === 0 || creating}
        >
          {creating ? 'Creating...' : `Create Quiz from ${selected.size} Question${selected.size !== 1 ? 's' : ''}`}
        </button>
        {!showAddQ && (
          <button className="btn btn-secondary btn-sm" onClick={() => setShowAddQ(true)}>+ Add Question</button>
        )}
      </div>
    </div>
  )
}

// --- Lesson Form ---
function LessonForm({ lesson, onSave, onCancel, courseId }) {
  const [title, setTitle] = useState(lesson?.title || '')
  const [type, setType] = useState(lesson?.lesson_type || 'text')
  const [contentText, setContentText] = useState(lesson?.content_text || '')
  const [videoUrl, setVideoUrl] = useState(lesson?.video_url || '')
  const [duration, setDuration] = useState(lesson?.duration_minutes || '')
  const [isRequired, setIsRequired] = useState(lesson?.is_required ?? true)
  const [liveUrl, setLiveUrl] = useState(lesson?.live_session_url || '')
  const [liveStart, setLiveStart] = useState(lesson?.live_session_start || '')
  const [liveEnd, setLiveEnd] = useState(lesson?.live_session_end || '')
  const [quizId, setQuizId] = useState(lesson?.quiz_id || null)
  const [file, setFile] = useState(null)
  const [saving, setSaving] = useState(false)
  const [aiPrompt, setAiPrompt] = useState('')
  const [aiLoading, setAiLoading] = useState(false)
  const [aiModels, setAiModels] = useState([])
  const [aiModelId, setAiModelId] = useState('')
  const [error, setError] = useState('')

  useEffect(() => {
    api.get('/admin/models/available?task=teach').then(r => {
      setAiModels(r.data || [])
    }).catch(() => {})
  }, [])

  const handleSave = async () => {
    if (!title.trim()) { setError('Title is required'); return }
    setSaving(true)
    setError('')
    try {
      const payload = {
        title: title.trim(),
        lesson_type: type,
        content_text: type === 'text' ? contentText : null,
        video_url: type === 'video' ? videoUrl : null,
        live_session_url: type === 'live_session' ? liveUrl : null,
        live_session_start: type === 'live_session' && liveStart ? liveStart : null,
        live_session_end: type === 'live_session' && liveEnd ? liveEnd : null,
        quiz_id: type === 'quiz' ? quizId : null,
        duration_minutes: duration ? parseInt(duration) : null,
        is_required: isRequired ? 1 : 0,
      }

      // Attach SCORM file for separate upload after lesson creation
      if (file && type === 'scorm_package') {
        payload._scormFile = file
        onSave(payload, false)
      } else if (file && (type === 'document' || type === 'video')) {
        const fd = new FormData()
        Object.entries(payload).forEach(([k, v]) => {
          if (v !== null && v !== undefined) fd.append(k, v)
        })
        fd.append('file', file)
        onSave(fd, true)
      } else {
        onSave(payload, false)
      }
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to save')
    } finally {
      setSaving(false)
    }
  }

  const aiGenerate = async (action = 'generate') => {
    if (!aiPrompt.trim() && action === 'generate') return
    setAiLoading(true)
    setError('')
    try {
      const endpoint = lesson?.id
        ? `/courses/${courseId}/lessons/${lesson.id}/ai-generate`
        : `/courses/${courseId}/ai-generate`
      const body = {
        prompt: aiPrompt || `Write lesson content about: ${title}`,
        action,
        existing_content: contentText || undefined,
      }
      if (aiModelId) body.model_id = aiModelId
      const res = await api.post(endpoint, body)
      if (res.data.generated_content) {
        let content = res.data.generated_content
        // Auto-set title if empty — use the prompt or first heading
        if (!title.trim()) {
          const headingMatch = content.match(/^#\s+(?:Lesson\s+Title:\s*)?(.+)/m)
          setTitle(headingMatch ? headingMatch[1].trim() : aiPrompt.trim().slice(0, 80))
        }
        // Remove any "# Lesson Title: ..." line from content
        content = content.replace(/^#\s+Lesson\s+Title:\s*.+\n+---\n*/m, '')
        setContentText(content)
      }
    } catch (err) {
      setError(err.response?.data?.detail || 'AI generation failed')
    } finally {
      setAiLoading(false)
    }
  }

  const detectVideoProvider = (url) => {
    if (!url) return null
    if (url.includes('youtube.com') || url.includes('youtu.be')) return 'YouTube'
    if (url.includes('vimeo.com')) return 'Vimeo'
    return null
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 16, marginTop: 8, background: 'var(--card-bg)' }}>
      {error && <div className="alert alert-error" style={{ marginBottom: 10, fontSize: '0.85rem' }}>{error}</div>}

      <div className="form-group">
        <label>Title</label>
        <input type="text" value={title} onChange={e => setTitle(e.target.value)} placeholder="Lesson title"
          style={{ width: '100%', padding: '10px 14px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.95rem', boxSizing: 'border-box' }} />
      </div>

      <div className="grid-2">
        <div className="form-group">
          <label>Type</label>
          <select value={type} onChange={e => setType(e.target.value)}>
            {LESSON_TYPES.map(t => (
              <option key={t.value} value={t.value}>{t.icon} {t.label}</option>
            ))}
          </select>
        </div>
        <div className="form-group">
          <label>Duration (minutes, optional)</label>
          <input type="number" min={1} value={duration} onChange={e => setDuration(e.target.value)} placeholder="Optional" />
        </div>
      </div>

      {/* Text content with rich editor */}
      {type === 'text' && (
        <div className="form-group">
          <label>Content</label>
          <Suspense fallback={<textarea value={contentText} onChange={e => setContentText(e.target.value)} rows={10} placeholder="Loading editor..." style={{ width: '100%', padding: 12, border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.9rem', resize: 'vertical', boxSizing: 'border-box' }} />}>
            <RichEditor value={contentText} onChange={setContentText} height={350} placeholder="Start writing your lesson content..." />
          </Suspense>
          <div style={{ display: 'flex', gap: 8, marginTop: 10, flexWrap: 'wrap', alignItems: 'center' }}>
            <input
              type="text"
              value={aiPrompt}
              onChange={e => setAiPrompt(e.target.value)}
              placeholder="Describe what AI should write or modify..."
              style={{ flex: 1, minWidth: 180, padding: '8px 12px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.9rem' }}
              onKeyDown={e => e.key === 'Enter' && aiGenerate('generate')}
            />
            {aiModels.length > 0 && (
              <select value={aiModelId} onChange={e => setAiModelId(e.target.value)}
                style={{ padding: '7px 10px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.82rem', maxWidth: 180 }}>
                <option value="">Default model</option>
                {aiModels.map(m => <option key={m.model_id} value={m.model_id}>{m.name || m.model_id}</option>)}
              </select>
            )}
            <button
              className="btn btn-primary btn-sm"
              onClick={() => aiGenerate('generate')}
              disabled={aiLoading || !aiPrompt.trim()}
            >
              {aiLoading ? 'Generating...' : 'AI Generate'}
            </button>
            {contentText.trim() && (
              <button
                className="btn btn-secondary btn-sm"
                onClick={() => aiGenerate('refine')}
                disabled={aiLoading}
              >
                AI Refine
              </button>
            )}
          </div>
        </div>
      )}

      {/* Video */}
      {type === 'video' && (
        <div className="form-group">
          <label>Video URL (YouTube / Vimeo) or upload</label>
          <input
            type="url"
            value={videoUrl}
            onChange={e => setVideoUrl(e.target.value)}
            placeholder="https://www.youtube.com/watch?v=..."
          />
          {detectVideoProvider(videoUrl) && (
            <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)', marginTop: 2, display: 'block' }}>
              Detected: {detectVideoProvider(videoUrl)}
            </span>
          )}
          <div style={{ marginTop: 8 }}>
            <label style={{ fontSize: '0.85rem', color: 'var(--text-muted)' }}>Or upload a video file:</label>
            <input type="file" accept="video/*" onChange={e => setFile(e.target.files[0])} style={{ marginTop: 4 }} />
          </div>
        </div>
      )}

      {/* Document */}
      {type === 'document' && (
        <div className="form-group">
          <label>Upload Document</label>
          <input type="file" accept=".pdf,.doc,.docx,.ppt,.pptx" onChange={e => setFile(e.target.files[0])} />
          {lesson?.local_file_path && !file && (
            <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)', marginTop: 2, display: 'block' }}>
              Current: {lesson.local_file_path}
            </span>
          )}
        </div>
      )}

      {/* Quiz */}
      {type === 'quiz' && (
        <div className="form-group">
          <label>Quiz</label>
          {quizId ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <span style={{ fontSize: '0.88rem', color: 'var(--correct-fg)', fontWeight: 600 }}>
                {lesson?.quiz_title || `Quiz #${quizId}`} linked
              </span>
              <button className="btn btn-secondary btn-sm" onClick={() => setQuizId(null)}>Change</button>
            </div>
          ) : (
            <QuestionBankBrowser courseId={courseId} onQuizCreated={(id) => {
              setQuizId(id)
              // Auto-save quiz_id to lesson if lesson already exists
              if (lesson?.id) {
                api.put(`/courses/${courseId}/lessons/${lesson.id}`, { quiz_id: id }).catch(() => {})
              }
            }} />
          )}
        </div>
      )}

      {/* SCORM Package */}
      {type === 'scorm_package' && (
        <div className="form-group">
          <label>SCORM Package (ZIP)</label>
          {lesson?.local_file_path ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
              <span style={{ fontSize: '0.85rem', color: 'var(--correct-fg)' }}>Package uploaded</span>
              <button className="btn btn-secondary btn-sm" onClick={() => {
                const input = document.createElement('input')
                input.type = 'file'; input.accept = '.zip'
                input.onchange = async (e) => {
                  const f = e.target.files[0]; if (!f) return
                  const fd = new FormData(); fd.append('file', f)
                  try {
                    await api.post(`/courses/${courseId}/lessons/${lesson.id}/scorm`, fd)
                    onSave({}) // refresh
                  } catch (err) { setError(err.response?.data?.detail || 'Upload failed') }
                }
                input.click()
              }}>Replace</button>
            </div>
          ) : (
            <input type="file" accept=".zip" onChange={e => setFile(e.target.files[0])} />
          )}
          <p style={{ fontSize: '0.78rem', color: 'var(--text-muted)', marginTop: 4 }}>
            Upload a SCORM 1.2 or 2004 package (ZIP with imsmanifest.xml)
          </p>
        </div>
      )}

      {/* Live Session */}
      {type === 'live_session' && (
        <>
          <div className="form-group">
            <label>Meeting URL</label>
            <input type="url" value={liveUrl} onChange={e => setLiveUrl(e.target.value)} placeholder="https://meet.example.com/..." />
          </div>
          <div className="grid-2">
            <div className="form-group">
              <label>Start Time</label>
              <input type="datetime-local" value={liveStart} onChange={e => setLiveStart(e.target.value)} />
            </div>
            <div className="form-group">
              <label>End Time</label>
              <input type="datetime-local" value={liveEnd} onChange={e => setLiveEnd(e.target.value)} />
            </div>
          </div>
        </>
      )}

      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 12 }}>
        <label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: '0.88rem', cursor: 'pointer' }}>
          <input type="checkbox" checked={isRequired} onChange={e => setIsRequired(e.target.checked)} />
          Required lesson
        </label>
      </div>

      <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
        <button className="btn btn-primary btn-sm" onClick={handleSave} disabled={saving}>
          {saving ? 'Saving...' : (lesson?.id ? 'Update Lesson' : 'Add Lesson')}
        </button>
        <button className="btn btn-secondary btn-sm" onClick={onCancel}>Cancel</button>
      </div>
    </div>
  )
}

// --- Main Page ---
export default function CourseEditorPage() {
  const { courseId } = useParams()
  const navigate = useNavigate()
  const { user } = useAuth()

  const [course, setCourse] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [success, setSuccess] = useState('')

  // Course settings
  const [title, setTitle] = useState('')
  const [description, setDescription] = useState('')
  const [thumbnail, setThumbnail] = useState(null)
  const [saving, setSaving] = useState(false)
  const [publishing, setPublishing] = useState(false)

  // Modules
  const [modules, setModules] = useState([])
  const [expandedModule, setExpandedModule] = useState(null)
  const [newModuleTitle, setNewModuleTitle] = useState('')
  const [addingModule, setAddingModule] = useState(false)
  const [showModuleForm, setShowModuleForm] = useState(false)
  const [editingModuleId, setEditingModuleId] = useState(null)
  const [editModuleTitle, setEditModuleTitle] = useState('')

  // Lessons
  const [editingLessonId, setEditingLessonId] = useState(null)
  const [showLessonForm, setShowLessonForm] = useState(null) // moduleId or null

  const isOwner = course && user && (course.user_id === user.id || user.role === 'admin')

  const fetchCourse = useCallback(async () => {
    try {
      const res = await api.get(`/courses/${courseId}`)
      const c = res.data
      setCourse(c)
      setTitle(c.title || '')
      setDescription(c.description || '')
      setModules(c.modules || [])
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to load course')
    } finally {
      setLoading(false)
    }
  }, [courseId])

  useEffect(() => { fetchCourse() }, [fetchCourse])

  const clearMessages = () => { setError(''); setSuccess('') }

  // --- Course Settings ---
  const saveCourse = async () => {
    clearMessages()
    setSaving(true)
    try {
      await api.put(`/courses/${courseId}`, { title: title.trim(), description: description.trim() })
      if (thumbnail) {
        const fd = new FormData()
        fd.append('file', thumbnail)
        await api.post(`/courses/${courseId}/thumbnail`, fd)
      }
      setSuccess('Course saved.')
      setThumbnail(null)
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to save')
    } finally {
      setSaving(false)
    }
  }

  const togglePublish = async () => {
    clearMessages()
    setPublishing(true)
    const action = course.status === 'published' ? 'unpublish' : 'publish'
    try {
      await api.post(`/courses/${courseId}/${action}`)
      setSuccess(action === 'publish' ? 'Course published!' : 'Course unpublished (draft).')
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || `Failed to ${action}`)
    } finally {
      setPublishing(false)
    }
  }

  // --- Module CRUD ---
  const addModule = async () => {
    if (!newModuleTitle.trim()) return
    setAddingModule(true)
    clearMessages()
    try {
      await api.post(`/courses/${courseId}/modules`, { title: newModuleTitle.trim() })
      setNewModuleTitle('')
      setShowModuleForm(false)
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to add module')
    } finally {
      setAddingModule(false)
    }
  }

  const updateModule = async (moduleId) => {
    if (!editModuleTitle.trim()) return
    clearMessages()
    try {
      await api.put(`/courses/${courseId}/modules/${moduleId}`, { title: editModuleTitle.trim() })
      setEditingModuleId(null)
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to update module')
    }
  }

  const deleteModule = async (moduleId) => {
    clearMessages()
    try {
      await api.delete(`/courses/${courseId}/modules/${moduleId}`)
      if (expandedModule === moduleId) setExpandedModule(null)
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to delete module')
    }
  }

  const reorderModule = async (moduleId, direction) => {
    const idx = modules.findIndex(m => m.id === moduleId)
    if ((direction === 'up' && idx === 0) || (direction === 'down' && idx === modules.length - 1)) return
    const swapIdx = direction === 'up' ? idx - 1 : idx + 1
    const newOrder = modules.map(m => m.id)
    ;[newOrder[idx], newOrder[swapIdx]] = [newOrder[swapIdx], newOrder[idx]]
    // Optimistic update
    const reordered = [...modules]
    ;[reordered[idx], reordered[swapIdx]] = [reordered[swapIdx], reordered[idx]]
    setModules(reordered)
    try {
      await api.put(`/courses/${courseId}/modules/reorder`, { module_ids: newOrder })
    } catch {
      fetchCourse()
    }
  }

  // --- Lesson CRUD ---
  const saveLesson = async (moduleId, lessonId, payload, isFormData) => {
    clearMessages()
    try {
      let savedLessonId = lessonId
      // Extract SCORM file before saving lesson metadata
      const scormFile = payload._scormFile
      if (scormFile) delete payload._scormFile

      if (lessonId) {
        await api.put(`/courses/${courseId}/lessons/${lessonId}`, payload)
      } else {
        const res = await api.post(`/courses/${courseId}/modules/${moduleId}/lessons`, payload)
        savedLessonId = res.data.id
      }

      // Upload SCORM package if present
      if (scormFile && savedLessonId) {
        const fd = new FormData()
        fd.append('file', scormFile)
        await api.post(`/courses/${courseId}/lessons/${savedLessonId}/scorm`, fd)
      }

      setEditingLessonId(null)
      setShowLessonForm(null)
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to save lesson')
    }
  }

  const deleteLesson = async (moduleId, lessonId) => {
    clearMessages()
    try {
      await api.delete(`/courses/${courseId}/lessons/${lessonId}`)
      fetchCourse()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to delete lesson')
    }
  }

  const reorderLesson = async (moduleId, lessonId, direction) => {
    const mod = modules.find(m => m.id === moduleId)
    if (!mod) return
    const lessons = mod.lessons || []
    const idx = lessons.findIndex(l => l.id === lessonId)
    if ((direction === 'up' && idx === 0) || (direction === 'down' && idx === lessons.length - 1)) return
    const swapIdx = direction === 'up' ? idx - 1 : idx + 1
    const newOrder = lessons.map(l => l.id)
    ;[newOrder[idx], newOrder[swapIdx]] = [newOrder[swapIdx], newOrder[idx]]
    // Optimistic update
    const reorderedLessons = [...lessons]
    ;[reorderedLessons[idx], reorderedLessons[swapIdx]] = [reorderedLessons[swapIdx], reorderedLessons[idx]]
    setModules(prev => prev.map(m => m.id === moduleId ? { ...m, lessons: reorderedLessons } : m))
    try {
      await api.put(`/courses/${courseId}/modules/${moduleId}/lessons/reorder`, { lesson_ids: newOrder })
    } catch {
      fetchCourse()
    }
  }

  if (loading) return <div className="loading"><div className="spinner"></div> Loading...</div>
  if (!course) return <div className="card"><p>Course not found.</p></div>

  return (
    <div>
      <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
        <button className="btn btn-secondary btn-sm" onClick={() => navigate('/courses')}>&larr; Back to Courses</button>
        <button className="btn btn-secondary btn-sm" onClick={() => navigate(`/courses/${courseId}`)}>Preview Course</button>
      </div>

      {error && <div className="alert alert-error">{error}</div>}
      {success && <div className="alert alert-success">{success}</div>}

      {/* Course Settings */}
      <div className="card">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 16 }}>
          <h2 style={{ margin: 0 }}>Course Settings</h2>
          <span className={`badge badge-${course.status || 'draft'}`}>{course.status || 'draft'}</span>
        </div>

        <div className="form-group">
          <label>Title</label>
          <input
            type="text"
            value={title}
            onChange={e => setTitle(e.target.value)}
            placeholder="Course title"
            disabled={!isOwner}
            style={{ width: '100%', padding: '10px 14px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '1rem', boxSizing: 'border-box' }}
          />
        </div>

        <div className="form-group">
          <label>Description</label>
          <textarea
            value={description}
            onChange={e => setDescription(e.target.value)}
            rows={4}
            placeholder="Describe what students will learn..."
            disabled={!isOwner}
            style={{ width: '100%', padding: '10px 14px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.95rem', resize: 'vertical', boxSizing: 'border-box' }}
          />
        </div>

        <div className="form-group">
          <label>Thumbnail (optional)</label>
          <input
            type="file"
            accept="image/*"
            onChange={e => setThumbnail(e.target.files[0])}
            disabled={!isOwner}
          />
          {course.thumbnail_path && !thumbnail && (
            <img
              src={course.thumbnail_path}
              alt="Thumbnail"
              style={{ marginTop: 8, maxHeight: 120, borderRadius: 8, objectFit: 'cover' }}
            />
          )}
        </div>

        {isOwner && (
          <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
            <button className="btn btn-primary" onClick={saveCourse} disabled={saving}>
              {saving ? 'Saving...' : 'Save Changes'}
            </button>
            <button className={`btn ${course.status === 'published' ? 'btn-secondary' : 'btn-primary'}`}
              onClick={togglePublish} disabled={publishing} style={course.status === 'published' ? { color: 'var(--wrong-fg)' } : {}}>
              {publishing ? '...' : course.status === 'published' ? 'Unpublish' : 'Publish'}
            </button>
          </div>
        )}
      </div>

      {/* Modules */}
      <div className="card">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
          <h2 style={{ margin: 0 }}>Modules</h2>
          {isOwner && (
            <button className="btn btn-primary btn-sm" onClick={() => setShowModuleForm(v => !v)}>
              + Add Module
            </button>
          )}
        </div>

        {showModuleForm && (
          <div style={{ display: 'flex', gap: 8, marginBottom: 16, alignItems: 'center' }}>
            <input
              type="text"
              value={newModuleTitle}
              onChange={e => setNewModuleTitle(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && addModule()}
              placeholder="Module title..."
              style={{ flex: 1, padding: '10px 14px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.95rem' }}
              autoFocus
            />
            <button className="btn btn-primary btn-sm" onClick={addModule} disabled={addingModule}>
              {addingModule ? 'Adding...' : 'Add'}
            </button>
            <button className="btn btn-secondary btn-sm" onClick={() => { setShowModuleForm(false); setNewModuleTitle('') }}>
              Cancel
            </button>
          </div>
        )}

        {modules.length === 0 && (
          <p style={{ color: 'var(--text-muted)', fontSize: '0.9rem' }}>
            No modules yet. Add your first module to start building the course.
          </p>
        )}

        {modules.map((mod, modIdx) => {
          const isExpanded = expandedModule === mod.id
          const lessons = mod.lessons || []

          return (
            <div key={mod.id} style={{ border: '1px solid var(--border)', borderRadius: 8, marginBottom: 10, overflow: 'hidden' }}>
              {/* Module header */}
              <div
                style={{
                  display: 'flex', alignItems: 'center', gap: 8, padding: '12px 14px',
                  background: isExpanded ? 'var(--bg)' : 'transparent', cursor: 'pointer',
                }}
                onClick={() => setExpandedModule(isExpanded ? null : mod.id)}
              >
                <span style={{ fontSize: '0.8rem', color: 'var(--text-muted)', transform: isExpanded ? 'rotate(90deg)' : 'none', transition: 'transform 0.15s' }}>
                  &#9654;
                </span>

                {editingModuleId === mod.id ? (
                  <input
                    type="text"
                    value={editModuleTitle}
                    onChange={e => setEditModuleTitle(e.target.value)}
                    onKeyDown={e => { if (e.key === 'Enter') updateModule(mod.id); if (e.key === 'Escape') setEditingModuleId(null) }}
                    onClick={e => e.stopPropagation()}
                    style={{ flex: 1, padding: '8px 12px', border: '1px solid var(--border)', borderRadius: 8, background: 'var(--input-bg)', color: 'var(--text)', fontSize: '0.95rem', fontWeight: 600 }}
                    autoFocus
                  />
                ) : (
                  <span style={{ flex: 1, fontWeight: 600 }}>
                    {mod.title}
                    <span style={{ fontWeight: 400, color: 'var(--text-muted)', fontSize: '0.82rem', marginLeft: 8 }}>
                      {lessons.length} lesson{lessons.length !== 1 ? 's' : ''}
                    </span>
                  </span>
                )}

                {isOwner && (
                  <div style={{ display: 'flex', gap: 4 }} onClick={e => e.stopPropagation()}>
                    {editingModuleId === mod.id ? (
                      <>
                        <button className="btn btn-primary btn-sm" onClick={() => updateModule(mod.id)}>Save</button>
                        <button className="btn btn-secondary btn-sm" onClick={() => setEditingModuleId(null)}>Cancel</button>
                      </>
                    ) : (
                      <>
                        <button
                          className="btn btn-secondary btn-sm"
                          style={{ padding: '2px 8px', fontSize: '0.85rem' }}
                          disabled={modIdx === 0}
                          onClick={() => reorderModule(mod.id, 'up')}
                          title="Move up"
                        >&#9650;</button>
                        <button
                          className="btn btn-secondary btn-sm"
                          style={{ padding: '2px 8px', fontSize: '0.85rem' }}
                          disabled={modIdx === modules.length - 1}
                          onClick={() => reorderModule(mod.id, 'down')}
                          title="Move down"
                        >&#9660;</button>
                        <button
                          className="btn btn-secondary btn-sm"
                          onClick={() => { setEditingModuleId(mod.id); setEditModuleTitle(mod.title) }}
                        >Edit</button>
                        <ConfirmButton
                          onConfirm={() => deleteModule(mod.id)}
                          label="Delete"
                          confirmLabel="Yes, delete"
                        />
                      </>
                    )}
                  </div>
                )}
              </div>

              {/* Expanded: lessons */}
              {isExpanded && (
                <div style={{ padding: '0 14px 14px' }}>
                  {lessons.length === 0 && (
                    <p style={{ color: 'var(--text-muted)', fontSize: '0.85rem', margin: '8px 0' }}>
                      No lessons in this module.
                    </p>
                  )}

                  {lessons.map((lesson, lesIdx) => (
                    <div key={lesson.id}>
                      {editingLessonId === lesson.id ? (
                        <LessonForm
                          lesson={lesson}
                          courseId={courseId}
                          onSave={(payload, isFormData) => saveLesson(mod.id, lesson.id, payload, isFormData)}
                          onCancel={() => setEditingLessonId(null)}
                        />
                      ) : (
                        <div style={{
                          display: 'flex', alignItems: 'center', gap: 8, padding: '8px 10px',
                          borderBottom: lesIdx < lessons.length - 1 ? '1px solid var(--border)' : 'none',
                        }}>
                          <span style={{ fontSize: '0.9rem' }}>{typeIcon(lesson.lesson_type)}</span>
                          <span style={{ flex: 1, fontSize: '0.9rem' }}>
                            {lesson.title}
                            {lesson.is_required === false && (
                              <span style={{ fontSize: '0.75rem', color: 'var(--text-muted)', marginLeft: 6 }}>optional</span>
                            )}
                          </span>
                          <span style={{ fontSize: '0.75rem', color: 'var(--text-muted)' }}>
                            {lesson.lesson_type}
                            {lesson.duration_minutes ? ` · ${lesson.duration_minutes}m` : ''}
                          </span>

                          {isOwner && (
                            <div style={{ display: 'flex', gap: 4 }}>
                              <button
                                className="btn btn-secondary btn-sm"
                                style={{ padding: '2px 8px', fontSize: '0.85rem' }}
                                disabled={lesIdx === 0}
                                onClick={() => reorderLesson(mod.id, lesson.id, 'up')}
                                title="Move up"
                              >&#9650;</button>
                              <button
                                className="btn btn-secondary btn-sm"
                                style={{ padding: '2px 8px', fontSize: '0.85rem' }}
                                disabled={lesIdx === lessons.length - 1}
                                onClick={() => reorderLesson(mod.id, lesson.id, 'down')}
                                title="Move down"
                              >&#9660;</button>
                              <button
                                className="btn btn-secondary btn-sm"
                                onClick={() => setEditingLessonId(lesson.id)}
                              >Edit</button>
                              <ConfirmButton
                                onConfirm={() => deleteLesson(mod.id, lesson.id)}
                                label="Delete"
                                confirmLabel="Yes, delete"
                              />
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  ))}

                  {/* Add lesson form */}
                  {showLessonForm === mod.id ? (
                    <LessonForm
                      courseId={courseId}
                      onSave={(payload, isFormData) => saveLesson(mod.id, null, payload, isFormData)}
                      onCancel={() => setShowLessonForm(null)}
                    />
                  ) : (
                    isOwner && (
                      <button
                        className="btn btn-secondary btn-sm"
                        style={{ marginTop: 10 }}
                        onClick={() => { setShowLessonForm(mod.id); setEditingLessonId(null) }}
                      >
                        + Add Lesson
                      </button>
                    )
                  )}
                </div>
              )}
            </div>
          )
        })}
      </div>

      {/* Enrollees */}
      {isOwner && <EnrolleesSection courseId={courseId} />}
    </div>
  )
}

function EnrolleesSection({ courseId }) {
  const [enrollees, setEnrollees] = useState([])
  const [loading, setLoading] = useState(false)
  const [expanded, setExpanded] = useState(false)

  const load = () => {
    setLoading(true)
    api.get(`/courses/${courseId}/enrollees`).then(r => setEnrollees(r.data)).catch(() => {}).finally(() => setLoading(false))
  }

  return (
    <div className="card">
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <h2 style={{ margin: 0 }}>Enrollees</h2>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn btn-secondary btn-sm" onClick={() => { setExpanded(v => !v); if (!expanded) load() }}>
            {expanded ? 'Hide' : 'Show'}
          </button>
          <button className="btn btn-secondary btn-sm" onClick={async () => {
            try {
              const res = await api.get(`/courses/${courseId}/enrollees/export`, { responseType: 'blob' })
              const blob = new Blob([res.data], { type: 'text/csv;charset=utf-8' })
              const url = window.URL.createObjectURL(blob)
              const a = document.createElement('a')
              a.href = url; a.download = 'enrollees.csv'; a.click()
              window.URL.revokeObjectURL(url)
            } catch {}
          }}>Export CSV</button>
        </div>
      </div>

      {expanded && (
        <div style={{ marginTop: 16 }}>
          {loading && <div className="loading"><div className="spinner" /></div>}
          {!loading && enrollees.length === 0 && (
            <p style={{ color: 'var(--text-muted)', fontSize: '0.88rem' }}>No enrollees yet.</p>
          )}
          {enrollees.map(e => (
            <div key={e.user_id} style={{ padding: '12px 0', borderBottom: '1px solid var(--border)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 8 }}>
                <div>
                  <span style={{ fontWeight: 600, fontSize: '0.92rem' }}>{e.name}</span>
                  <span style={{ color: 'var(--text-muted)', fontSize: '0.82rem', marginLeft: 8 }}>{e.email}</span>
                </div>
                <div style={{ display: 'flex', gap: 12, alignItems: 'center', fontSize: '0.85rem' }}>
                  <span style={{ color: e.progress_pct >= 100 ? 'var(--correct-fg)' : 'var(--text-muted)' }}>
                    {e.progress_pct}% complete
                  </span>
                  <span style={{ color: 'var(--text-muted)' }}>
                    {e.completed_lessons} lessons
                  </span>
                </div>
              </div>
              <div className="progress-bar" style={{ height: 4, marginTop: 6 }}>
                <div className="fill" style={{ width: `${e.progress_pct}%` }} />
              </div>
              {e.quiz_scores && e.quiz_scores.length > 0 && (
                <div style={{ marginTop: 8, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                  {e.quiz_scores.map(qs => (
                    <span key={qs.quiz_id} style={{
                      fontSize: '0.78rem', padding: '3px 8px', borderRadius: 6,
                      background: qs.percentage >= 75 ? 'var(--correct-bg)' : qs.percentage >= 50 ? '#fef3c7' : 'var(--wrong-bg)',
                      color: qs.percentage >= 75 ? 'var(--correct-fg)' : qs.percentage >= 50 ? '#92400e' : 'var(--wrong-fg)',
                      fontWeight: 600,
                    }}>
                      {qs.quiz_title}: {qs.percentage}% ({qs.attempts} attempt{qs.attempts !== 1 ? 's' : ''})
                    </span>
                  ))}
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  )
}
