'use client'

import { useEffect, useRef, useState, useCallback } from 'react'
import type { Game } from '@/types'
import TagSelector from '@/components/tags/TagSelector'

interface Props {
  game: Game
  libraryId: string
  onClose: () => void
  onTagsChanged?: () => void
  onCoverUploaded?: () => void
}

export default function GameDetailModal({ game, libraryId, onClose, onTagsChanged, onCoverUploaded }: Props) {
  const overlayRef = useRef<HTMLDivElement>(null)
  const menuRef = useRef<HTMLDivElement>(null)
  const [menuOpen, setMenuOpen] = useState(false)
  const [editingImages, setEditingImages] = useState(false)

  useEffect(() => {
    const handleKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        if (menuOpen) { setMenuOpen(false); return }
        if (editingImages) { setEditingImages(false); return }
        onClose()
      }
    }
    document.addEventListener('keydown', handleKey)
    document.body.style.overflow = 'hidden'
    return () => {
      document.removeEventListener('keydown', handleKey)
      document.body.style.overflow = ''
    }
  }, [onClose, menuOpen, editingImages])

  // Close menu on outside click
  useEffect(() => {
    if (!menuOpen) return
    const handler = (e: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        setMenuOpen(false)
      }
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [menuOpen])

  const handleOverlayClick = (e: React.MouseEvent) => {
    if (e.target === overlayRef.current) onClose()
  }

  const zipDownloadUrl = (zipPath: string) =>
    `/api/file?libraryId=${encodeURIComponent(libraryId)}&path=${encodeURIComponent(zipPath)}`
  const heroImage = game.wideCoverUrl ?? game.coverUrl

  return (
    <div
      ref={overlayRef}
      className="fixed inset-0 z-50 flex items-center justify-center p-4"
      style={{ backgroundColor: 'rgba(0,0,0,0.75)' }}
      onClick={handleOverlayClick}
    >
      <div
        className="relative w-full max-w-lg rounded-2xl overflow-hidden shadow-2xl"
        style={{ backgroundColor: 'var(--surface)', border: '1px solid var(--border)' }}
      >
        {editingImages ? (
          <ImageEditor
            game={game}
            libraryId={libraryId}
            onBack={() => setEditingImages(false)}
            onUploaded={onCoverUploaded}
          />
        ) : (
          <>
            {/* Close button */}
            <button
              onClick={onClose}
              className="absolute top-3 right-3 z-10 w-8 h-8 rounded-full flex items-center justify-center text-sm transition-colors"
              style={{ backgroundColor: 'rgba(0,0,0,0.5)', color: 'var(--text-primary)' }}
              onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(0,0,0,0.8)')}
              onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(0,0,0,0.5)')}
              aria-label="Close"
            >
              ✕
            </button>

            {/* Hero image */}
            <div className="w-full" style={{ backgroundColor: 'var(--border)' }}>
              {heroImage ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img src={heroImage} alt={`${game.title} cover`} className="w-full object-cover max-h-64" />
              ) : (
                <div className="h-40 flex items-center justify-center text-5xl">🎮</div>
              )}
            </div>

            {/* Info */}
            <div className="p-5">
              {/* Title row with kebab menu */}
              <div className="flex items-center gap-2 mb-4">
                <h2 className="text-lg font-semibold flex-1 min-w-0" style={{ color: 'var(--text-primary)' }}>
                  {game.title}
                </h2>

                {/* Kebab menu */}
                <div className="relative flex-shrink-0" ref={menuRef}>
                  <button
                    onClick={() => setMenuOpen((o) => !o)}
                    className="w-7 h-7 rounded-lg flex items-center justify-center transition-colors"
                    style={{ color: 'var(--text-secondary)', backgroundColor: 'transparent' }}
                    onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--border)')}
                    onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'transparent')}
                    aria-label="More options"
                  >
                    ⋮
                  </button>
                  {menuOpen && (
                    <div
                      className="absolute right-0 top-full mt-1 rounded-lg shadow-lg overflow-hidden z-20 min-w-max"
                      style={{ backgroundColor: 'var(--surface)', border: '1px solid var(--border)' }}
                    >
                      <button
                        onClick={() => { setMenuOpen(false); setEditingImages(true) }}
                        className="flex items-center gap-2 w-full px-4 py-2 text-sm text-left transition-colors"
                        style={{ color: 'var(--text-primary)' }}
                        onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--border)')}
                        onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'transparent')}
                      >
                        Edit images
                      </button>
                    </div>
                  )}
                </div>
              </div>

              <DownloadButton zipFiles={game.zipFiles} downloadUrl={zipDownloadUrl} />

              {/* Tags */}
              <div className="mt-4 pt-4" style={{ borderTop: '1px solid var(--border)' }}>
                <p className="text-xs font-semibold uppercase tracking-wider mb-2" style={{ color: 'var(--text-secondary)' }}>
                  Tags
                </p>
                <TagSelector itemKey={game.item_key!} onTagsChanged={onTagsChanged} />
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  )
}

