import { useState, useEffect, useCallback } from 'react'
import { useParams } from 'react-router-dom'
import { AppShell } from '../components/layout/AppShell'
import { Badge } from '../components/ui/Badge'
import { Button } from '../components/ui/Button'
import { Modal } from '../components/ui/Modal'
import { TermLabel } from '../components/ui/Tooltip'
import { useI18n } from '../i18n/useI18n'
import { api } from '../api/client'

interface ImageAsset {
  id: string
  asset_type: string
  entity_id: string | null
  still_id: string | null
  episode_id: string | null
  file_path: string
  prompt_used: string | null
  generation_model: string | null
  width: number | null
  height: number | null
  status: string
  review_notes: string
  sanitization_strategy: string | null
  original_prompt: string | null
  sanitization_note: string | null
  is_primary: boolean
  created_at: string
}

type TypeFilter = 'all' | 'reference' | 'scene'
type StatusFilter = 'all' | 'generated' | 'approved' | 'needs_fix'

function statusVariant(status: string): 'default' | 'green' | 'orange' | 'red' {
  switch (status) {
    case 'approved': return 'green'
    case 'needs_fix': return 'orange'
    case 'regenerating': return 'red'
    default: return 'default'
  }
}

function strategyLabel(strategy: string | null, t: (k: string) => string): string {
  if (!strategy) return t('image.strategy.original')
  const map: Record<string, string> = {
    film_previs: t('image.strategy.film_previs'),
    movie_poster: t('image.strategy.movie_poster'),
    aftermath: t('image.strategy.aftermath'),
  }
  return map[strategy] ?? strategy
}

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

  const [images, setImages] = useState<ImageAsset[]>([])
  const [loading, setLoading] = useState(true)
  const [typeFilter, setTypeFilter] = useState<TypeFilter>('all')
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all')

  const [selectedImage, setSelectedImage] = useState<ImageAsset | null>(null)
  const [zoomOpen, setZoomOpen] = useState(false)
  const [noteOpen, setNoteOpen] = useState(false)

  const [reviewStatus, setReviewStatus] = useState<string>('approved')
  const [reviewNotes, setReviewNotes] = useState<string>('')
  const [saving, setSaving] = useState(false)
  const [regenerating, setRegenerating] = useState(false)

  const fetchImages = useCallback(async () => {
    if (!id) return
    setLoading(true)
    try {
      const params = new URLSearchParams()
      if (typeFilter !== 'all') params.set('type', typeFilter)
      const url = `/api/v1/projects/${id}/images${params.toString() ? '?' + params.toString() : ''}`
      const data = await api<ImageAsset[]>(url)
      setImages(data)
    } catch {
      setImages([])
    } finally {
      setLoading(false)
    }
  }, [id, typeFilter])

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

  const filteredImages = statusFilter === 'all'
    ? images
    : images.filter(img => img.status === statusFilter)

  const handleReviewSave = async (imageId: string) => {
    if (!id) return
    setSaving(true)
    try {
      await api(`/api/v1/projects/${id}/images/${imageId}/review`, {
        method: 'PATCH',
        body: JSON.stringify({ status: reviewStatus, notes: reviewNotes }),
      })
      await fetchImages()
      setSelectedImage(null)
    } catch {
      // ignore
    } finally {
      setSaving(false)
    }
  }

  const handleSetPrimary = async (imageId: string) => {
    if (!id) return
    try {
      await api(`/api/v1/projects/${id}/images/${imageId}/set-primary`, {
        method: 'POST',
      })
      await fetchImages()
      // Update selected image if we're in a modal
      if (selectedImage && selectedImage.id === imageId) {
        setSelectedImage(prev => prev ? { ...prev, is_primary: true } : null)
      }
    } catch {
      // ignore
    }
  }

  const handleRegenerateNeedsFix = async () => {
    if (!id) return
    setRegenerating(true)
    try {
      // Collect ALL unique episode IDs that have needs_fix images
      const needsFixImages = images.filter(img => img.status === 'needs_fix')
      const episodeIds = [...new Set(needsFixImages.map(img => img.episode_id).filter(Boolean))]
      for (const episodeId of episodeIds) {
        await api(`/api/v1/projects/${id}/episodes/${episodeId}/regenerate-needs-fix`, {
          method: 'POST',
        })
      }
      await fetchImages()
    } catch {
      // ignore
    } finally {
      setRegenerating(false)
    }
  }

  const openReview = (img: ImageAsset) => {
    setSelectedImage(img)
    setReviewStatus(img.status === 'needs_fix' || img.status === 'approved' ? img.status : 'approved')
    setReviewNotes(img.review_notes || '')
    setNoteOpen(false)
  }

  const needsFixCount = images.filter(img => img.status === 'needs_fix').length

  // Group images by entity/still for display
  const groupedImages: Record<string, ImageAsset[]> = {}
  for (const img of filteredImages) {
    const key = img.entity_id
      ? `entity:${img.entity_id}`
      : img.still_id
        ? `still:${img.still_id}`
        : 'ungrouped'
    if (!groupedImages[key]) groupedImages[key] = []
    groupedImages[key].push(img)
  }

  return (
    <AppShell title={t('nav.project.images')} projectId={id}>
      <div className="page">
        {/* Filter bar */}
        <div style={{ display: 'flex', gap: '12px', marginBottom: '20px', flexWrap: 'wrap', alignItems: 'center' }}>
          <div className="tab-bar">
            {(['all', 'reference', 'scene'] as TypeFilter[]).map(tf => (
              <button
                key={tf}
                className={`tab${typeFilter === tf ? ' active' : ''}`}
                onClick={() => setTypeFilter(tf)}
              >
                {tf === 'all' ? t('entity.filter.all') : tf === 'reference' ? <TermLabel label={t('image.type.reference')} term={t('term.reference_image')} /> : t('image.type.scene')}
              </button>
            ))}
          </div>
          <div className="tab-bar">
            {(['all', 'generated', 'approved', 'needs_fix'] as StatusFilter[]).map(sf => (
              <button
                key={sf}
                className={`tab${statusFilter === sf ? ' active' : ''}`}
                onClick={() => setStatusFilter(sf)}
              >
                {sf === 'all' ? t('entity.filter.all')
                  : sf === 'generated' ? t('image.status.generated')
                  : sf === 'approved' ? t('image.status.approved')
                  : t('image.status.needs_fix')}
              </button>
            ))}
          </div>
          {needsFixCount > 0 && (
            <Button
              variant="warning"
              size="sm"
              disabled={regenerating}
              onClick={handleRegenerateNeedsFix}
            >
              {t('image.regenerate_all_fix')} ({needsFixCount})
            </Button>
          )}
        </div>

        {/* Image grid */}
        {loading ? (
          <div className="empty-state">{t('common.loading')}</div>
        ) : filteredImages.length === 0 ? (
          <div className="empty-state">{t('common.no_data')}</div>
        ) : (
          <div style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))',
            gap: '16px',
          }}>
            {filteredImages.map(img => (
              <div
                key={img.id}
                className="card"
                style={{
                  padding: '0',
                  overflow: 'hidden',
                  cursor: 'pointer',
                  border: img.is_primary ? '2px solid var(--green)' : undefined,
                }}
                onClick={() => openReview(img)}
              >
                <div style={{
                  width: '100%',
                  height: '160px',
                  background: 'var(--bg-input)',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  overflow: 'hidden',
                  position: 'relative',
                }}>
                  <img
                    src={`/api/v1/projects/${id}/images/${img.id}/file?thumb=1`}
                    alt={img.id}
                    style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                    onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
                  />
                  {/* Primary badge */}
                  {img.is_primary && (
                    <div style={{
                      position: 'absolute',
                      top: '6px',
                      left: '6px',
                      background: 'var(--green)',
                      color: '#fff',
                      fontSize: '10px',
                      fontWeight: 700,
                      padding: '2px 8px',
                      borderRadius: '999px',
                    }}>
                      {t('image.is_primary')}
                    </div>
                  )}
                </div>
                <div style={{ padding: '12px 14px' }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '6px' }}>
                    <div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
                      <span style={{ fontSize: '12px', fontWeight: 600, fontFamily: 'var(--font-mono)', color: 'var(--text-muted)' }}>
                        {img.asset_type === 'reference' ? t('image.type.reference') : t('image.type.scene')}
                      </span>
                      {img.still_id && (
                        <span style={{
                          fontSize: '10px', fontWeight: 600, padding: '1px 6px',
                          borderRadius: '999px', background: 'var(--accent)', color: '#fff',
                        }}>
                          씬 {img.still_id.substring(0, 6)}
                        </span>
                      )}
                    </div>
                    <div style={{ display: 'flex', gap: '4px', alignItems: 'center' }}>
                      <Badge
                        label={strategyLabel(img.sanitization_strategy, t)}
                        variant={img.sanitization_strategy ? 'orange' : 'green'}
                      />
                      <Badge
                        label={
                          img.status === 'approved' ? t('image.status.approved')
                            : img.status === 'needs_fix' ? t('image.status.needs_fix')
                            : img.status === 'regenerating' ? t('image.status.regenerating')
                            : t('image.status.generated')
                        }
                        variant={statusVariant(img.status)}
                      />
                    </div>
                  </div>
                  {img.review_notes && (
                    <div style={{ fontSize: '12px', color: 'var(--text-dim)', marginTop: '4px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {img.review_notes}
                    </div>
                  )}
                </div>
              </div>
            ))}
          </div>
        )}

        {/* Review modal */}
        {selectedImage && (
          <Modal
            open={!!selectedImage}
            title={t('image.review')}
            onClose={() => setSelectedImage(null)}
          >
            <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
              <div
                style={{ textAlign: 'center', cursor: 'pointer' }}
                onClick={() => setZoomOpen(true)}
              >
                <img
                  src={`/api/v1/projects/${id}/images/${selectedImage.id}/file?thumb=1`}
                  alt={selectedImage.id}
                  style={{ maxWidth: '100%', maxHeight: '300px', borderRadius: 'var(--radius-sm)' }}
                />
                <div style={{ fontSize: '11px', color: 'var(--text-dim)', marginTop: '4px' }}>{t('image.zoom')}</div>
              </div>

              {/* Primary badge / set primary button */}
              <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
                {selectedImage.is_primary ? (
                  <span style={{
                    padding: '3px 10px',
                    background: 'var(--green)',
                    color: '#fff',
                    borderRadius: '999px',
                    fontSize: '12px',
                    fontWeight: 600,
                  }}>
                    {t('image.is_primary')}
                  </span>
                ) : (
                  <Button
                    size="sm"
                    variant="secondary"
                    onClick={() => handleSetPrimary(selectedImage.id)}
                  >
                    {t('image.set_primary')}
                  </Button>
                )}
              </div>

              {/* Sanitization strategy badge */}
              <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
                <span style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text-muted)' }}>
                  {t('image.strategy.label')}:
                </span>
                <Badge
                  label={strategyLabel(selectedImage.sanitization_strategy, t)}
                  variant={selectedImage.sanitization_strategy ? 'orange' : 'green'}
                />
              </div>

              {/* Sanitization note (collapsible) */}
              {selectedImage.sanitization_note && (
                <div>
                  <button
                    onClick={() => setNoteOpen(!noteOpen)}
                    style={{
                      background: 'none',
                      border: 'none',
                      padding: 0,
                      cursor: 'pointer',
                      fontSize: '12px',
                      fontWeight: 600,
                      color: 'var(--accent)',
                      display: 'flex',
                      alignItems: 'center',
                      gap: '4px',
                    }}
                  >
                    {noteOpen ? '\u25BC' : '\u25B6'} {t('image.sanitization_note')}
                  </button>
                  {noteOpen && (
                    <div style={{
                      marginTop: '6px',
                      fontSize: '12px',
                      color: 'var(--text-muted)',
                      lineHeight: 1.5,
                      background: 'var(--bg-raised)',
                      borderRadius: 'var(--radius-sm)',
                      padding: '8px 12px',
                    }}>
                      {selectedImage.sanitization_note}
                    </div>
                  )}
                </div>
              )}

              <div>
                <label style={{ fontSize: '13px', fontWeight: 600, display: 'block', marginBottom: '6px' }}>
                  {t('image.review')}
                </label>
                <select
                  className="input"
                  value={reviewStatus}
                  onChange={e => setReviewStatus(e.target.value)}
                >
                  <option value="approved">{t('image.approve')}</option>
                  <option value="needs_fix">{t('image.needs_fix')}</option>
                </select>
              </div>

              <div>
                <label style={{ fontSize: '13px', fontWeight: 600, display: 'block', marginBottom: '6px' }}>
                  {t('image.notes')}
                </label>
                <textarea
                  className="input"
                  rows={3}
                  value={reviewNotes}
                  onChange={e => setReviewNotes(e.target.value)}
                  style={{ resize: 'vertical' }}
                />
              </div>

              <Button
                disabled={saving}
                onClick={() => handleReviewSave(selectedImage.id)}
              >
                {t('btn.save')}
              </Button>
            </div>
          </Modal>
        )}

        {/* Zoom modal */}
        {selectedImage && (
          <Modal
            open={zoomOpen}
            title={t('image.zoom')}
            onClose={() => setZoomOpen(false)}
          >
            <div style={{ textAlign: 'center' }}>
              <img
                src={`/api/v1/projects/${id}/images/${selectedImage.id}/file`}
                alt={selectedImage.id}
                style={{ maxWidth: '100%', maxHeight: '80vh' }}
              />
            </div>
          </Modal>
        )}
      </div>
    </AppShell>
  )
}
