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

function ExtractionProgress({ jobId, onDone, onClose, label = 'Extracting Questions' }) {
  const [steps, setSteps] = useState([])
  const [status, setStatus] = useState('pending')
  const [quizId, setQuizId] = useState(null)
  const [error, setError] = useState('')
  const intervalRef = useRef(null)
  const bottomRef = useRef(null)

  const poll = useCallback(async () => {
    try {
      const res = await api.get(`/quizzes/job/${jobId}`)
      const newSteps = res.data.steps || []
      setSteps(newSteps)
      setStatus(res.data.status)
      // Update localStorage job tracker
      const lastStep = newSteps.length ? newSteps[newSteps.length - 1].message : 'Processing…'
      const stored = JSON.parse(localStorage.getItem('pedquiz_jobs') || '[]')
      const idx = stored.findIndex(j => j.jobId === jobId)
      if (idx >= 0) { stored[idx].status = res.data.status; stored[idx].lastStep = lastStep.slice(0, 60) }
      localStorage.setItem('pedquiz_jobs', JSON.stringify(stored))
      if (res.data.status === 'completed') {
        setQuizId(res.data.quiz_id)
        clearInterval(intervalRef.current)
      }
      if (res.data.status === 'failed') {
        setError(res.data.error || 'Extraction failed')
        clearInterval(intervalRef.current)
      }
    } catch { }
  }, [jobId])

  useEffect(() => {
    poll()
    intervalRef.current = setInterval(poll, 2000)
    return () => clearInterval(intervalRef.current)
  }, [poll])

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [steps.length])

  const stepIcon = (step) => {
    if (step === 'error') return '✗'
    if (step === 'done') return '✓'
    if (step === 'ai') return '🤖'
    if (step === 'text') return '📄'
    if (step === 'images') return '🖼'
    if (step === 'save') return '💾'
    return '→'
  }

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.6)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
      <div style={{ background: 'var(--card-bg)', borderRadius: 14, padding: 28, maxWidth: 520, width: '100%', boxShadow: '0 20px 60px rgba(0,0,0,0.35)' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
          <h2 style={{ margin: 0, fontSize: '1.1rem' }}>
            {status === 'completed' ? `✓ ${label} Complete` : status === 'failed' ? `✗ ${label} Failed` : `🤖 ${label}…`}
          </h2>
          <button onClick={onClose} title="Close — job runs in background" style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-muted)', fontSize: '1.1rem' }}>✕</button>
        </div>

        <div style={{ background: 'var(--bg)', borderRadius: 8, padding: '12px 16px', maxHeight: 280, overflowY: 'auto', fontFamily: 'monospace', fontSize: '0.82rem' }}>
          {steps.length === 0 && <div style={{ color: 'var(--text-muted)' }}>Starting…</div>}
          {steps.map((s, i) => (
            <div key={i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', marginBottom: 8, color: s.step === 'error' ? 'var(--wrong-fg)' : s.step === 'done' ? 'var(--correct-fg)' : 'var(--text)' }}>
              <span style={{ flexShrink: 0, fontSize: '0.9rem' }}>{stepIcon(s.step)}</span>
              <span style={{ lineHeight: 1.5 }}>{s.message}</span>
            </div>
          ))}
          {(status === 'pending' || status === 'running') && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, color: 'var(--text-muted)' }}>
              <div className="spinner" style={{ width: 14, height: 14, borderWidth: 2 }} />
              <span>Working…</span>
            </div>
          )}
          <div ref={bottomRef} />
        </div>

        {error && <div className="alert alert-error" style={{ marginTop: 12 }}>{error}</div>}

        <div style={{ marginTop: 16, display: 'flex', gap: 8, justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>
            {status === 'completed' || status === 'failed' ? '' : '✕ closes this panel — job continues in background'}
          </span>
          {status === 'completed' && quizId && (
            <button className="btn btn-primary" onClick={() => onDone(quizId)}>
              Open Quiz →
            </button>
          )}
          {(status === 'failed' || status === 'completed') && (
            <button className="btn btn-secondary" onClick={onClose}>Close</button>
          )}
        </div>
      </div>
    </div>
  )
}