// ─── Download Button ──────────────────────────────────────────────────────────

function DownloadButton({
  zipFiles,
  downloadUrl,
}: {
  zipFiles: string[]
  downloadUrl: (zipPath: string) => string
}) {
  const [open, setOpen] = useState(false)
  const ref = useRef<HTMLDivElement>(null)

  const close = useCallback(() => setOpen(false), [])

  useEffect(() => {
    if (!open) return
    const handler = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) close()
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [open, close])

  const primary = zipFiles[0]
  const primaryName = primary.split('/').pop() ?? primary

  if (zipFiles.length === 1) {
    return (
      <a
        href={downloadUrl(primary)}
        download
        className="flex items-center justify-center gap-2 w-full px-4 py-2.5 rounded-lg font-medium text-sm transition-colors"
        style={{ backgroundColor: 'var(--accent)', color: '#fff' }}
        onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--accent-hover)')}
        onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--accent)')}
      >
        <span>↓</span>
        Download .zip
      </a>
    )
  }

  return (
    <div className="relative" ref={ref}>
      <div className="flex rounded-lg overflow-hidden" style={{ backgroundColor: 'var(--accent)' }}>
        {/* Primary download */}
        <a
          href={downloadUrl(primary)}
          download
          className="flex items-center justify-center gap-2 flex-1 px-4 py-2.5 font-medium text-sm transition-colors"
          style={{ color: '#fff' }}
          onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(255,255,255,0.1)')}
          onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'transparent')}
        >
          <span>↓</span>
          {primaryName}
        </a>

        {/* Divider */}
        <div style={{ width: '1px', backgroundColor: 'rgba(255,255,255,0.25)' }} />

        {/* Dropdown toggle */}
        <button
          onClick={() => setOpen((o) => !o)}
          className="px-3 flex items-center justify-center text-sm transition-colors"
          style={{ color: '#fff' }}
          onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(255,255,255,0.1)')}
          onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'transparent')}
          aria-label="Show all downloads"
        >
          ▾
        </button>
      </div>

      {open && (
        <div
          className="absolute left-0 right-0 top-full mt-1 rounded-lg shadow-lg overflow-hidden z-20"
          style={{ backgroundColor: 'var(--surface)', border: '1px solid var(--border)' }}
        >
          {zipFiles.map((zipPath) => {
            const name = zipPath.split('/').pop() ?? zipPath
            return (
              <a
                key={zipPath}
                href={downloadUrl(zipPath)}
                download
                onClick={close}
                className="flex items-center gap-2 px-4 py-2 text-sm transition-colors"
                style={{ color: 'var(--text-primary)' }}
                onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--border)')}
                onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'transparent')}
              >
                <span style={{ color: 'var(--text-secondary)' }}>↓</span>
                {name}
              </a>
            )
          })}
        </div>
      )}
    </div>
  )
}

// ─── Image Editor ─────────────────────────────────────────────────────────────

interface ImageEditorProps {
  game: Game
  libraryId: string
  onBack: () => void
  onUploaded?: () => void
}

