import { useRef, useState, type ChangeEvent } from "react";
import { useNavigate, useParams } from "react-router";
import { ArrowRight, Sparkles, Plus, Edit2, Users, MapPin, Box, Trash2, X, Check, RefreshCw, ImageIcon, Loader2, Upload } from "lucide-react";
import { useScenes, useExtractScenes, useGenerateSceneImage, useDeleteScene, useSaveScene, useUploadSceneImage } from "../../hooks/useAi";
import type { Scene } from "../../lib/api/ai";
import { ImagePreviewModal } from "../components/ImagePreviewModal";

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

const emptyForm = (): Partial<Scene> => ({
  name: "", sceneType: "indoor", description: "", imagePrompt: "",
});

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

export function SceneGeneration() {
  const navigate = useNavigate();
  const { projectId } = useParams();
  const pid = projectId ?? "";

  const { data: scenes = [], isLoading } = useScenes(pid);
  const extract = useExtractScenes(pid);
  const saveScene = useSaveScene(pid);
  const generateImage = useGenerateSceneImage(pid);
  const uploadImage = useUploadSceneImage(pid);
  const deleteScene = useDeleteScene(pid);

  const [activeTab] = useState<SettingsTab>("scenes");
  const [generatingImageId, setGeneratingImageId] = useState<string | null>(null);

  // modal state
  const [showModal, setShowModal] = useState(false);
  const [editingScene, setEditingScene] = useState<Partial<Scene>>(emptyForm());
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [pendingFile, setPendingFile] = useState<File | null>(null);
  const [saving, setSaving] = useState(false);
  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 handleExtract = () => {
    extract.mutate(undefined, { onError: (e) => alert("提取失败: " + (e as Error).message) });
  };

  const openCreate = () => {
    revokeObjectPreview(imagePreview);
    setEditingScene(emptyForm());
    setImagePreview(null);
    setPendingFile(null);
    if (fileInputRef.current) fileInputRef.current.value = "";
    setShowModal(true);
  };

  const openEdit = (scene: Scene) => {
    revokeObjectPreview(imagePreview);
    setEditingScene({ ...scene });
    setImagePreview(scene.imageUrl ?? null);
    setPendingFile(null);
    if (fileInputRef.current) fileInputRef.current.value = "";
    setShowModal(true);
  };

  const closeModal = () => {
    revokeObjectPreview(imagePreview);
    setShowModal(false);
    setPendingFile(null);
    if (fileInputRef.current) fileInputRef.current.value = "";
  };

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

  const clearSelectedImage = () => {
    revokeObjectPreview(imagePreview);
    setPendingFile(null);
    setImagePreview(editingScene.imageUrl ?? null);
    if (fileInputRef.current) fileInputRef.current.value = "";
  };

  const handleSave = async () => {
    if (!editingScene.name?.trim()) return;
    setSaving(true);
    try {
      const saved = await saveScene.mutateAsync({ ...editingScene, status: editingScene.status ?? "draft" });
      if (pendingFile) {
        await uploadImage.mutateAsync({ id: String(saved.id), file: pendingFile });
      }
      closeModal();
    } catch (e) {
      alert("保存失败: " + (e as Error).message);
    } finally {
      setSaving(false);
    }
  };

  const handleGenerateImage = (scene: Scene) => {
    setGeneratingImageId(scene.id);
    generateImage.mutate(scene.id, {
      onSettled: () => setGeneratingImageId(null),
      onError: (e) => alert("图片生成失败: " + (e as Error).message),
    });
  };

  const handleDelete = (scene: Scene) => {
    if (!confirm(`确定要删除场景「${scene.name}」吗？`)) return;
    deleteScene.mutate(scene.id, { onError: (e) => alert("删除失败: " + (e as Error).message) });
  };

  const statusBadge = (status: string) => {
    if (status === "ready") return <span className="px-1.5 py-0.5 rounded text-xs bg-green-500/10 text-green-600">已生成</span>;
    if (status === "generating") return <span className="px-1.5 py-0.5 rounded text-xs bg-blue-500/10 text-blue-600 flex items-center gap-1"><Loader2 className="w-3 h-3 animate-spin" />生成中</span>;
    if (status === "failed") return <span className="px-1.5 py-0.5 rounded text-xs bg-red-500/10 text-red-600">失败</span>;
    return <span className="px-1.5 py-0.5 rounded text-xs bg-yellow-500/10 text-yellow-600">待生成</span>;
  };

  return (
    <div className="h-full overflow-auto bg-background relative">
      <div className="p-6 pb-24">
        <div className="max-w-7xl mx-auto">
          {/* Header */}
          <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>

          {/* Settings Navigation Tabs */}
          <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={() => 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>
            <div className="flex items-center gap-2">
              <button
                onClick={openCreate}
                className="px-4 py-2 rounded-lg border border-border bg-card text-foreground hover:bg-muted transition-all flex items-center gap-2 text-sm"
              >
                <Plus className="w-4 h-4" />
                手动添加
              </button>
              <button
                onClick={handleExtract}
                disabled={extract.isPending}
                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 disabled:opacity-60"
              >
                {extract.isPending ? <Loader2 className="w-4 h-4 animate-spin" /> : <Sparkles className="w-4 h-4" />}
                AI提取场景
              </button>
            </div>
          </div>

          {/* Statistics */}
          <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">{scenes.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">
                  {scenes.filter(s => s.status === "ready").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-foreground">
                  {scenes.filter(s => s.sceneType === "indoor").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-foreground">
                  {scenes.filter(s => s.sceneType === "outdoor").length}
                </span>
              </div>
            </div>
          </div>

          {/* Empty State */}
          {!isLoading && scenes.length === 0 && (
            <div className="rounded-xl border border-dashed border-border bg-card p-12 text-center">
              <MapPin className="w-12 h-12 text-muted-foreground mx-auto mb-4" />
              <h3 className="text-lg font-medium text-foreground mb-2">暂无场景</h3>
              <p className="text-sm text-muted-foreground mb-6">手动添加场景，或点击「AI提取场景」从大纲和分集自动提取主要场景</p>
              <div className="flex items-center justify-center gap-3">
                <button
                  onClick={openCreate}
                  className="px-5 py-2.5 rounded-lg border border-border bg-card text-foreground hover:bg-muted transition-all flex items-center gap-2"
                >
                  <Plus className="w-4 h-4" />
                  手动添加
                </button>
                <button
                  onClick={handleExtract}
                  disabled={extract.isPending}
                  className="px-6 py-2.5 rounded-lg bg-gradient-to-r from-[#5b5ff9] to-[#8b5ff9] text-white hover:shadow-md transition-all flex items-center gap-2 disabled:opacity-60"
                >
                  {extract.isPending ? <Loader2 className="w-4 h-4 animate-spin" /> : <Sparkles className="w-4 h-4" />}
                  AI提取场景
                </button>
              </div>
            </div>
          )}

          {isLoading && (
            <div className="flex items-center justify-center py-16">
              <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
            </div>
          )}

          {/* Scene Grid */}
          {scenes.length > 0 && (
            <div className="grid grid-cols-3 gap-4 mb-8">
              {scenes.map((scene) => (
                <div key={scene.id} className="rounded-xl border border-border bg-card overflow-hidden group">
                  {/* Image */}
                  <div className="aspect-video relative overflow-hidden bg-muted">
                    {scene.imageUrl ? (
                      <button
                        type="button"
                        onClick={() => setPreviewImage({ src: scene.imageUrl!, title: scene.name })}
                        className="block h-full w-full cursor-zoom-in"
                      >
                        <img src={scene.imageUrl} alt={scene.name} className="w-full h-full object-cover" />
                      </button>
                    ) : (
                      <div className="w-full h-full flex flex-col items-center justify-center gap-2">
                        {scene.status === "generating" ? (
                          <Loader2 className="w-8 h-8 text-primary animate-spin" />
                        ) : (
                          <ImageIcon className="w-8 h-8 text-muted-foreground" />
                        )}
                      </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-2 ${
                        scene.imageUrl ? "cursor-zoom-in" : ""
                      }`}
                      onClick={() => {
                        if (scene.imageUrl) setPreviewImage({ src: scene.imageUrl, title: scene.name });
                      }}
                    >
                      {scene.imageUrl && (
                        <button
                          type="button"
                          onClick={(event) => {
                            event.stopPropagation();
                            setPreviewImage({ src: scene.imageUrl!, title: scene.name });
                          }}
                          className="p-2 rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30 transition-colors"
                          title="查看大图"
                        >
                          <ImageIcon className="w-5 h-5 text-white" />
                        </button>
                      )}
                      <button
                        onClick={(event) => {
                          event.stopPropagation();
                          handleGenerateImage(scene);
                        }}
                        disabled={generatingImageId === scene.id || scene.status === "generating"}
                        className="p-2 rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30 transition-colors disabled:opacity-50"
                        title="AI重新生成"
                      >
                        <RefreshCw className={`w-5 h-5 text-white ${generatingImageId === scene.id ? "animate-spin" : ""}`} />
                      </button>
                    </div>
                    <div className="absolute top-2 right-2 px-2 py-1 rounded-md bg-card/90 backdrop-blur-sm text-xs text-foreground border border-border">
                      {scene.sceneType === "indoor" ? "室内" : "室外"}
                    </div>
                    <div className="absolute top-2 left-2">
                      {statusBadge(scene.status)}
                    </div>
                  </div>

                  {/* Info */}
                  <div className="p-4">
                    <div className="flex items-center justify-between mb-2">
                      <div className="flex items-center gap-2 min-w-0">
                        <MapPin className="w-4 h-4 text-primary flex-shrink-0" />
                        <h3 className="font-medium text-foreground truncate">{scene.name}</h3>
                      </div>
                      <div className="flex items-center gap-1 flex-shrink-0">
                        <button
                          onClick={() => openEdit(scene)}
                          className="p-1 rounded hover:bg-muted transition-colors"
                        >
                          <Edit2 className="w-3.5 h-3.5 text-muted-foreground" />
                        </button>
                        <button
                          onClick={() => handleDelete(scene)}
                          className="p-1 rounded hover:bg-destructive/10 transition-colors"
                        >
                          <Trash2 className="w-3.5 h-3.5 text-destructive" />
                        </button>
                      </div>
                    </div>
                    <p className="text-sm text-muted-foreground mb-2 line-clamp-2">{scene.description}</p>
                    {!scene.imageUrl && scene.status !== "generating" && (
                      <button
                        onClick={() => handleGenerateImage(scene)}
                        disabled={generatingImageId === scene.id}
                        className="w-full mt-1 px-3 py-1.5 rounded-md border border-border bg-card text-foreground hover:bg-muted transition-colors text-xs flex items-center justify-center gap-1.5 disabled:opacity-50"
                      >
                        <Sparkles className="w-3 h-3" />
                        生成场景图片
                      </button>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* Floating Bottom Bar */}
      <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-[#5b5ff9] to-[#8b5ff9] text-white hover:shadow-md transition-all flex items-center gap-2 text-sm font-medium"
          >
            <span>前往分镜工作台</span>
            <ArrowRight className="w-5 h-5" />
          </button>
        </div>
      </div>

      {/* Add/Edit Scene Modal */}
      {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">
            {/* Modal Header */}
            <div className="flex items-center justify-between p-6 border-b border-border flex-shrink-0">
              <h2 className="text-lg font-semibold text-foreground">
                {editingScene.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>

            {/* Modal Body */}
            <div className="overflow-auto p-6 space-y-4 flex-1">
              {/* Image Upload */}
              <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">可以上传自己的场景参考图，保存后会覆盖当前场景图。</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 && (
                  <button
                    type="button"
                    onClick={() => fileInputRef.current?.click()}
                    className="mt-2 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>
                )}
                <input ref={fileInputRef} type="file" accept="image/*" className="hidden" onChange={handleFileSelect} />
              </div>

              {/* Name */}
              <div>
                <label className="block text-sm font-medium text-foreground mb-1">场景名称 <span className="text-destructive">*</span></label>
                <input
                  type="text"
                  value={editingScene.name ?? ""}
                  onChange={(e) => setEditingScene({ ...editingScene, 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>

              {/* Scene Type */}
              <div>
                <label className="block text-sm font-medium text-foreground mb-1">场景类型</label>
                <select
                  value={editingScene.sceneType ?? "indoor"}
                  onChange={(e) => setEditingScene({ ...editingScene, sceneType: 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"
                >
                  <option value="indoor">室内</option>
                  <option value="outdoor">室外</option>
                </select>
              </div>

              {/* Description */}
              <div>
                <label className="block text-sm font-medium text-foreground mb-1">场景描述</label>
                <textarea
                  value={editingScene.description ?? ""}
                  onChange={(e) => setEditingScene({ ...editingScene, description: e.target.value })}
                  placeholder="描述场景的环境、氛围、陈设等"
                  rows={3}
                  className="w-full px-3 py-2 rounded-lg border border-border bg-background text-foreground placeholder-muted-foreground resize-none focus:outline-none focus:ring-2 focus:ring-primary/20"
                />
              </div>

              <div>
                <label className="block text-sm font-medium text-foreground mb-1">图片 Prompt</label>
                <textarea
                  value={editingScene.imagePrompt ?? ""}
                  onChange={(e) => setEditingScene({ ...editingScene, imagePrompt: e.target.value })}
                  placeholder="用于 AI 生成场景图的提示词；留空时会根据场景名称和描述自动补全"
                  rows={4}
                  className="w-full px-3 py-2 rounded-lg border border-border bg-background text-foreground placeholder-muted-foreground resize-none focus:outline-none focus:ring-2 focus:ring-primary/20"
                />
                <p className="mt-1 text-xs text-muted-foreground">
                  修改这里才会更新生成场景图片时真正使用的提示词
                </p>
              </div>
            </div>

            {/* Modal Footer */}
            <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={!editingScene.name?.trim() || saving || uploadImage.isPending}
                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"
              >
                {saving || uploadImage.isPending ? <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>
  );
}
