import { useState, useEffect } from 'react'
import { Modal } from '../ui/Modal'
import { Button } from '../ui/Button'
import { AngleEditor } from './AngleEditor'
import { useI18n } from '../../i18n/useI18n'

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
  status: string
  is_primary: boolean
  prompt_type: string | null
  created_at: string
  variant_type?: string | null
  is_recommended?: boolean
  recommendation_reason?: string | null
  angle_horizontal?: number | null
  angle_vertical?: number | null
  angle_zoom?: number | null
  color_prompt?: string | null
  selected_for_pdf?: boolean
  parent_image_id?: string | null
  theme_label?: string | null
  generation_model?: string | null
  source_image_id?: string | null
}

interface ResolvedEntity {
  entity_id: string
  entity_name: string
  entity_type: string
  t2i_prompt: string
  has_reference_image: boolean
  reference_image_id: string | null
}

interface T2iVariation {
  variant_label: string
  camera_effect: string
  t2i_prompt: string
}

interface ImageGalleryModalProps {
  open: boolean
  image: ImageAsset
  projectId: string
  allImages: ImageAsset[]  // all images for this scene, for parent tracking
  resolvedEntities?: ResolvedEntity[]
  t2iVariations?: T2iVariation[]  // scene-level t2i_variations with [[markers]]
  onClose: () => void
  onApplyAngleColor: (imageId: string, h: number, v: number, z: number, colorPrompt: string) => void
  onSetRepresentative: (imageId: string) => void
  onRegenerateWithPrompt?: (stillId: string, customPrompt: string) => void
  loading?: boolean
}

