import React, { useState, useEffect, useRef } from 'react';
import { UploadCloud, Film, Settings2, Plus, Loader2, Activity, Images, Trash2 } from 'lucide-react';
import { cn } from '../lib/utils';
import { useStore } from '../store/useStore';
import { getProjects, createProject, uploadMedia, parseMedia, uploadDicomBatch, deleteProject } from '../lib/api';
import type { Project } from '../store/useStore';

interface ProjectLibraryProps {
  onProjectSelect: () => void;
}

export function ProjectLibrary({ onProjectSelect }: ProjectLibraryProps) {
  const projects = useStore((state) => state.projects);
  const setProjects = useStore((state) => state.setProjects);
  const currentProject = useStore((state) => state.currentProject);
  const setCurrentProject = useStore((state) => state.setCurrentProject);
  const addProject = useStore((state) => state.addProject);
  const setFrames = useStore((state) => state.setFrames);
  const setMasks = useStore((state) => state.setMasks);
  const setSelectedMaskIds = useStore((state) => state.setSelectedMaskIds);
  const [isLoading, setIsLoading] = useState(false);
  const [isCreating, setIsCreating] = useState(false);
  const [showModal, setShowModal] = useState(false);
  const [newName, setNewName] = useState('');
  const [newDesc, setNewDesc] = useState('');
  const [showImportMenu, setShowImportMenu] = useState(false);
  const [showVideoConfig, setShowVideoConfig] = useState(false);
  const [pendingFile, setPendingFile] = useState<File | null>(null);
  const [frameProject, setFrameProject] = useState<Project | null>(null);
  const [showFrameConfig, setShowFrameConfig] = useState(false);
  const [frameParseFps, setFrameParseFps] = useState(30);
  const [isGeneratingFrames, setIsGeneratingFrames] = useState(false);
  const [deletingProjectId, setDeletingProjectId] = useState<string | null>(null);
  const videoInputRef = useRef<HTMLInputElement>(null);
  const dicomInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    setIsLoading(true);
    getProjects()
      .then((data) => setProjects(data))
      .catch(console.error)
      .finally(() => setIsLoading(false));
  }, [setProjects]);

  const handleCreate = async () => {
    if (!newName.trim()) return;
    setIsCreating(true);
    try {
      const project = await createProject({ name: newName.trim(), description: newDesc.trim() || undefined });
      addProject(project);
      setShowModal(false);
      setNewName('');
      setNewDesc('');
    } catch (err) {
      console.error('Failed to create project:', err);
    } finally {
      setIsCreating(false);
    }
  };

  const handleSelect = (project: Project) => {
    setCurrentProject(project);
    onProjectSelect();
  };

  const handleDeleteProject = async (project: Project, event: React.MouseEvent) => {
    event.stopPropagation();
    if (deletingProjectId) return;
    const confirmed = window.confirm(`确认删除项目“${project.name}”？\n该操作会删除项目帧、标注、任务记录和相关 mask 元数据，无法撤销。`);
    if (!confirmed) return;

    setDeletingProjectId(project.id);
    try {
      await deleteProject(project.id);
      setProjects(projects.filter((item) => item.id !== project.id));
      if (currentProject?.id === project.id) {
        setCurrentProject(null);
        setFrames([]);
        setMasks([]);
        setSelectedMaskIds([]);
      }
    } catch (err) {
      console.error('Delete project failed:', err);
      alert('删除项目失败，请检查后端服务');
    } finally {
      setDeletingProjectId(null);
    }
  };

  const handleVideoSelect = (file: File) => {
    setPendingFile(file);
    setShowVideoConfig(true);
  };

  const handleVideoUpload = async () => {
    if (!pendingFile) return;
    setShowVideoConfig(false);
    setIsLoading(true);
    try {
      const newProject = await createProject({
        name: pendingFile.name,
        description: `导入于 ${new Date().toLocaleString()}`,
      });
      const result = await uploadMedia(pendingFile, String(newProject.id));
      alert(`视频导入成功: ${pendingFile.name}\n已保存至: ${result.url}\n需要生成帧时，请在项目卡片点击“生成帧”。`);
      const data = await getProjects();
      setProjects(data);
    } catch (err) {
      console.error('Upload failed:', err);
      alert('上传失败，请检查后端服务');
    } finally {
      setIsLoading(false);
      setPendingFile(null);
      if (videoInputRef.current) videoInputRef.current.value = '';
    }
  };

  const openFrameConfig = (project: Project, event: React.MouseEvent) => {
    event.stopPropagation();
    setFrameProject(project);
    setFrameParseFps(Math.round(project.parse_fps || 30));
    setShowFrameConfig(true);
  };

  const handleGenerateFrames = async () => {
    if (!frameProject?.id) return;
    setIsGeneratingFrames(true);
    try {
      const task = await parseMedia(frameProject.id, { parseFps: frameParseFps });
      alert(`生成帧任务已入队 #${task.id}\n帧率: ${frameParseFps} FPS\n可在 Dashboard 查看进度。`);
      const data = await getProjects();
      setProjects(data);
      setShowFrameConfig(false);
      setFrameProject(null);
    } catch (err) {
      console.error('Frame generation failed:', err);
      alert('生成帧失败，请检查后端服务或项目源文件');
    } finally {
      setIsGeneratingFrames(false);
    }
  };

  const handleDicomUpload = async (files: FileList | null) => {
    if (!files || files.length === 0) return;
    const dcmFiles = Array.from(files).filter((f) => f.name.toLowerCase().endsWith('.dcm'));
    if (dcmFiles.length === 0) {
      alert('未选择有效的 .dcm 文件');
      return;
    }
    setIsLoading(true);
    try {
      const result = await uploadDicomBatch(dcmFiles);
      await parseMedia(String(result.project_id));
      alert(`DICOM 上传成功: ${result.uploaded_count} 个文件`);
      const data = await getProjects();
      setProjects(data);
    } catch (err) {
      console.error('DICOM upload failed:', err);
      alert('DICOM 上传失败，请检查后端服务');
    } finally {
      setIsLoading(false);
      if (dicomInputRef.current) dicomInputRef.current.value = '';
    }
  };

  const SkeletonCard = () => (
    <div className="group flex flex-col bg-[#111] border border-white/5 rounded-xl overflow-hidden animate-pulse">
      <div className="w-full aspect-[16/9] bg-[#1a1a1a]" />
      <div className="p-4 flex flex-col gap-2">
        <div className="h-4 bg-[#1a1a1a] rounded w-3/4" />
        <div className="h-3 bg-[#1a1a1a] rounded w-1/2 mt-2" />
      </div>
    </div>
  );

  return (
    <div className="p-8 w-full h-full overflow-y-auto bg-[#0a0a0a]">
      <div className="flex justify-between items-end mb-8 border-b border-white/5 pb-6">
        <div>
          <h1 className="text-3xl font-medium tracking-tight text-white mb-2">视频与连续帧项目库</h1>
          <p className="text-gray-400 text-sm">上传源文件、按帧解析配置，并结构化管理多媒体资产实体。</p>
        </div>
        <div className="flex items-center gap-3">
          <button
            onClick={() => setShowModal(true)}
            className="flex items-center gap-2 bg-white/5 hover:bg-white/10 border border-white/10 text-gray-200 px-5 py-2.5 rounded-lg font-medium text-sm transition-colors"
          >
            <Plus size={18} />
            <span>新建项目</span>
          </button>
          <div className="relative">
            <button
              onClick={() => setShowImportMenu(!showImportMenu)}
              className="flex items-center gap-2 bg-cyan-600 hover:bg-cyan-500 text-white px-5 py-2.5 rounded-lg font-medium text-sm transition-colors border border-cyan-500 shadow-lg shadow-cyan-900/20"
            >
              <UploadCloud size={18} />
              <span>导入多媒体资源</span>
            </button>
            {showImportMenu && (
              <div className="absolute right-0 top-full mt-2 w-56 bg-[#111] border border-white/10 rounded-lg shadow-2xl z-50 overflow-hidden">
                <button
                  className="w-full text-left px-4 py-3 text-sm text-gray-200 hover:bg-white/5 flex items-center gap-3 transition-colors"
                  onClick={() => { setShowImportMenu(false); videoInputRef.current?.click(); }}
                >
                  <Film size={16} className="text-cyan-400" />
                  导入视频文件
                </button>
                <button
                  className="w-full text-left px-4 py-3 text-sm text-gray-200 hover:bg-white/5 flex items-center gap-3 transition-colors border-t border-white/5"
                  onClick={() => { setShowImportMenu(false); dicomInputRef.current?.click(); }}
                >
                  <Activity size={16} className="text-emerald-400" />
                  导入 DICOM 序列
                </button>
              </div>
            )}
          </div>
          <input
            type="file"
            ref={videoInputRef}
            className="hidden"
            accept="video/*"
            onChange={(e) => {
              const file = e.target.files?.[0];
              if (file) handleVideoSelect(file);
            }}
          />
          <input
            type="file"
            ref={dicomInputRef}
            className="hidden"
            accept=".dcm"
            multiple
            onChange={(e) => handleDicomUpload(e.target.files)}
          />
        </div>
      </div>

      {isLoading && projects.length === 0 ? (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
          {Array.from({ length: 8 }).map((_, i) => (
            <SkeletonCard key={i} />
          ))}
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
          {projects.map((proj) => (
            <div
              key={proj.id}
              className="group flex flex-col bg-[#111] border border-white/5 rounded-xl overflow-hidden cursor-pointer hover:border-cyan-500/50 transition-all hover:shadow-[0_0_20px_rgba(6,182,212,0.15)]"
              onClick={() => handleSelect(proj)}
            >
              <div className={cn("w-full aspect-[16/9] relative flex items-center justify-center overflow-hidden bg-[#0d0d0d]")}>
                {proj.thumbnail_url ? (
                  <img
                    src={proj.thumbnail_url}
                    alt={proj.name}
                    className="absolute inset-0 w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
                    loading="lazy"
                  />
                ) : (
                  <Film className="w-12 h-12 text-[#2a2a2a] group-hover:text-[#333] transition-colors" />
                )}
                <div className="absolute top-2 right-2 flex gap-2">
                  <span className="backdrop-blur-md bg-black/40 text-gray-200 text-[10px] font-mono px-2 py-1 rounded border border-white/10 uppercase tracking-widest">
                    {proj.source_type === 'dicom' ? 'DICOM' : (proj.video_path && (proj.frames ?? 0) === 0 ? '待生成帧' : (proj.fps || '30FPS'))}
                  </span>
                  <span className="backdrop-blur-md bg-black/40 text-gray-200 text-[10px] px-2 py-1 rounded border border-white/10 flex items-center gap-1 uppercase tracking-widest">
                    {proj.status === 'ready' ? (
                      <><div className="w-1.5 h-1.5 bg-emerald-500 rounded-full" /> 已就绪</>
                    ) : proj.status === 'parsing' ? (
                      <><div className="w-1.5 h-1.5 bg-amber-500 rounded-full animate-pulse" /> 解析拆帧中</>
                    ) : proj.status === 'error' ? (
                      <><div className="w-1.5 h-1.5 bg-red-500 rounded-full" /> 异常</>
                    ) : (
                      <><div className="w-1.5 h-1.5 bg-blue-500 rounded-full" /> 待处理</>
                    )}
                  </span>
                </div>
              </div>
              <div className="p-4 flex flex-col gap-1">
                <div className="flex justify-between items-start">
                  <h3 className="text-sm font-medium text-gray-200 truncate pr-4" title={proj.name}>{proj.name}</h3>
                  <button
                    type="button"
                    aria-label={`删除项目 ${proj.name}`}
                    title="删除项目"
                    disabled={deletingProjectId === proj.id}
                    onClick={(event) => handleDeleteProject(proj, event)}
                    className="text-gray-500 hover:text-red-400 disabled:opacity-50 disabled:cursor-wait transition-colors"
                  >
                    {deletingProjectId === proj.id ? <Loader2 size={16} className="animate-spin" /> : <Trash2 size={16} />}
                  </button>
                </div>
                <div className="flex items-center gap-4 text-xs text-gray-500 font-mono mt-2">
                   <span className="flex items-center gap-1.5"><Settings2 size={12} /> {proj.frames ?? 0} 帧节点</span>
                   {proj.original_fps && (
                     <span className="flex items-center gap-1.5 text-cyan-400/80"><Activity size={12} /> 原 {proj.original_fps.toFixed(1)}fps</span>
                   )}
                </div>
                {proj.video_path && (proj.frames ?? 0) === 0 && proj.status !== 'parsing' && (
                  <button
                    onClick={(event) => openFrameConfig(proj, event)}
                    className="mt-3 inline-flex items-center justify-center gap-2 rounded-md border border-cyan-500/30 bg-cyan-500/10 px-3 py-2 text-xs font-medium text-cyan-200 hover:bg-cyan-500/20 transition-colors"
                  >
                    <Images size={14} />
                    生成帧
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Video parse FPS config modal */}
      {showVideoConfig && pendingFile && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
          <div className="bg-[#111] border border-white/10 rounded-2xl p-6 w-full max-w-md shadow-2xl">
            <h2 className="text-lg font-semibold text-white mb-4">导入视频文件</h2>
            <div className="space-y-4">
              <div className="text-sm text-gray-400">文件: <span className="text-gray-200">{pendingFile.name}</span></div>
              <p className="text-xs leading-5 text-gray-500">此步骤只上传源视频并创建项目，不会立即拆帧。拆帧时再选择目标 FPS。</p>
            </div>
            <div className="flex justify-end gap-3 mt-6">
              <button
                onClick={() => { setShowVideoConfig(false); setPendingFile(null); }}
                className="px-4 py-2 rounded-lg text-sm text-gray-400 hover:text-white transition-colors"
              >
                取消
              </button>
              <button
                onClick={handleVideoUpload}
                className="px-4 py-2 rounded-lg text-sm font-medium bg-cyan-500 hover:bg-cyan-400 text-black transition-all"
              >
                开始导入
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Frame generation FPS config modal */}
      {showFrameConfig && frameProject && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
          <div className="bg-[#111] border border-white/10 rounded-2xl p-6 w-full max-w-md shadow-2xl">
            <h2 className="text-lg font-semibold text-white mb-4">生成帧</h2>
            <div className="space-y-4">
              <div className="text-sm text-gray-400">项目: <span className="text-gray-200">{frameProject.name}</span></div>
              <div>
                <label className="block text-xs font-medium text-gray-400 uppercase tracking-widest mb-2">生成帧率 (FPS)</label>
                <div className="flex items-center gap-3">
                  <input
                    type="range"
                    min="1"
                    max="60"
                    value={frameParseFps}
                    onChange={(e) => setFrameParseFps(parseInt(e.target.value))}
                    className="flex-1 accent-cyan-500"
                  />
                  <span className="text-sm font-mono text-cyan-400 w-12 text-right">{frameParseFps}</span>
                </div>
                <p className="text-[10px] text-gray-600 mt-1">帧率越低，提取的帧越少，处理速度越快</p>
              </div>
            </div>
            <div className="flex justify-end gap-3 mt-6">
              <button
                onClick={() => { setShowFrameConfig(false); setFrameProject(null); }}
                disabled={isGeneratingFrames}
                className="px-4 py-2 rounded-lg text-sm text-gray-400 hover:text-white transition-colors disabled:opacity-50"
              >
                取消
              </button>
              <button
                onClick={handleGenerateFrames}
                disabled={isGeneratingFrames}
                className="px-4 py-2 rounded-lg text-sm font-medium bg-cyan-500 hover:bg-cyan-400 text-black transition-all disabled:opacity-60"
              >
                {isGeneratingFrames ? '入队中...' : '开始生成帧'}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* New project modal */}
      {showModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
          <div className="bg-[#111] border border-white/10 rounded-2xl p-6 w-full max-w-md shadow-2xl">
            <h2 className="text-lg font-semibold text-white mb-4">新建项目</h2>
            <div className="space-y-4">
              <div>
                <label className="block text-xs font-medium text-gray-400 uppercase tracking-widest mb-2">项目名称</label>
                <input
                  type="text"
                  value={newName}
                  onChange={(e) => setNewName(e.target.value)}
                  className="w-full bg-[#1a1a1a] border border-white/10 rounded-lg px-4 py-3 text-sm focus:outline-none focus:border-cyan-500/50 focus:ring-1 focus:ring-cyan-500/50 transition-all"
                  placeholder="输入项目名称"
                />
              </div>
              <div>
                <label className="block text-xs font-medium text-gray-400 uppercase tracking-widest mb-2">描述（可选）</label>
                <input
                  type="text"
                  value={newDesc}
                  onChange={(e) => setNewDesc(e.target.value)}
                  className="w-full bg-[#1a1a1a] border border-white/10 rounded-lg px-4 py-3 text-sm focus:outline-none focus:border-cyan-500/50 focus:ring-1 focus:ring-cyan-500/50 transition-all"
                  placeholder="输入项目描述"
                />
              </div>
            </div>
            <div className="flex justify-end gap-3 mt-6">
              <button
                onClick={() => { setShowModal(false); setNewName(''); setNewDesc(''); }}
                className="px-4 py-2 rounded-lg text-sm text-gray-400 hover:text-white transition-colors"
              >
                取消
              </button>
              <button
                onClick={handleCreate}
                disabled={isCreating || !newName.trim()}
                className={cn(
                  "px-4 py-2 rounded-lg text-sm font-medium flex items-center gap-2 transition-all",
                  isCreating || !newName.trim()
                    ? "bg-cyan-500/50 text-black/70 cursor-not-allowed"
                    : "bg-cyan-500 hover:bg-cyan-400 text-black"
                )}
              >
                {isCreating && <Loader2 size={14} className="animate-spin" />}
                创建
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
