"use client"

import { useState, useEffect, useCallback } from "react"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
import { X, Upload, Image as ImageIcon, Plus, ZoomIn, Edit2, Video, Play } from "lucide-react"
import { useDialog } from "@/components/ui/alert-dialog-custom"
import imageCompression from "browser-image-compression"
import type { FamilyPhoto } from "@/types/family"
import { format } from "date-fns"
import { zhCN } from "date-fns/locale"

interface PhotoGalleryProps {
  photos?: FamilyPhoto[]
  photoIds?: string[] // 兼容旧格式
  onChange: (photos: FamilyPhoto[]) => Promise<void> | void
  readonly?: boolean
}

export function PhotoGallery({ photos: propPhotos = [], photoIds = [], onChange, readonly = false }: PhotoGalleryProps) {
  const { showAlert, showConfirm, showPrompt } = useDialog()
  const [photos, setPhotos] = useState<FamilyPhoto[]>([])
  const [selectedPhoto, setSelectedPhoto] = useState<FamilyPhoto | null>(null)
  const [isUploading, setIsUploading] = useState(false)
  const [editingPhoto, setEditingPhoto] = useState<FamilyPhoto | null>(null)
  const [editCaption, setEditCaption] = useState("")
  const [pendingVisibilityUrl, setPendingVisibilityUrl] = useState<string | null>(null)

  // 加载照片 - 兼容新旧格式
  useEffect(() => {
    // 优先使用新格式 photos
    if (propPhotos && propPhotos.length > 0) {
      const normalized = propPhotos.map(photo => ({
        ...photo,
        visibleInOverview: photo.visibleInOverview ?? false,
        adminVisibleOverride: photo.adminVisibleOverride ?? true,
      }))
      setPhotos(normalized)
    } else if (photoIds && photoIds.length > 0) {
      // 兼容旧格式：将 string[] 转换为 FamilyPhoto[]
      const convertedPhotos: FamilyPhoto[] = photoIds.map(url => ({
        url,
        uploadedAt: new Date().toISOString(), // 旧数据没有时间，用当前时间
        visibleInOverview: false,
        adminVisibleOverride: true,
      }))
      setPhotos(convertedPhotos)
    } else {
      setPhotos([])
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [JSON.stringify(propPhotos), JSON.stringify(photoIds)])

  // 判断是否为视频文件
  const isVideoFile = useCallback((url: string) => {
    const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']
    return videoExtensions.some(ext => url.toLowerCase().endsWith(ext))
  }, [])

  const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    if (!files || files.length === 0) return

    setIsUploading(true)
    try {
      const newPhotos: FamilyPhoto[] = []

      for (const file of Array.from(files)) {
        const isImage = file.type.startsWith('image/')
        const isVideo = file.type.startsWith('video/')
        
        if (!isImage && !isVideo) continue

        let fileToUpload: File | Blob = file

        // 只对图片进行压缩
        if (isImage) {
          const options = {
            maxSizeMB: 2,
            maxWidthOrHeight: 1920,
            useWebWorker: true,
          }
          fileToUpload = await imageCompression(file, options)
        }
        
        // 上传到服务器
        const formData = new FormData()
        // 对于视频文件，保留原始文件名；对于压缩后的图片，使用原始文件名
        formData.append('file', fileToUpload, file.name)
        
        const response = await fetch('/api/upload', {
          method: 'POST',
          body: formData,
        })

        if (!response.ok) {
          const errorData = await response.json()
          throw new Error(errorData.error || '上传失败')
        }

        const { url } = await response.json()
        newPhotos.push({
          url,
          uploadedAt: new Date().toISOString(),
          visibleInOverview: false,
          adminVisibleOverride: true,
        })
      }

      // 更新照片列表
      onChange([...photos, ...newPhotos])
    } catch (error: any) {
      console.error('上传文件失败:', error)
      await showAlert(error.message || '上传文件失败', '错误')
    } finally {
      setIsUploading(false)
      e.target.value = ''
    }
  }

  const handleDelete = async (photo: FamilyPhoto) => {
    const confirmed = await showConfirm('确定要删除这张照片吗？', '删除照片')
    if (confirmed) {
      onChange(photos.filter(p => p.url !== photo.url))
    }
  }

  const handleToggleOverview = async (photo: FamilyPhoto, value: boolean) => {
    if (readonly) return
    setPendingVisibilityUrl(photo.url)
    const previous = photos
    const updatedPhotos = photos.map(p =>
      p.url === photo.url ? { ...p, visibleInOverview: value } : p
    )
    setPhotos(updatedPhotos)
    try {
      await onChange(updatedPhotos)
    } catch (error) {
      console.error('更新照片展示状态失败:', error)
      setPhotos(previous)
      await showAlert('更新照片展示状态失败，请重试', '错误')
    } finally {
      setPendingVisibilityUrl(null)
    }
  }

  const handleEditCaption = (photo: FamilyPhoto) => {
    setEditingPhoto(photo)
    setEditCaption(photo.caption || "")
  }

  const handleSaveCaption = async () => {
    if (!editingPhoto) return
    const updatedPhotos = photos.map(p => 
      p.url === editingPhoto.url 
        ? { ...p, caption: editCaption.trim() || undefined }
        : p
    )
    
    try {
      await onChange(updatedPhotos)
      setEditingPhoto(null)
      setEditCaption("")
    } catch (error) {
      console.error("保存说明失败:", error)
      await showAlert("保存说明失败，请重试", "错误")
    }
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h3 className="text-sm font-medium">媒体库 ({photos.length})</h3>
        {!readonly && (
          <label>
            <input
              type="file"
              multiple
              accept="image/*,video/*"
              className="hidden"
              onChange={handleUpload}
              disabled={isUploading}
            />
            <Button
              type="button"
              variant="outline"
              size="sm"
              disabled={isUploading}
              asChild
            >
              <span>
                <Plus className="mr-2 h-4 w-4" />
                {isUploading ? '上传中...' : '添加照片/视频'}
              </span>
            </Button>
          </label>
        )}
      </div>

      {photos.length > 0 ? (
        <div className="space-y-6">
          {/* 按月份分组显示 */}
          {(() => {
            // 按月份分组
            const sortedPhotos = [...photos].sort((a, b) => 
              new Date(b.uploadedAt).getTime() - new Date(a.uploadedAt).getTime()
            )
            const groupedByMonth: Record<string, FamilyPhoto[]> = {}
            sortedPhotos.forEach(photo => {
              const monthKey = format(new Date(photo.uploadedAt), 'yyyy年MM月', { locale: zhCN })
              if (!groupedByMonth[monthKey]) {
                groupedByMonth[monthKey] = []
              }
              groupedByMonth[monthKey].push(photo)
            })
            
            return Object.entries(groupedByMonth).map(([month, monthPhotos]) => (
              <div key={month}>
                <h4 className="text-sm font-medium text-muted-foreground mb-3 flex items-center gap-2">
                  <span className="w-2 h-2 rounded-full bg-primary"></span>
                  {month}
                  <span className="text-xs text-muted-foreground/70">({monthPhotos.length})</span>
                </h4>
                <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
                  {monthPhotos.map((photo, index) => {
                    const isVideo = isVideoFile(photo.url)
                    return (
                      <div key={photo.url + index} className="relative group">
                        <div className="aspect-square">
                          {isVideo ? (
                            <div 
                              className="w-full h-full bg-black rounded-t-lg border border-border cursor-pointer hover:opacity-90 transition-opacity flex items-center justify-center relative"
                              onClick={() => setSelectedPhoto(photo)}
                            >
                              <video
                                src={photo.url}
                                className="w-full h-full object-cover rounded-t-lg"
                                muted
                                preload="metadata"
                              />
                              <div className="absolute inset-0 flex items-center justify-center bg-black/30">
                                <div className="w-12 h-12 rounded-full bg-white/90 flex items-center justify-center">
                                  <Play className="h-6 w-6 text-black ml-1" />
                                </div>
                              </div>
                              <div className="absolute top-2 left-2 bg-black/70 text-white text-xs px-2 py-1 rounded flex items-center gap-1">
                                <Video className="h-3 w-3" />
                                视频
                              </div>
                            </div>
                          ) : (
                            <img
                              src={photo.url}
                              alt={photo.caption || "家族照片"}
                              className="w-full h-full object-cover rounded-t-lg border border-border cursor-pointer hover:opacity-90 transition-opacity"
                              onClick={() => setSelectedPhoto(photo)}
                            />
                          )}
                        </div>
                        {/* 媒体信息区域 */}
                        <div className="p-2 bg-muted/50 rounded-b-lg border border-t-0 border-border text-xs">
                          <div className="text-muted-foreground">
                            {format(new Date(photo.uploadedAt), 'MM-dd HH:mm', { locale: zhCN })}
                          </div>
                          {photo.caption && (
                            <div className="text-foreground mt-1 line-clamp-2">{photo.caption}</div>
                          )}
                          <div className="mt-2 flex items-center justify-between gap-2 text-[11px] text-muted-foreground">
                            <span>展示到总览</span>
                            <Switch
                              checked={photo.visibleInOverview ?? false}
                              onCheckedChange={(checked) => handleToggleOverview(photo, checked)}
                              disabled={readonly || pendingVisibilityUrl === photo.url}
                            />
                          </div>
                        </div>
                        {/* 操作按钮 */}
                        {!readonly && (
                          <>
                            <Button
                              type="button"
                              variant="destructive"
                              size="icon"
                              className="absolute top-2 right-2 h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
                              onClick={() => handleDelete(photo)}
                            >
                              <X className="h-3 w-3" />
                            </Button>
                            <Button
                              type="button"
                              variant="secondary"
                              size="icon"
                              className="absolute top-2 right-10 h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
                              onClick={() => handleEditCaption(photo)}
                              title="编辑说明"
                            >
                              <Edit2 className="h-3 w-3" />
                            </Button>
                          </>
                        )}
                        <Button
                          type="button"
                          variant="secondary"
                          size="icon"
                          className="absolute bottom-12 right-2 h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
                          onClick={() => setSelectedPhoto(photo)}
                        >
                          {isVideo ? <Play className="h-3 w-3" /> : <ZoomIn className="h-3 w-3" />}
                        </Button>
                      </div>
                    )
                  })}
                </div>
              </div>
            ))
          })()}
        </div>
      ) : (
        <div className="text-center py-8 text-muted-foreground text-sm border border-dashed rounded-lg">
          暂无照片或视频
        </div>
      )}

      {/* 媒体预览对话框 */}
      <Dialog open={!!selectedPhoto} onOpenChange={() => setSelectedPhoto(null)}>
        <DialogContent className="max-w-4xl" aria-describedby="photo-preview-desc">
          <DialogHeader>
            <DialogTitle>
              {selectedPhoto?.caption || (selectedPhoto && isVideoFile(selectedPhoto.url) ? "视频预览" : "照片预览")}
            </DialogTitle>
            <DialogDescription id="photo-preview-desc" className="sr-only">
              家族媒体预览弹窗，可查看大图或播放视频
            </DialogDescription>
          </DialogHeader>
          {selectedPhoto && (
            <div className="space-y-2">
              {isVideoFile(selectedPhoto.url) ? (
                <video
                  src={selectedPhoto.url}
                  controls
                  autoPlay
                  className="w-full h-auto max-h-[70vh] object-contain bg-black rounded-lg"
                />
              ) : (
                <img
                  src={selectedPhoto.url}
                  alt={selectedPhoto.caption || "照片预览"}
                  className="w-full h-auto max-h-[70vh] object-contain"
                />
              )}
              <div className="text-sm text-muted-foreground">
                上传于 {format(new Date(selectedPhoto.uploadedAt), 'yyyy年MM月dd日', { locale: zhCN })}
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>

      {/* 编辑说明对话框 */}
      <Dialog open={!!editingPhoto} onOpenChange={() => setEditingPhoto(null)}>
        <DialogContent aria-describedby="photo-edit-desc">
          <DialogHeader>
            <DialogTitle>编辑照片说明</DialogTitle>
            <DialogDescription id="photo-edit-desc" className="sr-only">
              修改当前照片的备注文字并保存
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="caption">照片说明（选填）</Label>
              <Input
                id="caption"
                value={editCaption}
                onChange={(e) => setEditCaption(e.target.value)}
                placeholder="输入照片说明..."
                maxLength={200}
              />
              <p className="text-xs text-muted-foreground">{editCaption.length}/200</p>
            </div>
            <div className="flex justify-end gap-2">
              <Button variant="outline" onClick={() => setEditingPhoto(null)}>
                取消
              </Button>
              <Button onClick={handleSaveCaption}>
                保存
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>
    </div>
  )
}
