import { useState, type ChangeEvent, type MouseEvent } from "react";
import { useNavigate } from "react-router";
import {
  AlertCircle,
  ArrowRight,
  FileText,
  Image as ImageIcon,
  Loader2,
  Sparkles,
  Upload,
  X,
} from "lucide-react";
import { Progress } from "../components/ui/progress";
import { useCreateProject } from "../../hooks/useProjects";
import { projectsApi } from "../../lib/api/projects";
import { aspectRatioOptions, projectStyleOptions, resolutionOptions } from "../../lib/projectStyles";

type SubmitStage = "idle" | "creating" | "uploading" | "redirecting";

const submitStageMeta: Record<
  Exclude<SubmitStage, "idle">,
  { title: string; description: string; progress: number }
> = {
  creating: {
    title: "正在创建项目",
    description: "项目基础信息正在写入，请稍候。",
    progress: 28,
  },
  uploading: {
    title: "正在上传素材",
    description: "如果你上传了剧本或封面，系统会先完成上传再进入大纲页。",
    progress: 72,
  },
  redirecting: {
    title: "准备进入剧本大纲",
    description: "马上跳转到“生成剧本大纲”，可以继续解析已上传剧本，或手动输入内容。",
    progress: 96,
  },
};

export function NewProject() {
  const navigate = useNavigate();
  const [projectName, setProjectName] = useState("");
  const [scriptFile, setScriptFile] = useState<File | null>(null);
  const [coverFile, setCoverFile] = useState<File | null>(null);
  const [coverPreview, setCoverPreview] = useState<string | null>(null);
  const [aspectRatio, setAspectRatio] = useState(aspectRatioOptions[0].value);
  const [resolution, setResolution] = useState(resolutionOptions[0].value);
  const [style, setStyle] = useState(projectStyleOptions[0].value);
  const [submitStage, setSubmitStage] = useState<SubmitStage>("idle");
  const [submitError, setSubmitError] = useState<string | null>(null);
  const createProject = useCreateProject();

  const isSubmitting = submitStage !== "idle";
  const hasUpload = !!scriptFile || !!coverFile;

  const handleScriptChange = (e: ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files?.[0] || isSubmitting) return;

    const file = e.target.files[0];
    setScriptFile(file);

    if (!projectName.trim()) {
      setProjectName(file.name.replace(/\.[^/.]+$/, ""));
    }
  };

  const handleCoverChange = (e: ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files?.[0] || isSubmitting) return;

    const file = e.target.files[0];
    setCoverFile(file);
    setCoverPreview((prev) => {
      if (prev) URL.revokeObjectURL(prev);
      return URL.createObjectURL(file);
    });
  };

  const removeCover = (e: MouseEvent) => {
    e.preventDefault();
    if (isSubmitting) return;

    setCoverFile(null);
    if (coverPreview) URL.revokeObjectURL(coverPreview);
    setCoverPreview(null);
  };

  const handleSubmit = async () => {
    if (isSubmitting) return;

    const name =
      projectName.trim() ||
      (scriptFile ? scriptFile.name.replace(/\.[^/.]+$/, "") : "新短剧项目");

    try {
      setSubmitError(null);
      setSubmitStage("creating");

      const project = await createProject.mutateAsync({
        name,
        style,
        aspectRatio,
        resolution,
      });

      if (hasUpload) {
        setSubmitStage("uploading");

        await Promise.all([
          scriptFile ? projectsApi.uploadAsset(project.id, scriptFile, "script") : Promise.resolve(),
          coverFile ? projectsApi.uploadAsset(project.id, coverFile, "cover") : Promise.resolve(),
        ]);
      }

      setSubmitStage("redirecting");

      navigate(`/project/${project.id}/outline`, {
        state: {
          fromNewProject: true,
          projectName: name,
          aspectRatio,
          resolution,
          style,
        },
      });
    } catch (error) {
      setSubmitStage("idle");
      setSubmitError((error as Error)?.message ?? "创建项目失败，请重试");
    }
  };

  const canSubmit = !isSubmitting;
  const activeSubmitMeta = submitStage === "idle" ? null : submitStageMeta[submitStage];

  return (
    <div className="relative h-full overflow-auto bg-background">
      {activeSubmitMeta && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-background/80 p-6 backdrop-blur-sm">
          <div className="w-full max-w-md rounded-2xl border border-border bg-card p-6 shadow-2xl">
            <div className="mb-5 flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br from-[#5b5ff9] to-[#8b5ff9]">
              <Loader2 className="h-7 w-7 animate-spin text-white" />
            </div>
            <h2 className="mb-2 text-xl font-semibold text-foreground">{activeSubmitMeta.title}</h2>
            <p className="mb-5 text-sm leading-relaxed text-muted-foreground">
              {activeSubmitMeta.description}
            </p>
            <Progress value={activeSubmitMeta.progress} className="mb-4 h-2.5" />
            <div className="space-y-2 text-sm">
              <div className="flex items-center justify-between text-foreground">
                <span>创建项目</span>
                <span>{submitStage === "creating" ? "进行中" : "已准备"}</span>
              </div>
              <div className="flex items-center justify-between text-foreground">
                <span>上传素材</span>
                <span>
                  {!hasUpload
                    ? "已跳过"
                    : submitStage === "uploading"
                      ? "进行中"
                      : submitStage === "redirecting"
                        ? "已完成"
                        : "等待中"}
                </span>
              </div>
              <div className="flex items-center justify-between text-foreground">
                <span>进入大纲页</span>
                <span>{submitStage === "redirecting" ? "进行中" : "等待中"}</span>
              </div>
            </div>
            <p className="mt-4 text-xs text-muted-foreground">
              处理中已锁定按钮，避免重复点击创建多个项目。
            </p>
          </div>
        </div>
      )}

      <div className="mx-auto max-w-4xl p-8">
        <div className="mb-8 text-center">
          <h1 className="mb-2 text-3xl font-semibold text-foreground">创建短剧项目</h1>
          <p className="text-sm text-muted-foreground">
            可以先上传剧本直接进入解析流程，也可以跳过上传，在下一页手动输入内容生成大纲。
          </p>
        </div>

        {submitError && (
          <div className="mb-5 flex items-start gap-3 rounded-xl border border-red-200 bg-red-50 p-4">
            <AlertCircle className="mt-0.5 h-5 w-5 flex-shrink-0 text-red-500" />
            <p className="text-sm text-red-700">{submitError}</p>
          </div>
        )}

        <div className="mb-5">
          <label className="mb-2 block text-sm font-medium text-foreground">项目名称</label>
          <input
            type="text"
            value={projectName}
            onChange={(e) => setProjectName(e.target.value)}
            disabled={isSubmitting}
            placeholder="输入项目名称，或上传剧本后自动带入文件名"
            className="w-full rounded-xl border border-border bg-card px-4 py-3 text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 disabled:cursor-not-allowed disabled:opacity-60"
          />
        </div>

        <div className="mb-6 flex gap-4">
          <div className="flex-shrink-0">
            <label className="mb-2 block text-sm font-medium text-foreground">
              封面图片
              <span className="ml-1 font-normal text-muted-foreground">（可选）</span>
            </label>
            <div className="relative flex h-40 w-28 items-center justify-center overflow-hidden rounded-xl border-2 border-dashed border-border bg-card">
              <input
                type="file"
                accept="image/*"
                onChange={handleCoverChange}
                disabled={isSubmitting}
                className="absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed"
              />
              {coverPreview ? (
                <>
                  <img src={coverPreview} alt="封面预览" className="h-full w-full object-cover" />
                  <button
                    onClick={removeCover}
                    disabled={isSubmitting}
                    className="absolute right-1 top-1 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-black/60 transition-colors hover:bg-black/80 disabled:opacity-50"
                  >
                    <X className="h-3 w-3 text-white" />
                  </button>
                </>
              ) : (
                <div className="p-2 text-center">
                  <ImageIcon className="mx-auto mb-1 h-6 w-6 text-muted-foreground" />
                  <span className="text-xs text-muted-foreground">点击上传</span>
                </div>
              )}
            </div>
          </div>

          <div className="flex-1">
            <label className="mb-2 block text-sm font-medium text-foreground">
              剧本文件
              <span className="ml-1 font-normal text-muted-foreground">（可选）</span>
            </label>
            <div className="relative flex h-40 items-center justify-center rounded-xl border-2 border-dashed border-border bg-card">
              <input
                type="file"
                accept=".txt,.doc,.docx,.pdf,.md"
                onChange={handleScriptChange}
                disabled={isSubmitting}
                className="absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed"
              />
              {scriptFile ? (
                <div className="flex flex-col items-center gap-3">
                  <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-[#5b5ff9] to-[#8b5ff9]">
                    <FileText className="h-6 w-6 text-white" />
                  </div>
                  <div className="text-center">
                    <div className="mb-0.5 text-sm font-medium text-foreground">{scriptFile.name}</div>
                    <div className="text-xs text-muted-foreground">
                      {(scriptFile.size / 1024).toFixed(1)} KB
                    </div>
                  </div>
                  <button
                    onClick={(e) => {
                      e.preventDefault();
                      if (!isSubmitting) setScriptFile(null);
                    }}
                    disabled={isSubmitting}
                    className="text-xs text-primary hover:underline disabled:no-underline disabled:opacity-50"
                  >
                    重新上传
                  </button>
                </div>
              ) : (
                <div className="flex flex-col items-center gap-3">
                  <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-muted">
                    <Upload className="h-6 w-6 text-muted-foreground" />
                  </div>
                  <div className="text-center">
                    <div className="mb-0.5 text-sm text-foreground">点击或拖拽剧本文件到这里</div>
                    <div className="text-xs text-muted-foreground">
                      支持 doc、docx、txt、pdf、md，大小不超过 20M；也可以先跳过，下一页手动输入剧本。
                    </div>
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>

        <div className="mb-6 grid grid-cols-3 gap-4">
          <div className="rounded-xl border border-border bg-card p-4">
            <div className="mb-2 text-xs text-muted-foreground">画幅比例</div>
            <select
              value={aspectRatio}
              onChange={(e) => setAspectRatio(e.target.value)}
              disabled={isSubmitting}
              className="w-full cursor-pointer rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 disabled:cursor-not-allowed disabled:opacity-60"
            >
              {aspectRatioOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label} · {option.helper}
                </option>
              ))}
            </select>
          </div>

          <div className="rounded-xl border border-border bg-card p-4">
            <div className="mb-2 text-xs text-muted-foreground">清晰度</div>
            <select
              value={resolution}
              onChange={(e) => setResolution(e.target.value)}
              disabled={isSubmitting}
              className="w-full cursor-pointer rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 disabled:cursor-not-allowed disabled:opacity-60"
            >
              {resolutionOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label} · {option.helper}
                </option>
              ))}
            </select>
          </div>

          <div className="rounded-xl border border-border bg-card p-4">
            <div className="mb-2 text-xs text-muted-foreground">视觉风格</div>
            <select
              value={style}
              onChange={(e) => setStyle(e.target.value)}
              disabled={isSubmitting}
              className="w-full cursor-pointer rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 disabled:cursor-not-allowed disabled:opacity-60"
            >
              {projectStyleOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </div>
        </div>

        <div className="mb-6 rounded-xl border border-primary/20 bg-accent/50 p-4">
          <div className="flex items-start gap-3">
            <div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-primary/10">
              <Sparkles className="h-5 w-5 text-primary" />
            </div>
            <div>
              <h3 className="mb-1 text-sm font-medium text-foreground">AI 智能处理</h3>
              <p className="text-sm leading-relaxed text-muted-foreground">
                如果上传了剧本，下一页会继续自动解析；如果没有上传，也可以直接手动输入剧本内容生成大纲。这里选择的视觉风格会继续影响后续人物与场景的 AI 生成效果。
              </p>
            </div>
          </div>
        </div>

        <button
          onClick={handleSubmit}
          disabled={!canSubmit}
          className="flex w-full items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-[#5b5ff9] to-[#8b5ff9] py-3 text-white transition-all hover:shadow-md disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:shadow-none"
        >
          <span>{isSubmitting ? activeSubmitMeta?.title ?? "处理中..." : "创建新短剧项目"}</span>
          {isSubmitting ? <Loader2 className="h-5 w-5 animate-spin" /> : <ArrowRight className="h-5 w-5" />}
        </button>
      </div>
    </div>
  );
}
