import { useState, useEffect, useCallback, useRef } from 'react'
import { useParams } from 'react-router-dom'
import { AppShell } from '../components/layout/AppShell'
import { Button } from '../components/ui/Button'
import { TermLabel } from '../components/ui/Tooltip'
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
  status: string
}

interface ExportFile {
  filename: string
  episode_id: string | null
  file_path: string
  size_bytes: number
  created_at: string
}

interface ValidationResult {
  text_readable: boolean
  images_present: boolean
  layout_correct: boolean
  caption_visible: boolean
  overall_quality: number
  issues: string[]
  pdf_filename: string
  error?: string
}

type StepStatus = 'idle' | 'running' | 'done' | 'error'

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

  const [episodes, setEpisodes] = useState<Episode[]>([])
  const [selectedEpisodeId, setSelectedEpisodeId] = useState<string>('')
  const [webEpisodeCount, setWebEpisodeCount] = useState(4)
  const [sectionsPerEp, setSectionsPerEp] = useState(10)
  const [exportFiles, setExportFiles] = useState<ExportFile[]>([])
  const [loading, setLoading] = useState(true)
  const [generating, setGenerating] = useState(false)
  const [rendering, setRendering] = useState(false)
  const [message, setMessage] = useState('')
  const [messageType, setMessageType] = useState<'info' | 'error'>('info')
  const [webbookStatus, setWebbookStatus] = useState<StepStatus>('idle')
  const [pdfStatus, setPdfStatus] = useState<StepStatus>('idle')
  const [validations, setValidations] = useState<Record<string, ValidationResult>>({})
  const [validatingFile, setValidatingFile] = useState<string | null>(null)
  const [exportProgress, setExportProgress] = useState<AllProgress | null>(null)
  const exportPollRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const fetchEpisodes = useCallback(async () => {
    if (!id) return
    try {
      const data = await api<Episode[]>(`/api/v1/projects/${id}/episodes/`)
      setEpisodes(data)
      if (data.length > 0 && !selectedEpisodeId) {
        setSelectedEpisodeId(data[0].id)
      }
    } catch {
      setEpisodes([])
    }
  }, [id, selectedEpisodeId])

  const fetchExports = useCallback(async () => {
    if (!id) return
    setLoading(true)
    try {
      const data = await api<ExportFile[]>(`/api/v1/projects/${id}/exports`)
      setExportFiles(data)
    } catch {
      setExportFiles([])
    } finally {
      setLoading(false)
    }
  }, [id])

  const fetchExportProgress = useCallback(async () => {
    if (!id || !selectedEpisodeId) return
    try {
      const data = await api<AllProgress>(
        `/api/v1/projects/${id}/episodes/${selectedEpisodeId}/progress`,
      )
      setExportProgress(data)
    } catch {
      // ignore
    }
  }, [id, selectedEpisodeId])

  useEffect(() => { fetchEpisodes() }, [fetchEpisodes])
  useEffect(() => { fetchExports() }, [fetchExports])

  // Poll progress while generating or rendering
  useEffect(() => {
    if (generating || rendering) {
      fetchExportProgress()
      if (!exportPollRef.current) {
        exportPollRef.current = setInterval(() => {
          fetchExportProgress()
        }, 3000)
      }
    } else {
      if (exportPollRef.current) {
        clearInterval(exportPollRef.current)
        exportPollRef.current = null
      }
    }
    return () => {
      if (exportPollRef.current) {
        clearInterval(exportPollRef.current)
        exportPollRef.current = null
      }
    }
  }, [generating, rendering, fetchExportProgress])

  const handleGenerateWebbook = async () => {
    if (!id || !selectedEpisodeId) return
    setGenerating(true)
    setMessage('')
    setWebbookStatus('running')
    try {
      const resp = await api<{ ok: boolean; message: string }>(
        `/api/v1/projects/${id}/episodes/${selectedEpisodeId}/generate-webbook`,
        {
          method: 'POST',
          body: JSON.stringify({
            web_episode_count: webEpisodeCount,
            sections_per_episode: sectionsPerEp,
          }),
        },
      )
      setMessage(resp.message)
      setMessageType('info')
      setWebbookStatus('done')
    } catch {
      setMessage(t('export.error_generating'))
      setMessageType('error')
      setWebbookStatus('error')
    } finally {
      setGenerating(false)
    }
  }

  const handleRenderPdf = async () => {
    if (!id || !selectedEpisodeId) return
    setRendering(true)
    setMessage('')
    setPdfStatus('running')
    try {
      const resp = await api<{ ok: boolean; message: string }>(
        `/api/v1/projects/${id}/episodes/${selectedEpisodeId}/render-pdf`,
        { method: 'POST' },
      )
      setMessage(resp.message)
      setMessageType('info')
      setPdfStatus('done')
      await fetchExports()
    } catch {
      setMessage(t('export.error_rendering'))
      setMessageType('error')
      setPdfStatus('error')
    } finally {
      setRendering(false)
    }
  }

  const handleValidate = async (filename: string) => {
    if (!id) return
    setValidatingFile(filename)
    try {
      const result = await api<ValidationResult>(
        `/api/v1/projects/${id}/exports/${filename}/validate`,
        { method: 'POST' },
      )
      setValidations(prev => ({ ...prev, [filename]: result }))
    } catch {
      setValidations(prev => ({
        ...prev,
        [filename]: {
          text_readable: false,
          images_present: false,
          layout_correct: false,
          caption_visible: false,
          overall_quality: 0,
          issues: [t('export.validation_failed')],
          pdf_filename: filename,
          error: 'Validation request failed',
        },
      }))
    } finally {
      setValidatingFile(null)
    }
  }

  const formatBytes = (bytes: number): string => {
    if (bytes < 1024) return `${bytes} B`
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
    return `${(bytes / 1024 / 1024).toFixed(1)} MB`
  }

  const formatDate = (iso: string): string => {
    try {
      const d = new Date(iso)
      return d.toLocaleDateString('ko-KR', {
        year: 'numeric', month: '2-digit', day: '2-digit',
        hour: '2-digit', minute: '2-digit',
      })
    } catch {
      return iso
    }
  }

  const stepBadge = (status: StepStatus) => {
    const map: Record<StepStatus, { cls: string; label: string }> = {
      idle: { cls: 'muted', label: '--' },
      running: { cls: 'pulse', label: t('export.status_running') },
      done: { cls: 'green', label: t('export.status_done') },
      error: { cls: 'red', label: t('export.status_error') },
    }
    const s = map[status]
    return <span className={`badge ${s.cls}`}>{s.label}</span>
  }

  const qualityColor = (score: number): string => {
    if (score >= 8) return 'var(--green)'
    if (score >= 5) return 'var(--orange)'
    return 'var(--red)'
  }

  const checkIcon = (ok: boolean) => ok ? '\u2713' : '\u2717'
  const checkColor = (ok: boolean) => ok ? 'var(--green)' : 'var(--red)'

  return (
    <AppShell title={t('export.title')} projectId={id}>
      <div className="page">
        {/* Pipeline controls */}
        <div className="card" style={{ padding: '20px', marginBottom: '20px' }}>
          <div style={{ display: 'grid', gap: '16px', maxWidth: '600px' }}>
            <div>
              <label style={{ fontSize: '13px', fontWeight: 600, display: 'block', marginBottom: '6px' }}>
                {t('nav.project.episodes')}
              </label>
              <select
                className="input"
                value={selectedEpisodeId}
                onChange={e => setSelectedEpisodeId(e.target.value)}
              >
                {episodes.map(ep => (
                  <option key={ep.id} value={ep.id}>
                    EP{ep.episode_number} - {ep.title}
                  </option>
                ))}
              </select>
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
              <div>
                <label style={{ fontSize: '13px', fontWeight: 600, display: 'block', marginBottom: '6px' }}>
                  <TermLabel label={t('export.episode_count')} term={t('term.webbook_episode')} />
                </label>
                <input
                  type="number"
                  className="input"
                  min={1}
                  max={10}
                  value={webEpisodeCount}
                  onChange={e => setWebEpisodeCount(Number(e.target.value))}
                />
              </div>
              <div>
                <label style={{ fontSize: '13px', fontWeight: 600, display: 'block', marginBottom: '6px' }}>
                  {t('export.sections_per_ep')}
                </label>
                <input
                  type="number"
                  className="input"
                  min={1}
                  max={20}
                  value={sectionsPerEp}
                  onChange={e => setSectionsPerEp(Number(e.target.value))}
                />
              </div>
            </div>

            {/* Pipeline steps with status */}
            <div style={{
              display: 'grid',
              gridTemplateColumns: '1fr 1fr',
              gap: '12px',
              background: 'var(--bg-input)',
              borderRadius: 'var(--radius-sm)',
              padding: '14px',
            }}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                  <span style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase' }}>
                    {t('export.step_webbook')}
                  </span>
                  {stepBadge(webbookStatus)}
                </div>
                {generating && exportProgress?.webbook && exportProgress.webbook.status === 'running' && (
                  <ProgressBar data={exportProgress.webbook} />
                )}
                <Button
                  disabled={generating || !selectedEpisodeId}
                  onClick={handleGenerateWebbook}
                >
                  {generating ? t('export.status_running') : t('export.generate_webbook')}
                </Button>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                  <span style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase' }}>
                    {t('export.step_pdf')}
                  </span>
                  {stepBadge(pdfStatus)}
                </div>
                {rendering && exportProgress?.pdf_render && exportProgress.pdf_render.status === 'running' && (
                  <ProgressBar data={exportProgress.pdf_render} />
                )}
                <Button
                  variant="secondary"
                  disabled={rendering || !selectedEpisodeId}
                  onClick={handleRenderPdf}
                >
                  {rendering ? t('export.status_running') : t('export.render_pdf')}
                </Button>
              </div>
            </div>

            {message && (
              <div style={{
                fontSize: '13px',
                fontWeight: 500,
                color: messageType === 'error' ? 'var(--red)' : 'var(--accent)',
                padding: '8px 12px',
                background: messageType === 'error' ? 'var(--red-bg)' : 'var(--accent-glow)',
                borderRadius: 'var(--radius-sm)',
              }}>
                {message}
              </div>
            )}
          </div>
        </div>

        {/* Export files */}
        <h3 style={{ fontSize: '15px', fontWeight: 700, marginBottom: '12px' }}>
          {t('export.files')}
          {exportFiles.length > 0 && (
            <span style={{ fontSize: '12px', color: 'var(--text-dim)', fontWeight: 400, marginLeft: '8px' }}>
              ({exportFiles.length})
            </span>
          )}
        </h3>

        {loading ? (
          <div className="empty-state">{t('common.loading')}</div>
        ) : exportFiles.length === 0 ? (
          <div className="empty-state">{t('export.no_files')}</div>
        ) : (
          <div style={{ display: 'grid', gap: '10px' }}>
            {exportFiles.map(file => {
              const validation = validations[file.filename]
              const isValidating = validatingFile === file.filename

              return (
                <div
                  key={file.filename}
                  className="card"
                  style={{ padding: '14px 18px' }}
                >
                  <div style={{
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                  }}>
                    <div>
                      <div style={{ fontWeight: 600, fontSize: '14px', fontFamily: 'var(--font-mono)' }}>
                        {file.filename}
                      </div>
                      <div style={{ fontSize: '12px', color: 'var(--text-dim)', marginTop: '4px', display: 'flex', gap: '12px' }}>
                        <span>{formatBytes(file.size_bytes)}</span>
                        <span>{formatDate(file.created_at)}</span>
                      </div>
                    </div>
                    <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
                      <Button
                        variant="ghost"
                        size="sm"
                        disabled={isValidating}
                        onClick={() => handleValidate(file.filename)}
                      >
                        {isValidating ? t('export.validating') : t('export.validate')}
                      </Button>
                      <a
                        href={`/api/v1/projects/${id}/exports/${file.filename}`}
                        download
                        style={{ textDecoration: 'none' }}
                      >
                        <Button variant="ghost" size="sm">
                          {t('export.download')}
                        </Button>
                      </a>
                    </div>
                  </div>

                  {/* Validation result */}
                  {validation && (
                    <div style={{
                      marginTop: '12px',
                      paddingTop: '12px',
                      borderTop: '1px solid var(--border)',
                    }}>
                      {validation.error ? (
                        <div style={{ fontSize: '12px', color: 'var(--red)' }}>
                          {validation.error}
                        </div>
                      ) : (
                        <>
                          <div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', fontSize: '12px' }}>
                            <span style={{ color: checkColor(validation.text_readable) }}>
                              {checkIcon(validation.text_readable)} {t('export.check_text')}
                            </span>
                            <span style={{ color: checkColor(validation.images_present) }}>
                              {checkIcon(validation.images_present)} {t('export.check_images')}
                            </span>
                            <span style={{ color: checkColor(validation.layout_correct) }}>
                              {checkIcon(validation.layout_correct)} {t('export.check_layout')}
                            </span>
                            <span style={{ color: checkColor(validation.caption_visible) }}>
                              {checkIcon(validation.caption_visible)} {t('export.check_caption')}
                            </span>
                            <span style={{
                              fontWeight: 700,
                              fontFamily: 'var(--font-mono)',
                              color: qualityColor(validation.overall_quality),
                            }}>
                              {t('export.quality')}: {validation.overall_quality}/10
                            </span>
                          </div>
                          {validation.issues.length > 0 && (
                            <div style={{ marginTop: '8px', fontSize: '12px', color: 'var(--text-muted)' }}>
                              {validation.issues.map((issue, i) => (
                                <div key={i} style={{ marginTop: '2px' }}>- {issue}</div>
                              ))}
                            </div>
                          )}
                        </>
                      )}
                    </div>
                  )}
                </div>
              )
            })}
          </div>
        )}
      </div>
    </AppShell>
  )
}
