/**
 * Copy to Private Gallery Modal
 *
 * Used from Downloads, Media, Review, and Paid Content pages
 * to copy files to the private gallery
 */

import { useState, useRef, useEffect } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  X,
  Copy,
  Calendar,
  FileText,
  Loader2,
  Lock,
  Video,
} from 'lucide-react'
import { api } from '../../lib/api'
import PersonSelector from './PersonSelector'
import TagSearchSelector from './TagSearchSelector'
import ThrottledImage from '../ThrottledImage'
import ThumbnailProgressModal, { ThumbnailProgressItem } from '../ThumbnailProgressModal'

interface CopyToGalleryModalProps {
  open: boolean
  onClose: () => void
  sourcePaths: string[]
  sourceType: 'downloads' | 'media' | 'review' | 'recycle' | 'paid_content'
  onSuccess?: () => void
  sourceNames?: Record<string, string>  // source_path -> display name
}

export function CopyToGalleryModal({
  open,
  onClose,
  sourcePaths,
  sourceType,
  onSuccess,
  sourceNames,
}: CopyToGalleryModalProps) {
  const queryClient = useQueryClient()

  const [personId, setPersonId] = useState<number | undefined>()
  const [selectedTags, setSelectedTags] = useState<number[]>([])
  const [tagsManuallyModified, setTagsManuallyModified] = useState(false)
  const [mediaDate, setMediaDate] = useState('')
  const [description, setDescription] = useState('')
  const [jobId, setJobId] = useState<string | null>(null)
  const [progressItems, setProgressItems] = useState<ThumbnailProgressItem[]>([])
  const [showProgress, setShowProgress] = useState(false)
  const isSubmitting = useRef(false)

  // Check gallery status
  const { data: galleryStatus, isLoading: isLoadingStatus } = useQuery({
    queryKey: ['private-gallery-status'],
    queryFn: () => api.privateGallery.getStatus(),
    enabled: open,
  })

  const { data: tags = [] } = useQuery({
    queryKey: ['private-gallery-tags'],
    queryFn: () => api.privateGallery.getTags(),
    enabled: open && galleryStatus?.is_unlocked,
  })

  const copyMutation = useMutation({
    mutationFn: (data: {
      source_paths: string[]
      person_id: number
      tag_ids: number[]
      media_date?: string
      description?: string
      original_filenames?: Record<string, string>
    }) => api.privateGallery.copy(data),
    onSuccess: (result) => {
      setJobId(result.job_id)
    },
  })

  // Poll job status
  useEffect(() => {
    if (!jobId) return

    const pollInterval = setInterval(async () => {
      try {
        const status = await api.privateGallery.getJobStatus(jobId)

        setProgressItems(prev => prev.map(item => {
          const result = status.results.find(r => {
            const resultFilename = r.filename || (r.path ? r.path.split('/').pop() : '')
            return resultFilename === item.filename || r.path === item.id
          })
          if (result) {
            return {
              ...item,
              status: result.status === 'created' ? 'success'
                : result.status === 'duplicate' ? 'duplicate'
                : result.status === 'failed' ? 'error'
                : item.status,
              error: result.error
            }
          }
          if (status.current_file === item.filename) {
            return { ...item, status: 'processing' }
          }
          return item
        }))

        if (status.status === 'completed') {
          clearInterval(pollInterval)
          setJobId(null)

          queryClient.invalidateQueries({ queryKey: ['private-gallery-media'] })
          queryClient.invalidateQueries({ queryKey: ['private-gallery-posts'] })
          queryClient.invalidateQueries({ queryKey: ['private-gallery-albums'] })
          queryClient.invalidateQueries({ queryKey: ['private-gallery-stats'] })

          // Auto-close if all succeeded
          if (status.failed_count === 0) {
            setTimeout(() => {
              handleClose()
              onSuccess?.()
            }, 1500)
          }
        }
      } catch (error) {
        console.error('Error polling job status:', error)
      }
    }, 500)

    return () => clearInterval(pollInterval)
  }, [jobId, queryClient, onSuccess])

  const handleClose = () => {
    setPersonId(undefined)
    setSelectedTags([])
    setTagsManuallyModified(false)
    setMediaDate('')
    setDescription('')
    setJobId(null)
    setProgressItems([])
    setShowProgress(false)
    isSubmitting.current = false
    copyMutation.reset()
    onClose()
  }

  const handleSubmit = () => {
    if (!personId) {
      alert('Please select a person')
      return
    }
    if (isSubmitting.current) return
    isSubmitting.current = true

    // Build progress items from source paths
    const items: ThumbnailProgressItem[] = sourcePaths.map((path) => {
      const isVideo = /\.(mp4|mov|webm|avi|mkv|flv|m4v)$/i.test(path)
      const mediaType = isVideo ? 'video' : 'image'
      const filename = sourceNames?.[path] || path.split('/').pop() || path
      return {
        id: path,
        filename,
        status: 'pending' as const,
        thumbnailUrl: api.getMediaThumbnailUrl(path, mediaType),
        fileType: mediaType,
      }
    })
    setProgressItems(items)
    setShowProgress(true)

    copyMutation.mutate({
      source_paths: sourcePaths,
      person_id: personId,
      tag_ids: selectedTags,
      media_date: mediaDate || undefined,
      description: description || undefined,
      original_filenames: sourceNames,
    }, {
      onSettled: () => {
        isSubmitting.current = false
      },
    })
  }

  if (!open) return null

  // Show progress modal when processing
  if (showProgress) {
    return (
      <ThumbnailProgressModal
        isOpen={true}
        title="Copying to Private Gallery"
        items={progressItems}
        onClose={handleClose}
      />
    )
  }

  // Gallery not setup or locked
  if (isLoadingStatus) {
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
        <div className="w-full max-w-md bg-card rounded-xl shadow-2xl border border-border p-8">
          <div className="flex flex-col items-center gap-4">
            <Loader2 className="w-8 h-8 animate-spin text-primary" />
            <p className="text-muted-foreground">Checking gallery status...</p>
          </div>
        </div>
      </div>
    )
  }

  if (!galleryStatus?.is_setup_complete) {
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
        <div className="w-full max-w-md bg-card rounded-xl shadow-2xl border border-border p-8">
          <div className="flex flex-col items-center gap-4 text-center">
            <div className="w-16 h-16 rounded-full bg-primary/10 flex items-center justify-center">
              <Lock className="w-8 h-8 text-primary" />
            </div>
            <h2 className="text-xl font-semibold">Private Gallery Not Set Up</h2>
            <p className="text-muted-foreground">
              You need to set up the private gallery before you can copy files to it.
            </p>
            <div className="flex gap-3 mt-4">
              <button
                onClick={handleClose}
                className="px-4 py-2 rounded-lg border border-border hover:bg-secondary transition-colors"
              >
                Cancel
              </button>
              <a
                href="/private-gallery"
                className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors"
              >
                Set Up Gallery
              </a>
            </div>
          </div>
        </div>
      </div>
    )
  }

  if (!galleryStatus?.is_unlocked) {
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
        <div className="w-full max-w-md bg-card rounded-xl shadow-2xl border border-border p-8">
          <div className="flex flex-col items-center gap-4 text-center">
            <div className="w-16 h-16 rounded-full bg-amber-500/10 flex items-center justify-center">
              <Lock className="w-8 h-8 text-amber-500" />
            </div>
            <h2 className="text-xl font-semibold">Gallery Locked</h2>
            <p className="text-muted-foreground">
              Please unlock the private gallery first to copy files to it.
            </p>
            <div className="flex gap-3 mt-4">
              <button
                onClick={handleClose}
                className="px-4 py-2 rounded-lg border border-border hover:bg-secondary transition-colors"
              >
                Cancel
              </button>
              <a
                href="/private-gallery"
                className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors"
              >
                Unlock Gallery
              </a>
            </div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
      <div className="w-full max-w-2xl bg-card rounded-xl shadow-2xl border border-border max-h-[90vh] flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between px-4 sm:px-6 py-4 border-b border-border">
          <h2 className="text-lg font-semibold">Copy to Private Gallery</h2>
          <button
            onClick={handleClose}
            className="p-2 rounded-lg hover:bg-secondary transition-colors"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-4 sm:p-6 space-y-6">
          {/* File Thumbnails */}
          <div className="space-y-2">
            <p className="text-sm text-muted-foreground">
              <span className="font-medium">{sourcePaths.length}</span>{' '}
              {sourcePaths.length === 1 ? 'file' : 'files'} selected from{' '}
              <span className="capitalize">{sourceType.replace('_', ' ')}</span>
            </p>
            <div className="grid grid-cols-4 sm:grid-cols-5 gap-1.5 max-h-48 overflow-y-auto p-1 rounded-lg border border-border bg-secondary/30">
              {sourcePaths.map((path, index) => {
                const isVideo = /\.(mp4|mov|webm|avi|mkv|flv|m4v)$/i.test(path)
                const mediaType = isVideo ? 'video' : 'image'
                const thumbnailUrl = api.getMediaThumbnailUrl(path, mediaType)
                const filename = path.split('/').pop() || ''
                return (
                  <div key={index} className="relative aspect-square rounded-lg overflow-hidden bg-secondary">
                    <ThrottledImage
                      src={thumbnailUrl}
                      alt={filename}
                      className="w-full h-full object-cover"
                    />
                    {isVideo && (
                      <div className="absolute bottom-0.5 left-0.5 bg-black/70 rounded px-1">
                        <Video className="w-3 h-3 text-white" />
                      </div>
                    )}
                  </div>
                )
              })}
            </div>
          </div>

          {/* Person Selector */}
          <div>
            <label className="flex items-center gap-2 text-sm font-medium mb-2">
              <span className="text-red-500">*</span>
              Person
            </label>
            <PersonSelector
              value={personId}
              onChange={(id, person) => {
                setPersonId(id)
                // Auto-populate tags from person defaults if not manually modified
                if (!tagsManuallyModified && person?.default_tag_ids?.length) {
                  setSelectedTags(person.default_tag_ids)
                }
              }}
              required
            />
          </div>

          {/* Tags */}
          <TagSearchSelector
            tags={tags}
            selectedTagIds={selectedTags}
            onChange={(ids) => {
              setTagsManuallyModified(true)
              setSelectedTags(ids)
            }}
            label="Tags (optional)"
          />

          {/* Date */}
          <div>
            <label className="flex items-center gap-2 text-sm font-medium mb-2">
              <Calendar className="w-4 h-4" />
              Date (optional)
            </label>
            <input
              type="date"
              value={mediaDate}
              onChange={(e) => setMediaDate(e.target.value)}
              className="w-full px-4 py-2.5 rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-primary"
            />
            <p className="text-xs text-muted-foreground mt-1">
              Leave empty to auto-detect from EXIF or filename
            </p>
          </div>

          {/* Description */}
          <div>
            <label className="flex items-center gap-2 text-sm font-medium mb-2">
              <FileText className="w-4 h-4" />
              Description (optional)
            </label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={2}
              className="w-full px-4 py-2.5 rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-primary resize-none"
              placeholder="Add a description..."
            />
          </div>
        </div>

        {/* Footer */}
        <div className="flex flex-col-reverse sm:flex-row sm:items-center sm:justify-end gap-3 px-4 sm:px-6 py-4 border-t border-border">
          <button
            onClick={handleClose}
            className="w-full sm:w-auto px-4 py-2 rounded-lg border border-border hover:bg-secondary transition-colors"
          >
            Cancel
          </button>
          <button
            onClick={handleSubmit}
            disabled={copyMutation.isPending || !personId}
            className="w-full sm:w-auto px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 transition-colors"
          >
            {copyMutation.isPending ? (
              <>
                <Loader2 className="w-4 h-4 animate-spin" />
                Copying...
              </>
            ) : (
              <>
                <Copy className="w-4 h-4" />
                Copy to Gallery
              </>
            )}
          </button>
        </div>
      </div>
    </div>
  )
}

export default CopyToGalleryModal