export function ImageGalleryModal({
  open,
  image,
  projectId,
  allImages,
  resolvedEntities = [],
  t2iVariations = [],
  onClose,
  onApplyAngleColor,
  onSetRepresentative,
  onRegenerateWithPrompt,
  loading = false,
}: ImageGalleryModalProps) {
  const { t } = useI18n()

  const [angleH, setAngleH] = useState(image.angle_horizontal ?? 0)
  const [angleV, setAngleV] = useState(image.angle_vertical ?? 0)
  const [angleZ, setAngleZ] = useState(image.angle_zoom ?? 1.0)
  // editPrompt: prompt_used (최종 Gemini 프롬프트) for editing/regeneration
  const [editPrompt, setEditPrompt] = useState(image.prompt_used ?? '')
  const [isEditingPrompt, setIsEditingPrompt] = useState(false)

  // Reset state when image changes
  useEffect(() => {
    setAngleH(image.angle_horizontal ?? 0)
    setAngleV(image.angle_vertical ?? 0)
    setAngleZ(image.angle_zoom ?? 1.0)
    setEditPrompt(image.prompt_used ?? '')
    setIsEditingPrompt(false)
  }, [image.id])

  const isFalAngle = image.variant_type === 'angle_fal'

  // Find parent/source image
  const sourceImage = image.source_image_id
    ? allImages.find(img => img.id === image.source_image_id)
    : null
  const parentImage = image.parent_image_id
    ? allImages.find(img => img.id === image.parent_image_id)
    : null

  const handleApply = () => {
    onApplyAngleColor(image.id, angleH, angleV, angleZ, '')
  }

  const handleRegenerate = () => {
    if (onRegenerateWithPrompt && image.still_id && editPrompt.trim()) {
      onRegenerateWithPrompt(image.still_id, editPrompt.trim())
      onClose()
    }
  }

  // Parse [[entity]] and [location: desc] markers from a prompt
  const parseMarkers = (prompt: string | null) => {
    if (!prompt) return { entities: [] as string[], locations: [] as Array<{ name: string; desc: string }> }
    const entities: string[] = []
    const locations: Array<{ name: string; desc: string }> = []
    // [[character]+[outlook]] or [[prop]]
    const linkedRe = /\[\[((?:[^\]]|\](?!\]))+)\]\]/g
    let m: RegExpExecArray | null
    while ((m = linkedRe.exec(prompt)) !== null) {
      if (!entities.includes(m[1])) entities.push(m[1])
    }
    // [location: description] — single bracket, not inside [[]]
    const locRe = /(?<!\[)\[([^\[\]]+?)\s*:\s*([^\]]+)\](?!\])/g
    let m2: RegExpExecArray | null
    while ((m2 = locRe.exec(prompt)) !== null) {
      if (!locations.find(l => l.name === m2![1].trim())) {
        locations.push({ name: m2[1].trim(), desc: m2[2].trim() })
      }
    }
    return { entities, locations }
  }

  // Find the original T2I prompt (with [[markers]]) for this image by matching variant_type
  const findOriginalT2i = (): string | null => {
    if (isFalAngle) return null
    const vt = image.variant_type || ''
    // variant_type = "var_1", "var_2" etc — match against t2iVariations[].variant_label
    const matched = t2iVariations.find(v => v.variant_label === vt)
    if (matched) return matched.t2i_prompt
    // Fallback: theme_label match against camera_effect
    if (image.theme_label) {
      const byTheme = t2iVariations.find(v => v.camera_effect === image.theme_label)
      if (byTheme) return byTheme.t2i_prompt
    }
    // Fallback: first variation
    if (t2iVariations.length > 0) return t2iVariations[0].t2i_prompt
    return null
  }

  const originalT2i = findOriginalT2i()
  const { entities: imageMarkers, locations: imageLocations } = parseMarkers(originalT2i || image.prompt_used)

  // Parse fal.ai angle from prompt_used (format: "[fal.ai angle] H=45 V=20 Z=5")
  const parseFalAngle = (prompt: string | null) => {
    if (!prompt) return null
    const match = prompt.match(/H=([-\d.]+)\s*V=([-\d.]+)\s*Z=([-\d.]+)/)
    if (!match) return null
    return { h: parseFloat(match[1]), v: parseFloat(match[2]), z: parseFloat(match[3]) }
  }

  const falAngle = isFalAngle ? parseFalAngle(image.prompt_used) : null

  return (
    <Modal open={open} title={t('gallery.modal_title')} onClose={onClose} size="large">
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '24px', minHeight: '400px' }}>
        {/* Left: Large image preview */}
        <div>
          <div style={{
            borderRadius: 'var(--radius-sm)',
            overflow: 'hidden',
            border: '1px solid var(--border)',
            marginBottom: '12px',
          }}>
            <img
              src={`/api/v1/projects/${projectId}/images/${image.id}/file`}
              alt={image.id}
              style={{ width: '100%', height: 'auto', display: 'block', maxHeight: '60vh', objectFit: 'contain' }}
            />
          </div>

          {/* Image metadata */}
          <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap', marginBottom: '8px' }}>
            {image.theme_label && (
              <span style={{
                fontSize: '11px', padding: '2px 8px',
                background: 'var(--accent-glow)', color: 'var(--accent)',
                borderRadius: '999px', fontWeight: 600,
              }}>
                {image.theme_label}
              </span>
            )}
            {isFalAngle && (
              <span style={{
                fontSize: '11px', padding: '2px 8px',
                background: 'var(--warning-bg, #3a3000)', color: 'var(--warning, #ffa500)',
                borderRadius: '999px', fontWeight: 600,
              }}>
                fal.ai angle
              </span>
            )}
            {image.is_primary && (
              <span style={{
                fontSize: '11px', padding: '2px 8px',
                background: 'var(--green-bg)', color: 'var(--green)',
                borderRadius: '999px', fontWeight: 600,
              }}>
                {t('gallery.representative')}
              </span>
            )}
            {image.selected_for_pdf && (
              <span style={{
                fontSize: '11px', padding: '2px 8px',
                background: 'var(--green-bg)', color: 'var(--green)',
                borderRadius: '999px', fontWeight: 600,
              }}>
                {t('variation.selected_for_pdf')}
              </span>
            )}
          </div>

          {/* Set as representative button */}
          {!image.is_primary && (
            <Button
              size="sm"
              variant="secondary"
              onClick={() => onSetRepresentative(image.id)}
              style={{ marginTop: '4px', marginBottom: '8px' }}
            >
              {t('gallery.set_representative')}
            </Button>
          )}
        </div>

        {/* Right: Prompt/Angle info + editing */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>

          {isFalAngle ? (
            /* ── fal.ai angle image: show source + angle info ── */
            <>
              <div>
                <span style={{
                  fontSize: '11px', fontWeight: 700, color: 'var(--text-dim)',
                  textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '8px', display: 'block',
                }}>
                  fal.ai Angle Edit
                </span>

                {/* Source image thumbnail */}
                {sourceImage && (
                  <div style={{ marginBottom: '10px' }}>
                    <div style={{ fontSize: '11px', color: 'var(--text-muted)', marginBottom: '4px' }}>
                      원본 이미지: {sourceImage.theme_label || sourceImage.variant_type || sourceImage.id.slice(0, 8)}
                    </div>
                    <img
                      src={`/api/v1/projects/${projectId}/images/${sourceImage.id}/file?thumb=1`}
                      alt="source"
                      style={{
                        width: '120px', height: '120px', objectFit: 'cover',
                        borderRadius: 'var(--radius-sm)', border: '1px solid var(--border)',
                      }}
                    />
                  </div>
                )}

                {/* Angle parameters */}
                {falAngle && (
                  <div style={{
                    background: 'var(--bg-input)', padding: '10px 12px',
                    borderRadius: 'var(--radius-sm)', fontSize: '12px', lineHeight: 1.8,
                  }}>
                    <div><strong>Horizontal:</strong> {falAngle.h}°</div>
                    <div><strong>Vertical:</strong> {falAngle.v}°</div>
                    <div><strong>Zoom:</strong> {falAngle.z}</div>
                  </div>
                )}
              </div>

              {/* Close button for fal.ai view */}
              <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '12px' }}>
                <Button size="sm" variant="ghost" onClick={onClose}>
                  {t('btn.cancel')}
                </Button>
              </div>
            </>
          ) : (
            /* ── T2I image: reference entities + editable prompt + regenerate ── */
            <>
              {/* Referenced entities + locations for THIS image */}
              {(imageMarkers.length > 0 || imageLocations.length > 0) && (
                <div>
                  <span style={{
                    fontSize: '11px', fontWeight: 700, color: 'var(--text-dim)',
                    textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '6px', display: 'block',
                  }}>
                    참조 요소
                  </span>
                  <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
                    {imageMarkers.map(marker => {
                      const isComposite = marker.includes(']+[')
                      let charName = marker
                      let outlookName = ''
                      let refImageId: string | null = null

                      if (isComposite) {
                        const parts = marker.split(']+[')
                        charName = parts[0].trim()
                        outlookName = parts[1].trim()
                        const outlookEnt = resolvedEntities.find(e => e.entity_name === outlookName && e.entity_type === 'outlook')
                        const charEnt = resolvedEntities.find(e => e.entity_name === charName && e.entity_type === 'character')
                        refImageId = outlookEnt?.reference_image_id || charEnt?.reference_image_id || null
                      } else {
                        const ent = resolvedEntities.find(e => e.entity_name === marker)
                        refImageId = ent?.reference_image_id || null
                      }

                      const label = isComposite ? `[[${charName}]+[${outlookName}]]` : `[[${marker}]]`

                      return (
                        <div key={marker} style={{
                          display: 'flex', alignItems: 'center', gap: '4px',
                          padding: '3px 8px', background: 'var(--bg-input)',
                          borderRadius: 'var(--radius-sm)',
                          border: `1px solid ${isComposite ? 'var(--pink, #ec4899)' : 'var(--green)'}`,
                          fontSize: '11px',
                        }}>
                          {refImageId ? (
                            <img
                              src={`/api/v1/projects/${projectId}/images/${refImageId}/file?thumb=1`}
                              alt={charName}
                              style={{ width: '22px', height: '22px', borderRadius: '3px', objectFit: 'cover' }}
                              onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
                            />
                          ) : (
                            <span style={{
                              width: '22px', height: '22px', borderRadius: '3px',
                              background: 'var(--bg-raised)', display: 'flex',
                              alignItems: 'center', justifyContent: 'center',
                              fontSize: '9px', color: 'var(--text-dim)',
                            }}>?</span>
                          )}
                          <span style={{ color: 'var(--green)' }}>{label}</span>
                        </div>
                      )
                    })}

                    {/* Location markers — different color, no ref image */}
                    {imageLocations.map(loc => (
                      <div key={`loc-${loc.name}`} style={{
                        display: 'flex', alignItems: 'center', gap: '4px',
                        padding: '3px 8px', background: 'var(--bg-input)',
                        borderRadius: 'var(--radius-sm)',
                        border: '1px dashed var(--warning, #d97706)',
                        fontSize: '11px',
                      }} title={loc.desc}>
                        <span style={{
                          width: '22px', height: '22px', borderRadius: '3px',
                          background: 'var(--warning-bg, #3a3000)', display: 'flex',
                          alignItems: 'center', justifyContent: 'center',
                          fontSize: '9px', color: 'var(--warning, #d97706)',
                        }}>&#x1F3D7;</span>
                        <span style={{ color: 'var(--warning, #d97706)' }}>[{loc.name}]</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Original T2I prompt (with markers) — read only */}
              {originalT2i && (
                <div>
                  <span style={{
                    fontSize: '11px', fontWeight: 700, color: 'var(--accent)',
                    textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '4px', display: 'block',
                  }}>
                    원본 T2I (마커 포함)
                  </span>
                  <div style={{
                    fontSize: '11px', color: 'var(--text)', lineHeight: 1.5,
                    background: 'var(--bg-raised)', padding: '8px 10px',
                    borderRadius: 'var(--radius-sm)', maxHeight: '100px', overflowY: 'auto',
                    border: '1px solid var(--border)', fontFamily: 'var(--font-mono)',
                  }}>
                    {originalT2i}
                  </div>
                </div>
              )}

              {/* Final Gemini Prompt (editable for regeneration) */}
              <div>
                <div style={{
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                  marginBottom: '6px',
                }}>
                  <span style={{
                    fontSize: '11px', fontWeight: 700, color: 'var(--text-dim)',
                    textTransform: 'uppercase', letterSpacing: '0.04em',
                  }}>
                    최종 생성 프롬프트
                  </span>
                  {!isEditingPrompt && (
                    <button
                      onClick={() => setIsEditingPrompt(true)}
                      style={{
                        fontSize: '11px', color: 'var(--accent)', background: 'none',
                        border: 'none', cursor: 'pointer', padding: '2px 6px',
                      }}
                    >
                      편집
                    </button>
                  )}
                </div>

                {isEditingPrompt ? (
                  <div>
                    <textarea
                      className="input"
                      rows={8}
                      value={editPrompt}
                      onChange={(e) => setEditPrompt(e.target.value)}
                      style={{ resize: 'vertical', width: '100%', fontSize: '11px', lineHeight: 1.5 }}
                    />
                    <div style={{ display: 'flex', gap: '6px', marginTop: '6px', justifyContent: 'flex-end' }}>
                      <Button size="sm" variant="ghost" onClick={() => {
                        setEditPrompt(image.prompt_used ?? '')
                        setIsEditingPrompt(false)
                      }}>
                        취소
                      </Button>
                      <Button
                        size="sm"
                        onClick={handleRegenerate}
                        disabled={loading || !editPrompt.trim()}
                      >
                        {loading ? '생성 중...' : '이 프롬프트로 재생성'}
                      </Button>
                    </div>
                  </div>
                ) : (
                  <div
                    onClick={() => setIsEditingPrompt(true)}
                    style={{
                      fontSize: '11px', color: 'var(--text-muted)', lineHeight: 1.5,
                      background: 'var(--bg-input)', padding: '8px 10px',
                      borderRadius: 'var(--radius-sm)', maxHeight: '160px', overflowY: 'auto',
                      cursor: 'pointer',
                    }}
                    title="클릭하여 편집"
                  >
                    {image.prompt_used || '(프롬프트 없음)'}
                  </div>
                )}
              </div>

              {/* Parent info */}
              {parentImage && (
                <div style={{ fontSize: '11px', color: 'var(--text-dim)' }}>
                  파생 원본: {parentImage.theme_label || parentImage.id.slice(0, 8)}
                </div>
              )}

              {/* Angle editor → fal.ai */}
              <div>
                <span style={{
                  fontSize: '11px', fontWeight: 700, color: 'var(--text-dim)',
                  textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '8px', display: 'block',
                }}>
                  앵글 편집 (fal.ai)
                </span>
                <AngleEditor
                  horizontal={angleH}
                  vertical={angleV}
                  zoom={angleZ}
                  onChange={(h, v, z) => { setAngleH(h); setAngleV(v); setAngleZ(z) }}
                />
              </div>

              {/* Apply angle button */}
              <div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>
                <Button size="sm" variant="ghost" onClick={onClose}>
                  {t('btn.cancel')}
                </Button>
                <Button size="sm" onClick={handleApply} disabled={loading}>
                  {loading ? t('gallery.generating') : '앵글 적용'}
                </Button>
              </div>
            </>
          )}
        </div>
      </div>
    </Modal>
  )
}