function ImageEditor({ game, libraryId, onBack, onUploaded }: ImageEditorProps) {
  return (
    <div className="p-5">
      {/* Header */}
      <div className="flex items-center gap-3 mb-6">
        <button
          onClick={onBack}
          className="w-7 h-7 rounded-lg flex items-center justify-center transition-colors flex-shrink-0"
          style={{ color: 'var(--text-secondary)', backgroundColor: 'transparent' }}
          onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--border)')}
          onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'transparent')}
          aria-label="Back"
        >
          ←
        </button>
        <h2 className="text-base font-semibold" style={{ color: 'var(--text-primary)' }}>
          Edit Images
        </h2>
      </div>

      <div className="flex flex-col gap-6">
        <ImageSlot
          label="Cover"
          description="Portrait artwork (3:4)"
          currentUrl={game.coverUrl}
          fallback="🎮"
          aspectClass="aspect-[3/4]"
          libraryId={libraryId}
          itemId={game.id}
          coverType="cover"
          onUploaded={onUploaded}
        />
        <ImageSlot
          label="Wide Cover"
          description="Landscape hero image"
          currentUrl={game.wideCoverUrl}
          fallback="🎮"
          aspectClass="aspect-video"
          libraryId={libraryId}
          itemId={game.id}
          coverType="widecover"
          onUploaded={onUploaded}
        />
      </div>
    </div>
  )
}

// ─── Image Slot ───────────────────────────────────────────────────────────────

interface ImageSlotProps {
  label: string
  description: string
  currentUrl: string | null
  fallback: string
  aspectClass: string
  libraryId: string
  itemId: string
  coverType: 'cover' | 'widecover'
  onUploaded?: () => void
}

function ImageSlot({
  label, description, currentUrl, fallback, aspectClass,
  libraryId, itemId, coverType, onUploaded,
}: ImageSlotProps) {
  const inputRef = useRef<HTMLInputElement>(null)
  const [preview, setPreview] = useState<string | null>(null)
  const [uploading, setUploading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const displayUrl = preview ?? currentUrl

  const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return

    // Show local preview immediately
    const objectUrl = URL.createObjectURL(file)
    setPreview(objectUrl)
    setError(null)
    setUploading(true)

    const form = new FormData()
    form.append('cover', file)

    try {
      const res = await fetch(
        `/api/game-cover?libraryId=${encodeURIComponent(libraryId)}&itemId=${encodeURIComponent(itemId)}&coverType=${coverType}`,
        { method: 'POST', body: form }
      )
      if (!res.ok) {
        const data = await res.json().catch(() => ({}))
        setError(data.error ?? 'Upload failed.')
        setPreview(null)
      } else {
        onUploaded?.()
      }
    } catch {
      setError('Network error.')
      setPreview(null)
    } finally {
      setUploading(false)
      e.target.value = ''
    }
  }

  return (
    <div>
      <div className="flex items-baseline justify-between mb-2">
        <p className="text-sm font-medium" style={{ color: 'var(--text-primary)' }}>{label}</p>
        <p className="text-xs" style={{ color: 'var(--text-secondary)' }}>{description}</p>
      </div>

      <div className="flex items-start gap-4">
        {/* Preview */}
        <div
          className={`${aspectClass} rounded-lg overflow-hidden flex-shrink-0 relative`}
          style={{
            width: coverType === 'cover' ? '80px' : '160px',
            backgroundColor: 'var(--border)',
            border: '1px solid var(--border)',
          }}
        >
          {displayUrl ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={displayUrl} alt={label} className="w-full h-full object-cover" />
          ) : (
            <div className="w-full h-full flex items-center justify-center text-2xl">{fallback}</div>
          )}
          {uploading && (
            <div className="absolute inset-0 flex items-center justify-center" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
              <span className="text-xs text-white">Saving…</span>
            </div>
          )}
        </div>

        {/* Controls */}
        <div className="flex flex-col gap-2 flex-1 min-w-0">
          <button
            onClick={() => inputRef.current?.click()}
            disabled={uploading}
            className="px-3 py-1.5 rounded-lg text-sm font-medium transition-colors disabled:opacity-50 text-left"
            style={{ backgroundColor: 'var(--border)', color: 'var(--text-primary)' }}
            onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--accent)')}
            onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--border)')}
          >
            {currentUrl || preview ? 'Replace image' : 'Upload image'}
          </button>
          {error && (
            <p className="text-xs" style={{ color: '#fca5a5' }}>{error}</p>
          )}
        </div>
      </div>

      <input
        ref={inputRef}
        type="file"
        accept="image/jpeg,image/png,image/webp,image/gif"
        className="hidden"
        onChange={handleChange}
      />
    </div>
  )
}
