import { useRef, useState, type ChangeEvent } from "react";
import { useNavigate, useParams } from "react-router";
import {
  ArrowRight,
  Box,
  Sparkles,
  Users,
  MapPin,
  Plus,
  Edit2,
  Trash2,
  Upload,
  X,
  Check,
  RefreshCw,
  ImageIcon,
  Loader2,
} from "lucide-react";
import {
  useGlobalAssets,
  useCreateAsset,
  useUpdateAsset,
  useUploadAssetImage,
  useGenerateAssetImage,
  useDeleteAsset,
} from "../../hooks/useAssets";
import type { GlobalAsset } from "../../lib/api/assets";
import { ImagePreviewModal } from "../components/ImagePreviewModal";

type SettingsTab = "characters" | "scenes" | "props";

interface EditForm {
  id?: string;
  name: string;
  category: string;
  description: string;
  imageUrl: string;
}

const CATEGORIES = ["首饰", "文件", "配饰", "文具", "饮品", "电子设备", "武器", "交通工具", "其他"];

const emptyForm = (): EditForm => ({
  name: "",
  category: "配饰",
  description: "",
  imageUrl: "",
});

function revokeObjectPreview(url: string | null) {
  if (url?.startsWith("blob:")) {
    URL.revokeObjectURL(url);
  }
}