export default function DocumentDetailPage() {
  const { id } = useParams()
  const navigate = useNavigate()
  const { user } = useAuth()
  const [doc, setDoc] = useState(null)
  const [loading, setLoading] = useState(true)
  const [sectionForm, setSectionForm] = useState({ name: '', start_page: 1, end_page: 10 })
  const [creating, setCreating] = useState(false)
  const [deletingSection, setDeletingSection] = useState(null)
  const [activeJob, setActiveJob] = useState(null) // {jobId, sectionName}
  const [generating, setGenerating] = useState(null)
  const [quizTitle, setQuizTitle] = useState('')
  const [quizMode, setQuizMode] = useState('timed')
  const [timeLimitMinutes, setTimeLimitMinutes] = useState('')
  const [selectedModelId, setSelectedModelId] = useState('')
  const [availableModels, setAvailableModels] = useState([])
  const [extractionMode, setExtractionMode] = useState('standard')
  const [questionCategories, setQuestionCategories] = useState([])
  const [selectedQuestionCategoryId, setSelectedQuestionCategoryId] = useState('')
  const [newCatInline, setNewCatInline] = useState('')
  const [showNewCat, setShowNewCat] = useState(false)
  const [error, setError] = useState('')

  const isModerator = user?.role === 'admin' || user?.role === 'moderator'

  const fetchDoc = () => {
    api.get(`/documents/${id}`).then(res => {
      setDoc(res.data)
      setLoading(false)
    }).catch(() => navigate('/'))
  }

  useEffect(() => {
    fetchDoc()
    Promise.all([
      api.get('/admin/models/available?task=extraction').catch(() => ({ data: [] })),
      api.get('/question-categories/').catch(() => ({ data: [] })),
    ]).then(([modelsRes, catsRes]) => {
      setAvailableModels(modelsRes.data)
      const def = modelsRes.data.find(m => m.is_default) || modelsRes.data[0]
      if (def) setSelectedModelId(def.model_id)
      setQuestionCategories(catsRes.data)
    })
  }, [id])

  const [processingSteps, setProcessingSteps] = useState([])
  useEffect(() => {
    if (!doc || doc.status !== 'processing') return
    const interval = setInterval(() => {
      Promise.all([
        api.get(`/documents/${id}/status`),
        api.get(`/documents/${id}/processing-steps`).catch(() => ({ data: { steps: [] } })),
      ]).then(([statusRes, stepsRes]) => {
        setProcessingSteps(stepsRes.data.steps || [])
        if (statusRes.data.status !== 'processing') {
          fetchDoc()
          clearInterval(interval)
        }
      })
    }, 2000)
    return () => clearInterval(interval)
  }, [doc?.status])

  const createSection = async (e) => {
    e.preventDefault()
    setCreating(true)
    setError('')
    try {
      await api.post(`/documents/${id}/sections`, sectionForm)
      fetchDoc()
      setSectionForm({ name: '', start_page: 1, end_page: 10 })
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to create section')
    } finally {
      setCreating(false)
    }
  }

  const generateFlashcards = async (sectionId, sectionName) => {
    setGenerating(sectionId)
    setError('')
    try {
      const title = quizTitle || `Flashcards: ${sectionName}`
      const res = await api.post('/flashcards/', {
        section_id: sectionId,
        title,
        model_id: selectedModelId || null,
      })
      if (res.data.job_id) {
        const stored = JSON.parse(localStorage.getItem('pedquiz_jobs') || '[]')
        stored.unshift({ jobId: res.data.job_id, title, status: 'running', lastStep: 'Starting…', ts: Date.now() })
        localStorage.setItem('pedquiz_jobs', JSON.stringify(stored.slice(0, 10)))
        setActiveJob({ jobId: res.data.job_id, sectionName, type: 'flashcard' })
      }
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to start flashcard generation. Check AI model config.')
    } finally {
      setGenerating(null)
    }
  }

  const generateQuiz = async (sectionId, sectionName) => {
    setGenerating(sectionId)
    setError('')
    try {
      const title = quizTitle || `Quiz: ${sectionName}`
      const res = await api.post('/quizzes/', {
        section_id: sectionId,
        title,
        mode: quizMode,
        time_limit_minutes: quizMode === 'timed' && timeLimitMinutes ? parseInt(timeLimitMinutes) : null,
        model_id: selectedModelId || null,
        question_category_id: selectedQuestionCategoryId ? parseInt(selectedQuestionCategoryId) : null,
        extraction_mode: extractionMode,
      })
      // Async: show progress panel
      if (res.data.job_id) {
        // Track in localStorage so navbar badge can show it
        const title = quizTitle || `Quiz: ${sectionName}`
        const stored = JSON.parse(localStorage.getItem('pedquiz_jobs') || '[]')
        stored.unshift({ jobId: res.data.job_id, title, status: 'running', lastStep: 'Starting…', ts: Date.now() })
        localStorage.setItem('pedquiz_jobs', JSON.stringify(stored.slice(0, 10)))
        setActiveJob({ jobId: res.data.job_id, sectionName })
        // If already completed (sync fallback), navigate directly
        if (res.data.status === 'completed' && res.data.quiz_id) {
          navigate(`/quizzes/${res.data.quiz_id}`)
        }
      } else if (res.data.id) {
        navigate(`/quizzes/${res.data.id}`)
      }
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to start extraction. Check AI model config.')
    } finally {
      setGenerating(null)
    }
  }

  const deleteSection = async (sectionId) => {
    setDeletingSection(sectionId)
    try {
      await api.delete(`/documents/${id}/sections/${sectionId}`)
      fetchDoc()
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to delete section')
    } finally { setDeletingSection(null) }
  }

  const createCategoryAndSelect = async () => {
    const name = newCatInline.trim()
    if (!name) return
    try {
      const res = await api.post('/question-categories/', { name })
      setQuestionCategories(prev => [...prev, res.data])
      setSelectedQuestionCategoryId(String(res.data.id))
      setNewCatInline('')
      setShowNewCat(false)
    } catch (err) {
      setError(err.response?.data?.detail || 'Failed to create category')
    }
  }

  const deleteDoc = async () => {
    await api.delete(`/documents/${id}`)
    navigate('/')
  }

  // Warn if user tries to close while a job is running
  useEffect(() => {
    if (!activeJob) return
    const handler = (e) => { e.preventDefault(); e.returnValue = '' }
    window.addEventListener('beforeunload', handler)
    return () => window.removeEventListener('beforeunload', handler)
  }, [activeJob])

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

  return (
    <div>
      {activeJob && (
        <ExtractionProgress
          jobId={activeJob.jobId}
          label={activeJob.type === 'flashcard' ? 'Generating Flashcards' : 'Extracting Questions'}
          onDone={(quizId) => { setActiveJob(null); if (activeJob.type === 'flashcard') navigate('/flashcards'); else navigate(`/quizzes/${quizId}`) }}
          onClose={() => setActiveJob(null)}
        />
      )}
      <div className="card">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div>
            <h2>{doc.original_filename}</h2>
            <p style={{ color: '#64748b', fontSize: '0.9rem' }}>
              {doc.total_pages ? `${doc.total_pages} pages` : ''} · Uploaded {new Date(doc.uploaded_at).toLocaleDateString()}
            </p>
          </div>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <span className={`badge badge-${doc.status}`}>{doc.status}</span>
            {isModerator && <ConfirmButton onConfirm={deleteDoc} label="Delete" confirmLabel="Yes, delete document" />}
          </div>
        </div>

        {doc.status === 'processing' && (
          <div style={{ marginTop: 16 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
              <div className="spinner"></div>
              <span style={{ color: 'var(--text-muted)', fontSize: '0.9rem' }}>Processing PDF…</span>
            </div>
            {processingSteps.length > 0 && (
              <div style={{ padding: '10px 14px', background: 'var(--bg)', borderRadius: 8, fontSize: '0.82rem', color: 'var(--text-muted)', maxHeight: 150, overflowY: 'auto' }}>
                {processingSteps.map((s, i) => (
                  <div key={i} style={{ marginBottom: 2 }}>
                    {s.step === 'error' ? '✗' : s.step === 'done' ? '✓' : '›'} {s.message}
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
        {doc.status === 'error' && (
          <div className="alert alert-error" style={{ marginTop: 16 }}>
            Error: {doc.error_message || 'Unknown error'}
          </div>
        )}
      </div>

      {doc.status === 'ready' && (
        <>
          {error && <div className="alert alert-error">{error}</div>}

          {/* Moderators can create sections */}
          {isModerator && (
            <div className="card">
              <h2>Create Section</h2>
              <p style={{ color: '#64748b', marginBottom: 16, fontSize: '0.9rem' }}>
                Define page ranges — the AI will extract all questions from those pages.
              </p>
              <form onSubmit={createSection}>
                <div className="grid-2">
                  <div className="form-group">
                    <label>Section Name</label>
                    <input
                      type="text"
                      value={sectionForm.name}
                      onChange={e => setSectionForm({ ...sectionForm, name: e.target.value })}
                      placeholder="e.g., Chapter 1 (pages 1–50)"
                      required
                    />
                  </div>
                  <div style={{ display: 'flex', gap: 12 }}>
                    <div className="form-group" style={{ flex: 1 }}>
                      <label>Start Page</label>
                      <input type="number" min={1} max={doc.total_pages || 9999} value={sectionForm.start_page}
                        onChange={e => setSectionForm({ ...sectionForm, start_page: parseInt(e.target.value) || 1 })} />
                    </div>
                    <div className="form-group" style={{ flex: 1 }}>
                      <label>End Page</label>
                      <input type="number" min={1} max={doc.total_pages || 9999} value={sectionForm.end_page}
                        onChange={e => setSectionForm({ ...sectionForm, end_page: parseInt(e.target.value) || 10 })} />
                    </div>
                  </div>
                </div>
                <button className="btn btn-primary" disabled={creating}>
                  {creating ? 'Creating...' : 'Create Section'}
                </button>
              </form>
            </div>
          )}

          {/* Sections list */}
          {doc.sections && doc.sections.length > 0 && (
            <div className="card">
              <h2>Sections</h2>

              {/* Quiz settings (moderator only) */}
              {isModerator && (
                <div style={{ background: '#f8fafc', padding: 16, borderRadius: 8, marginBottom: 16 }}>
                  <strong style={{ display: 'block', marginBottom: 12 }}>Quiz Settings</strong>
                  <div className="grid-2">
                    <div className="form-group">
                      <label>Quiz Title (optional)</label>
                      <input type="text" value={quizTitle} onChange={e => setQuizTitle(e.target.value)}
                        placeholder="Auto-generated if empty" />
                    </div>
                    <div className="form-group">
                      <label>Mode</label>
                      <select value={quizMode} onChange={e => setQuizMode(e.target.value)}>
                        <option value="timed">Timed — answers hidden, timer counts down</option>
                        <option value="learning">Learning — answers + explanations shown inline</option>
                      </select>
                    </div>
                    {quizMode === 'timed' && (
                      <div className="form-group">
                        <label>Time Limit (minutes, optional)</label>
                        <input type="number" min={1} value={timeLimitMinutes}
                          onChange={e => setTimeLimitMinutes(e.target.value)}
                          placeholder="Leave blank for no limit" />
                      </div>
                    )}
                    <div className="form-group">
                      <label>Extraction Mode</label>
                      <select value={extractionMode} onChange={e => setExtractionMode(e.target.value)}>
                        <option value="standard">Standard — inline answers (Correct Answer / Preferred Response)</option>
                        <option value="questions_only">Questions Only — no answers (fill in manually later)</option>
                        <option value="ai_answer">AI Answer — extract questions, AI determines correct answers</option>
                        <option value="two_step">Two-Step — separate answer key section (PREP 2013 style)</option>
                        <option value="regex">AI + Regex — AI analyses format then applies regex for answers</option>
                        <option value="ai_decide">AI Decides — AI reads the document and picks best strategy</option>
                        <option value="generate">Generate — AI creates questions from plain text / textbook chapters</option>
                      </select>
                      <p style={{ fontSize: '0.75rem', color: 'var(--text-subtle)', marginTop: 4 }}>
                        {extractionMode === 'standard' && 'Best for PREP 2012, 2014 and most PDFs with answers inline.'}
                        {extractionMode === 'questions_only' && 'Extracts questions + options only. Answer each question manually in Edit mode.'}
                        {extractionMode === 'ai_answer' && 'For Q&A PDFs with no answer key. AI extracts questions then determines the correct answer and explanation from document context + medical knowledge.'}
                        {extractionMode === 'two_step' && 'For PDFs where all questions come first, then all answers at the back (PREP 2013 style).'}
                        {extractionMode === 'regex' && 'AI detects the answer pattern, then uses regex for fast reliable extraction.'}
                        {extractionMode === 'ai_decide' && 'AI samples the document and automatically picks the right strategy (standard, two_step, or ai_answer).'}
                        {extractionMode === 'generate' && 'For textbook chapters, lecture notes, or any material without a Q&A format. AI creates MCQ questions with correct answers from the text.'}
                      </p>
                    </div>
                    {availableModels.length > 1 && (
                      <div className="form-group">
                        <label>Extraction Model</label>
                        <select value={selectedModelId} onChange={e => setSelectedModelId(e.target.value)}>
                          {availableModels.map(m => (
                            <option key={m.model_id} value={m.model_id}>
                              {m.name}{m.is_default ? ' (default)' : ''}
                            </option>
                          ))}
                        </select>
                      </div>
                    )}
                    <div className="form-group">
                      <label>Add Questions to Bank Category <span style={{ fontWeight: 400, color: 'var(--text-muted)' }}>(optional)</span></label>
                      <div style={{ display: 'flex', gap: 8 }}>
                        <select value={selectedQuestionCategoryId}
                          onChange={e => setSelectedQuestionCategoryId(e.target.value)}
                          style={{ flex: 1 }}>
                          <option value="">— No category —</option>
                          {questionCategories.map(c => (
                            <option key={c.id} value={String(c.id)}>
                              {c.name}{c.question_count > 0 ? ` (${c.question_count})` : ''}
                            </option>
                          ))}
                        </select>
                        <button type="button" className="btn btn-secondary btn-sm" style={{ whiteSpace: 'nowrap' }}
                          onClick={() => setShowNewCat(v => !v)}>
                          + New
                        </button>
                      </div>
                      {showNewCat && (
                        <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                          <input type="text" value={newCatInline}
                            onChange={e => setNewCatInline(e.target.value)}
                            onKeyDown={e => e.key === 'Enter' && createCategoryAndSelect()}
                            placeholder="Category name…"
                            style={{ flex: 1, padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.85rem', background: 'var(--input-bg)', color: 'var(--text)' }}
                            autoFocus />
                          <button type="button" className="btn btn-primary btn-sm" onClick={createCategoryAndSelect}>Add</button>
                          <button type="button" className="btn btn-secondary btn-sm" onClick={() => { setShowNewCat(false); setNewCatInline('') }}>✕</button>
                        </div>
                      )}
                      <p style={{ fontSize: '0.75rem', color: 'var(--text-subtle)', marginTop: 4 }}>
                        Extracted questions will be tagged with this category in the Question Bank.
                      </p>
                    </div>
                  </div>
                </div>
              )}

              {doc.sections.map(section => (
                <div className="section-item" key={section.id}>
                  <div>
                    <strong>{section.name}</strong>
                    <div style={{ fontSize: '0.85rem', color: '#64748b' }}>
                      Pages {section.start_page}–{section.end_page}
                    </div>
                  </div>
                  <div style={{ display: 'flex', gap: 8 }}>
                    {isModerator && (
                      <>
                        <button
                          className="btn btn-primary btn-sm"
                          onClick={() => generateQuiz(section.id, section.name)}
                          disabled={generating === section.id}
                        >
                          {generating === section.id ? (
                            <><span className="spinner" style={{ width: 12, height: 12, borderWidth: 2 }}></span> Extracting...</>
                          ) : 'Extract Quiz'}
                        </button>
                        <button
                          className="btn btn-secondary btn-sm"
                          onClick={() => generateFlashcards(section.id, section.name)}
                          disabled={generating === section.id}
                        >
                          Create Flashcards
                        </button>
                        <ConfirmButton
                          onConfirm={() => deleteSection(section.id)}
                          label="Delete section"
                          confirmLabel="Yes, delete"
                          disabled={deletingSection === section.id}
                        />
                      </>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </>
      )}
    </div>
  )
}
