import { useState, useEffect, useCallback, useRef } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { AppShell } from '../components/layout/AppShell'
import { Button } from '../components/ui/Button'
import { Input } from '../components/ui/Input'
import { Modal } from '../components/ui/Modal'
import { Badge } from '../components/ui/Badge'
import { ProgressBar } from '../components/shared/PipelineProgress'
import type { AllProgress } from '../components/shared/PipelineProgress'
import { useI18n } from '../i18n/useI18n'
import { api } from '../api/client'

interface Episode {
  id: string
  episode_number: number
  title: string
  source_filename: string
  language: string
  page_count: number | null
  status: string
  created_at: string
}

function statusVariant(status: string): 'green' | 'orange' | 'red' | 'muted' | 'pulse' {
  switch (status) {
    case 'analyzed': return 'green'
    case 'analyzing': return 'pulse'
    case 'error': return 'red'
    default: return 'muted'
  }
}

function formatDate(iso: string): string {
  return new Date(iso).toLocaleDateString('ko-KR', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
  })
}

export function Episodes() {
  const { id } = useParams<{ id: string }>()
  const { t } = useI18n()
  const navigate = useNavigate()

  const [episodes, setEpisodes] = useState<Episode[]>([])
  const [loading, setLoading] = useState(true)
  const [addOpen, setAddOpen] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [formError, setFormError] = useState<string | null>(null)

  const [epNumber, setEpNumber] = useState('')
  const [epTitle, setEpTitle] = useState('')
  const [epFile, setEpFile] = useState<File | null>(null)

  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const [progressMap, setProgressMap] = useState<Record<string, AllProgress>>({})

  const fetchEpisodes = useCallback(async () => {
    if (!id) return
    try {
      const data = await api<Episode[]>(`/api/v1/projects/${id}/episodes/`)
      setEpisodes(data)
    } catch {
      setEpisodes([])
    } finally {
      setLoading(false)
    }
  }, [id])

  const fetchProgress = useCallback(async (episodeId: string) => {
    if (!id) return
    try {
      const data = await api<AllProgress>(`/api/v1/projects/${id}/episodes/${episodeId}/progress`)
      setProgressMap(prev => ({ ...prev, [episodeId]: data }))
    } catch {
      // ignore
    }
  }, [id])

  // Poll while any episode is analyzing or has running operations
  useEffect(() => {
    fetchEpisodes()
  }, [fetchEpisodes])

  useEffect(() => {
    const hasAnalyzing = episodes.some((e) => e.status === 'analyzing')
    const hasRunning = Object.values(progressMap).some(p =>
      p && Object.values(p).some(op => op && op.status === 'running')
    )

    if (hasAnalyzing || hasRunning) {
      if (!pollRef.current) {
        pollRef.current = setInterval(() => {
          fetchEpisodes()
          // Fetch progress for analyzing episodes
          episodes.forEach(ep => {
            if (ep.status === 'analyzing') {
              fetchProgress(ep.id)
            }
          })
        }, 3000)
      }
    } else {
      if (pollRef.current) {
        clearInterval(pollRef.current)
        pollRef.current = null
      }
    }
    return () => {
      if (pollRef.current) {
        clearInterval(pollRef.current)
        pollRef.current = null
      }
    }
  }, [episodes, progressMap, fetchEpisodes, fetchProgress])

  // Fetch progress for analyzing episodes on initial load
  useEffect(() => {
    episodes.forEach(ep => {
      if (ep.status === 'analyzing') {
        fetchProgress(ep.id)
      }
    })
  }, [episodes, fetchProgress])

  const handleAnalyze = async (episodeId: string, e: React.MouseEvent) => {
    e.stopPropagation()
    try {
      await api(`/api/v1/projects/${id}/episodes/${episodeId}/analyze`, { method: 'POST' })
      await fetchEpisodes()
    } catch (err: any) {
      const msg = err?.message || '분석 시작에 실패했습니다'
      alert(msg)
    }
  }

  const handleAddSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!epFile) {
      setFormError(t('episode.file'))
      return
    }
    setSubmitting(true)
    setFormError(null)
    try {
      const fd = new FormData()
      fd.append('episode_number', epNumber)
      fd.append('title', epTitle)
      fd.append('file', epFile)

      await fetch(`/api/v1/projects/${id}/episodes/`, {
        method: 'POST',
        credentials: 'include',
        body: fd,
      }).then(async (res) => {
        if (!res.ok) {
          const body = await res.json().catch(() => ({}))
          throw body
        }
        return res.json()
      })

      setAddOpen(false)
      setEpNumber('')
      setEpTitle('')
      setEpFile(null)
      await fetchEpisodes()
    } catch (err: any) {
      setFormError(err?.detail ?? err?.message ?? 'Error')
    } finally {
      setSubmitting(false)
    }
  }

  const statusLabel = (status: string): string => {
    const map: Record<string, string> = {
      uploaded: t('episode.status.uploaded'),
      analyzing: t('episode.status.analyzing'),
      analyzed: t('episode.status.analyzed'),
      error: t('episode.status.error'),
    }
    return map[status] ?? status
  }

  return (
    <AppShell title={t('nav.project.episodes')} projectId={id}>
      <div className="page">
        <div className="card">
          <div className="card-header">
            <h2>{t('nav.project.episodes')}</h2>
            <div className="card-actions">
              <Button variant="primary" size="sm" onClick={() => setAddOpen(true)}>
                + {t('episode.add')}
              </Button>
            </div>
          </div>

          {loading ? (
            <div className="empty-state">{t('common.loading')}</div>
          ) : episodes.length === 0 ? (
            <div className="empty-state">{t('episode.no_episodes')}</div>
          ) : (
            <div style={{ display: 'grid', gap: '12px' }}>
              {episodes.map((ep) => (
                <div
                  key={ep.id}
                  className="episode-card"
                  style={{
                    background: 'var(--bg-raised)',
                    border: '1px solid var(--border)',
                    borderRadius: 'var(--radius)',
                    padding: '16px 20px',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '16px',
                    cursor: ep.status === 'analyzed' ? 'pointer' : 'default',
                    transition: 'border-color 0.15s',
                  }}
                  onClick={() => {
                    if (ep.status === 'analyzed') {
                      navigate(`/projects/${id}/episodes/${ep.id}`)
                    }
                  }}
                  onMouseEnter={(e) => {
                    if (ep.status === 'analyzed') {
                      (e.currentTarget as HTMLElement).style.borderColor = 'var(--accent)'
                    }
                  }}
                  onMouseLeave={(e) => {
                    (e.currentTarget as HTMLElement).style.borderColor = 'var(--border)'
                  }}
                >
                  {/* Episode number badge */}
                  <div style={{
                    width: '48px',
                    height: '48px',
                    background: 'var(--accent-glow)',
                    borderRadius: 'var(--radius-sm)',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    flexShrink: 0,
                    fontFamily: 'var(--font-mono)',
                    fontWeight: 700,
                    fontSize: '18px',
                    color: 'var(--accent)',
                  }}>
                    {ep.episode_number}
                  </div>

                  {/* Episode info */}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: 600, fontSize: '15px', marginBottom: '4px', fontFamily: 'var(--font-serif)' }}>
                      {ep.title}
                    </div>
                    <div style={{ display: 'flex', gap: '12px', color: 'var(--text-muted)', fontSize: '12px', flexWrap: 'wrap' }}>
                      <span>{ep.source_filename}</span>
                      {ep.page_count != null && (
                        <span>{ep.page_count} {t('episode.pages')}</span>
                      )}
                      <span>{ep.language.toUpperCase()}</span>
                      <span>{formatDate(ep.created_at)}</span>
                    </div>
                  </div>

                  {/* Status + actions */}
                  <div style={{ display: 'flex', alignItems: 'center', gap: '10px', flexShrink: 0 }}>
                    <Badge label={statusLabel(ep.status)} variant={statusVariant(ep.status)} />

                    {ep.status === 'uploaded' && (
                      <Button
                        variant="secondary"
                        size="sm"
                        onClick={(e) => handleAnalyze(ep.id, e)}
                      >
                        {t('episode.analyze')}
                      </Button>
                    )}

                    {ep.status === 'error' && (
                      <Button
                        variant="warning"
                        size="sm"
                        onClick={(e) => handleAnalyze(ep.id, e)}
                      >
                        {t('episode.analyze')}
                      </Button>
                    )}

                    {ep.status === 'analyzing' && (
                      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: '4px' }}>
                        {progressMap[ep.id]?.analysis && progressMap[ep.id].analysis!.status === 'running' ? (
                          <ProgressBar data={progressMap[ep.id].analysis!} />
                        ) : (
                          <span style={{ fontSize: '12px', color: 'var(--text-muted)' }}>
                            {t('episode.analyzing_wait')}
                          </span>
                        )}
                      </div>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* Add episode modal */}
      <Modal open={addOpen} title={t('episode.add')} onClose={() => { setAddOpen(false); setFormError(null) }}>
        <form className="form-stack" onSubmit={handleAddSubmit}>
          <Input
            id="ep-number"
            label={t('episode.number')}
            type="number"
            min={1}
            required
            value={epNumber}
            onChange={(e) => setEpNumber(e.target.value)}
          />
          <Input
            id="ep-title"
            label={t('episode.title')}
            type="text"
            required
            value={epTitle}
            onChange={(e) => setEpTitle(e.target.value)}
          />
          <div className="field">
            <label htmlFor="ep-file">{t('episode.file')}</label>
            <input
              id="ep-file"
              type="file"
              accept=".pdf"
              required
              onChange={(e) => setEpFile(e.target.files?.[0] ?? null)}
            />
          </div>

          {formError && (
            <div style={{ color: 'var(--red)', fontSize: '13px' }}>{formError}</div>
          )}

          <div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>
            <Button type="button" variant="ghost" onClick={() => { setAddOpen(false); setFormError(null) }}>
              {t('btn.cancel')}
            </Button>
            <Button type="submit" variant="primary" disabled={submitting}>
              {submitting ? t('common.loading') : t('btn.create')}
            </Button>
          </div>
        </form>
      </Modal>
    </AppShell>
  )
}