export function PropsGeneration() {
  const navigate = useNavigate();
  const { projectId } = useParams();
  const numProjectId = projectId ?? "";

  const { data: props = [], isLoading } = useGlobalAssets("prop", "personal");
  const createAsset = useCreateAsset("prop", "personal");
  const updateAsset = useUpdateAsset("prop", "personal");
  const uploadImage = useUploadAssetImage("prop", "personal");
  const generateImage = useGenerateAssetImage("prop", "personal");
  const deleteAsset = useDeleteAsset("prop", "personal");

  const [activeTab, setActiveTab] = useState<SettingsTab>("props");
  const [showModal, setShowModal] = useState(false);
  const [editForm, setEditForm] = useState<EditForm>(emptyForm());
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [pendingFile, setPendingFile] = useState<File | null>(null);
  const [saving, setSaving] = useState(false);
  const [generatingImageId, setGeneratingImageId] = useState<string | null>(null);
  const [previewImage, setPreviewImage] = useState<{ src: string; title: string } | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const settingsTabs = [
    { id: "characters" as SettingsTab, label: "角色", icon: Users, path: `/project/${projectId}/characters` },
    { id: "scenes" as SettingsTab, label: "场景", icon: MapPin, path: `/project/${projectId}/scenes` },
    { id: "props" as SettingsTab, label: "道具", icon: Box, path: `/project/${projectId}/props` },
  ];

  const resetImageInput = () => {
    if (fileInputRef.current) fileInputRef.current.value = "";
  };

  const openAdd = () => {
    revokeObjectPreview(imagePreview);
    setEditForm(emptyForm());
    setImagePreview(null);
    setPendingFile(null);
    resetImageInput();
    setShowModal(true);
  };

  const openEdit = (p: GlobalAsset) => {
    revokeObjectPreview(imagePreview);
    setEditForm({
      id: p.id,
      name: p.name,
      category: p.tags?.[0] ?? "其他",
      description: p.description ?? "",
      imageUrl: p.imageUrl ?? "",
    });
    setImagePreview(p.imageUrl ?? null);
    setPendingFile(null);
    resetImageInput();
    setShowModal(true);
  };

  const closeModal = () => {
    revokeObjectPreview(imagePreview);
    setShowModal(false);
    setEditForm(emptyForm());
    setImagePreview(null);
    setPendingFile(null);
    resetImageInput();
  };

  const handleFileSelect = (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;
    revokeObjectPreview(imagePreview);
    setPendingFile(file);
    setImagePreview(URL.createObjectURL(file));
    event.target.value = "";
  };

  const clearSelectedImage = () => {
    revokeObjectPreview(imagePreview);
    setPendingFile(null);
    setImagePreview(editForm.imageUrl || null);
    resetImageInput();
  };

  const saveAsset = async (uploadPendingImage = true) => {
    if (!editForm.name.trim()) return null;
    const payload = {
      assetType: "prop",
      libraryType: "personal",
      name: editForm.name.trim(),
      description: editForm.description.trim(),
      tags: editForm.category,
      imageUrl: editForm.imageUrl || undefined,
      sourceProjectId: numProjectId || undefined,
    };
    let saved = editForm.id
      ? await updateAsset.mutateAsync({ id: editForm.id, patch: payload })
      : await createAsset.mutateAsync(payload);

    if (uploadPendingImage && pendingFile) {
      saved = await uploadImage.mutateAsync({ id: saved.id, file: pendingFile });
    }
    return saved;
  };

  const handleSave = async () => {
    if (!editForm.name.trim()) return;
    setSaving(true);
    try {
      await saveAsset(true);
      closeModal();
    } catch (error) {
      alert("保存失败: " + (error as Error).message);
    } finally {
      setSaving(false);
    }
  };

  const handleGenerateImage = async (prop: GlobalAsset) => {
    setGeneratingImageId(prop.id);
    try {
      await generateImage.mutateAsync(prop.id);
    } catch (error) {
      alert("道具图生成失败: " + (error as Error).message);
    } finally {
      setGeneratingImageId(null);
    }
  };

  const handleGenerateFromModal = async () => {
    if (!editForm.name.trim()) return;
    setSaving(true);
    setGeneratingImageId(editForm.id ?? "draft");
    try {
      const saved = await saveAsset(false);
      if (!saved) return;
      const generated = await generateImage.mutateAsync(saved.id);
      revokeObjectPreview(imagePreview);
      setEditForm({
        id: generated.id,
        name: generated.name,
        category: generated.tags?.[0] ?? editForm.category,
        description: generated.description ?? editForm.description,
        imageUrl: generated.imageUrl ?? "",
      });
      setImagePreview(generated.imageUrl ?? null);
      setPendingFile(null);
      resetImageInput();
    } catch (error) {
      alert("道具图生成失败: " + (error as Error).message);
    } finally {
      setSaving(false);
      setGeneratingImageId(null);
    }
  };

  const handleDelete = async (id: string) => {
    if (!confirm("确定要删除这个道具吗？")) return;
    await deleteAsset.mutateAsync(id);
  };

  const withImage = props.filter((p) => p.imageUrl).length;
  const isSaving = saving || createAsset.isPending || updateAsset.isPending || uploadImage.isPending;
  const isBusy = isSaving || generateImage.isPending;

  return (
    <div className="h-full overflow-auto bg-background relative">
      <div className="p-6 pb-24">
        <div className="max-w-7xl mx-auto">
          <div className="mb-6">
            <div className="flex items-center gap-3 mb-2">
              <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-[#5b5ff9] to-[#8b5ff9] flex items-center justify-center">
                <Sparkles className="w-4 h-4 text-white" />
              </div>
              <h1 className="text-2xl font-semibold text-foreground">项目设定</h1>
            </div>
            <p className="text-sm text-muted-foreground">管理角色、场景和道具设定</p>
          </div>

          <div className="flex items-center justify-between mb-6">
            <div className="flex items-center gap-2">
              {settingsTabs.map((tab) => {
                const Icon = tab.icon;
                return (
                  <button
                    key={tab.id}
                    onClick={() => { setActiveTab(tab.id); navigate(tab.path); }}
                    className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm transition-all ${
                      activeTab === tab.id
                        ? "bg-accent text-accent-foreground font-medium"
                        : "text-muted-foreground hover:text-foreground hover:bg-muted"
                    }`}
                  >
                    <Icon className="w-4 h-4" />
                    {tab.label}
                  </button>
                );
              })}
            </div>
            <button
              onClick={openAdd}
              className="px-4 py-2 rounded-lg bg-gradient-to-r from-[#5b5ff9] to-[#8b5ff9] text-white hover:shadow-md transition-all flex items-center gap-2 text-sm"
            >
              <Plus className="w-4 h-4" />
              新增道具
            </button>
          </div>

          <div className="flex items-center justify-between mb-6 rounded-lg border border-border bg-card p-4">
            <div className="flex items-center gap-6">
              <div className="flex items-center gap-2">
                <span className="text-sm text-muted-foreground">总计:</span>
                <span className="text-lg font-semibold text-foreground">{props.length}</span>
              </div>
              <div className="flex items-center gap-2">
                <span className="text-sm text-muted-foreground">有图片:</span>
                <span className="text-lg font-semibold text-green-600">{withImage}</span>
              </div>
              <div className="flex items-center gap-2">
                <span className="text-sm text-muted-foreground">无图片:</span>
                <span className="text-lg font-semibold text-muted-foreground">{props.length - withImage}</span>
              </div>
            </div>
            <button
              onClick={() => {}}
              className="p-2 rounded-lg border border-border bg-card text-foreground hover:bg-muted transition-colors"
            >
              <RefreshCw className="w-4 h-4" />
            </button>
          </div>

          {isLoading ? (
            <div className="flex items-center justify-center py-20">
              <Loader2 className="w-8 h-8 animate-spin text-primary" />
            </div>
          ) : props.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-20 text-center">
              <Box className="w-12 h-12 text-muted-foreground/30 mb-4" />
              <p className="text-muted-foreground mb-4">暂无道具，点击“新增道具”开始添加</p>
              <button onClick={openAdd} className="px-4 py-2 rounded-lg bg-gradient-to-r from-[#5b5ff9] to-[#8b5ff9] text-white text-sm flex items-center gap-2">
                <Plus className="w-4 h-4" />新增道具
              </button>
            </div>
          ) : (
            <div className="grid grid-cols-6 gap-4 mb-8">
              {props.map((prop) => (
                <div key={prop.id} className="rounded-xl border border-border bg-card overflow-hidden group">
                  <div className="aspect-square relative bg-muted">
                    {prop.imageUrl ? (
                      <button
                        type="button"
                        onClick={() => setPreviewImage({ src: prop.imageUrl!, title: prop.name })}
                        className="block h-full w-full cursor-zoom-in"
                      >
                        <img src={prop.imageUrl} alt={prop.name} className="w-full h-full object-cover" />
                      </button>
                    ) : (
                      <div className="w-full h-full flex items-center justify-center">
                        <Box className="w-10 h-10 text-muted-foreground/30" />
                      </div>
                    )}
                    <div
                      className={`pointer-events-none absolute inset-0 bg-black/40 opacity-0 group-hover:pointer-events-auto group-hover:opacity-100 transition-opacity flex items-center justify-center gap-1 ${
                        prop.imageUrl ? "cursor-zoom-in" : ""
                      }`}
                      onClick={() => {
                        if (prop.imageUrl) setPreviewImage({ src: prop.imageUrl, title: prop.name });
                      }}
                    >
                      {prop.imageUrl && (
                        <button
                          type="button"
                          onClick={(event) => {
                            event.stopPropagation();
                            setPreviewImage({ src: prop.imageUrl!, title: prop.name });
                          }}
                          className="p-1.5 rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30 transition-colors"
                          title="查看大图"
                        >
                          <ImageIcon className="w-4 h-4 text-white" />
                        </button>
                      )}
                      <button
                        onClick={(event) => {
                          event.stopPropagation();
                          handleGenerateImage(prop);
                        }}
                        disabled={generatingImageId === prop.id || generateImage.isPending}
                        className="p-1.5 rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30 transition-colors disabled:opacity-50"
                        title={prop.imageUrl ? "AI重新生成道具图" : "AI生成道具图"}
                      >
                        {generatingImageId === prop.id ? (
                          <Loader2 className="w-4 h-4 text-white animate-spin" />
                        ) : prop.imageUrl ? (
                          <RefreshCw className="w-4 h-4 text-white" />
                        ) : (
                          <Sparkles className="w-4 h-4 text-white" />
                        )}
                      </button>
                      <button
                        onClick={(event) => {
                          event.stopPropagation();
                          openEdit(prop);
                        }}
                        className="p-1.5 rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30 transition-colors"
                      >
                        <Edit2 className="w-4 h-4 text-white" />
                      </button>
                    </div>
                    {generatingImageId === prop.id && (
                      <div className="absolute inset-0 bg-background/80 backdrop-blur-sm flex flex-col items-center justify-center gap-2">
                        <Loader2 className="w-6 h-6 text-primary animate-spin" />
                        <span className="text-xs text-foreground">生成中</span>
                      </div>
                    )}
                  </div>
                  <div className="p-3">
                    <div className="flex items-center justify-between mb-1">
                      <h3 className="font-medium text-foreground text-sm truncate flex-1">{prop.name}</h3>
                      <button
                        onClick={() => handleDelete(prop.id)}
                        disabled={deleteAsset.isPending}
                        className="p-0.5 rounded hover:bg-destructive/10 transition-colors flex-shrink-0 disabled:opacity-50"
                      >
                        <Trash2 className="w-3 h-3 text-destructive" />
                      </button>
                    </div>
                    {prop.tags?.[0] && (
                      <div className="mb-2">
                        <span className="px-2 py-0.5 rounded-md bg-accent text-primary text-xs">{prop.tags[0]}</span>
                      </div>
                    )}
                    {prop.description && (
                      <p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">{prop.description}</p>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      <div className="fixed bottom-0 left-0 right-0 border-t border-border bg-card/95 backdrop-blur-sm px-6 py-3 z-10">
        <div className="max-w-7xl mx-auto flex items-center justify-end gap-3">
          <button
            onClick={() => navigate(`/project/${projectId}/storyboard`)}
            className="px-6 py-2 rounded-lg bg-gradient-to-r from-green-500 to-emerald-500 text-white hover:shadow-md transition-all flex items-center gap-2 text-sm font-medium"
          >
            <ArrowRight className="w-4 h-4" />
            进入分镜
          </button>
        </div>
      </div>

      {showModal && (
        <div className="fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-50 p-6">
          <div className="bg-card rounded-2xl border border-border w-full max-w-2xl max-h-[90vh] flex flex-col">
            <div className="flex items-center justify-between p-6 border-b border-border flex-shrink-0">
              <h2 className="text-lg font-semibold text-foreground">
                {editForm.id ? "编辑道具" : "新增道具"}
              </h2>
              <button onClick={closeModal} className="p-2 hover:bg-muted rounded-lg transition-colors">
                <X className="w-5 h-5 text-muted-foreground" />
              </button>
            </div>

            <div className="overflow-auto p-6 space-y-4 flex-1">
              <div className="rounded-xl border border-border bg-muted/20 p-4">
                <div className="mb-3 flex items-center justify-between gap-3">
                  <div>
                    <label className="block text-sm font-medium text-foreground">道具图片（可选）</label>
                    <p className="mt-1 text-xs text-muted-foreground">可以上传参考图，也可以根据道具名称和描述 AI 生成。</p>
                  </div>
                  {pendingFile && (
                    <button onClick={clearSelectedImage} className="text-xs text-destructive hover:underline">
                      撤销更换
                    </button>
                  )}
                </div>
                <div
                  className="w-full aspect-video rounded-lg border-2 border-dashed border-border bg-background flex items-center justify-center cursor-pointer hover:border-primary transition-colors overflow-hidden"
                  onClick={() => fileInputRef.current?.click()}
                >
                  {imagePreview ? (
                    <img src={imagePreview} alt="道具图片预览" className="w-full h-full object-cover" />
                  ) : (
                    <div className="text-center px-4">
                      <Upload className="w-8 h-8 text-muted-foreground mx-auto mb-2" />
                      <span className="text-sm text-muted-foreground">点击上传道具参考图</span>
                    </div>
                  )}
                </div>
                {imagePreview && (
                  <div className="mt-2 flex items-center gap-2">
                    <button
                      type="button"
                      onClick={() => fileInputRef.current?.click()}
                      className="inline-flex items-center gap-1.5 rounded-md border border-border bg-card px-2.5 py-1 text-xs text-foreground hover:bg-muted"
                    >
                      <Upload className="h-3.5 w-3.5" />
                      更换图片
                    </button>
                    <button
                      type="button"
                      onClick={handleGenerateFromModal}
                      disabled={!editForm.name.trim() || isBusy}
                      className="inline-flex items-center gap-1.5 rounded-md border border-primary/30 bg-primary/5 px-2.5 py-1 text-xs text-primary hover:bg-primary/10 disabled:opacity-50"
                    >
                      {generatingImageId === (editForm.id ?? "draft") ? (
                        <Loader2 className="h-3.5 w-3.5 animate-spin" />
                      ) : (
                        <Sparkles className="h-3.5 w-3.5" />
                      )}
                      AI重新生成
                    </button>
                  </div>
                )}
                {!imagePreview && (
                  <button
                    type="button"
                    onClick={handleGenerateFromModal}
                    disabled={!editForm.name.trim() || isBusy}
                    className="mt-2 inline-flex items-center gap-1.5 rounded-md border border-primary/30 bg-primary/5 px-2.5 py-1 text-xs text-primary hover:bg-primary/10 disabled:opacity-50"
                  >
                    {generatingImageId === (editForm.id ?? "draft") ? (
                      <Loader2 className="h-3.5 w-3.5 animate-spin" />
                    ) : (
                      <Sparkles className="h-3.5 w-3.5" />
                    )}
                    {editForm.id ? "AI生成道具图" : "保存并AI生成"}
                  </button>
                )}
                <input ref={fileInputRef} type="file" accept="image/*" className="hidden" onChange={handleFileSelect} />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium text-foreground mb-2">道具名称 <span className="text-destructive">*</span></label>
                  <input
                    type="text"
                    value={editForm.name}
                    onChange={(e) => setEditForm({ ...editForm, name: e.target.value })}
                    placeholder="输入道具名称"
                    className="w-full px-3 py-2 rounded-lg border border-border bg-background text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/20"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-foreground mb-2">道具分类</label>
                  <select
                    value={editForm.category}
                    onChange={(e) => setEditForm({ ...editForm, category: e.target.value })}
                    className="w-full px-3 py-2 rounded-lg border border-border bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 cursor-pointer"
                  >
                    {CATEGORIES.map((c) => <option key={c} value={c}>{c}</option>)}
                  </select>
                </div>
              </div>

              <div>
                <label className="block text-sm font-medium text-foreground mb-2">道具描述</label>
                <textarea
                  value={editForm.description}
                  onChange={(e) => setEditForm({ ...editForm, description: e.target.value })}
                  placeholder="描述道具的外观、用途和重要性"
                  rows={4}
                  className="w-full px-3 py-2 rounded-lg border border-border bg-background text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 resize-none"
                />
              </div>
            </div>

            <div className="flex gap-3 p-6 border-t border-border flex-shrink-0">
              <button onClick={closeModal} className="flex-1 px-4 py-2.5 rounded-lg border border-border bg-card text-foreground hover:bg-muted transition-colors">
                取消
              </button>
              <button
                onClick={handleSave}
                disabled={!editForm.name.trim() || isBusy}
                className="flex-1 px-4 py-2.5 rounded-lg bg-gradient-to-r from-[#5b5ff9] to-[#8b5ff9] text-white hover:shadow-md transition-all flex items-center justify-center gap-2 disabled:opacity-50"
              >
                {isBusy ? <Loader2 className="w-4 h-4 animate-spin" /> : <Check className="w-4 h-4" />}
                保存
              </button>
            </div>
          </div>
        </div>
      )}
      <ImagePreviewModal
        src={previewImage?.src ?? null}
        title={previewImage?.title}
        alt={previewImage?.title}
        onClose={() => setPreviewImage(null)}
      />
    </div>
  );
}
