import { useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import {
  scanLocalGit, githubCreateRepo, gitInitAndCommit,
  gitRemoteSet, gitPushToGithub, registerAndLinkRepo,
  type GitScanResult, type Project,
} from "../../lib/commands";
import { useUIStore } from "../../store/ui";

interface Props {
  project: Project;
  onClose: () => void;
}

type Step = "scan" | "config" | "executing" | "done";

interface ExecLog {
  label: string;
  status: "pending" | "ok" | "error";
  detail?: string;
}

const GITIGNORE_TEMPLATES: Record<string, string> = {
  Node: `node_modules/\ndist/\n.next/\n.nuxt/\n*.log\n.env\n.env.*\n!.env.example\n`,
  Rust: `target/\nCargo.lock\n*.pdb\n`,
  Python: `__pycache__/\n*.py[cod]\n.venv/\nvenv/\n*.egg-info/\ndist/\n.env\n`,
  Go: `*.exe\n*.test\n*.out\nvendor/\n`,
  Java: `target/\n*.class\n*.jar\n.gradle/\nbuild/\n`,
  VisualStudio: `bin/\nobj/\n*.user\n*.suo\n.vs/\n`,
};

export function PublishModal({ project, onClose }: Props) {
  const showToast = useUIStore((s) => s.showToast);
  const qc = useQueryClient();

  const localPath = project.platform === "wsl" ? project.wsl_path : project.win_path;

  const [step, setStep] = useState<Step>("scan");
  const [scan, setScan] = useState<GitScanResult | null>(null);
  const [scanning, setScanning] = useState(false);
  const [scanError, setScanError] = useState("");

  // 配置表单
  const [repoName, setRepoName] = useState(
    project.name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "")
  );
  const [repoDesc, setRepoDesc] = useState(project.description ?? "");
  const [isPrivate, setIsPrivate] = useState(false);
  const [branch, setBranch] = useState("main");
  const [commitMsg, setCommitMsg] = useState("Initial commit");
  const [confirmedSensitive, setConfirmedSensitive] = useState(false);
  const [selectedTemplates, setSelectedTemplates] = useState<string[]>([]);

  // 执行日志
  const [logs, setLogs] = useState<ExecLog[]>([]);

  // ── 工具 ──────────────────────────────────────────────────────────────────

  const updateLog = (index: number, status: ExecLog["status"], detail?: string) => {
    setLogs((prev) => prev.map((l, i) => i === index ? { ...l, status, detail } : l));
  };

  // ── 步骤1：扫描 ──────────────────────────────────────────────────────────

  const handleScan = async () => {
    if (!localPath) { showToast("❌ 项目没有配置本地路径"); return; }
    setScanning(true);
    try {
      const result = await scanLocalGit(localPath);
      setScan(result);
      // 预选推荐模板
      setSelectedTemplates(result.suggested_templates);
      // 若已有分支名则使用
      if (result.branch) setBranch(result.branch);
      setStep("config");
    } catch (e) {
      setScanError(String(e));
    } finally {
      setScanning(false);
    }
  };

  // ── 步骤2 → 步骤3：执行 ─────────────────────────────────────────────────

  const buildSteps = (): ExecLog[] => {
    if (!scan) return [];
    const steps: ExecLog[] = [];
    const needInit = !scan.has_git || !scan.has_commits;
    const needGitignore = !scan.has_gitignore && selectedTemplates.length > 0;
    if (needGitignore) steps.push({ label: "生成 .gitignore", status: "pending" });
    steps.push({ label: "在 GitHub 创建远端仓库", status: "pending" });
    if (needInit) {
      steps.push({ label: `初始化并提交代码（${commitMsg}）`, status: "pending" });
    }
    steps.push({ label: "配置 origin remote", status: "pending" });
    steps.push({ label: `推送到 GitHub (${branch})`, status: "pending" });
    steps.push({ label: "注册到本地仓库", status: "pending" });
    return steps;
  };

  const handleExecute = async () => {
    if (!scan || !localPath) return;
    if (scan.suspicious_files.length > 0 && !confirmedSensitive) {
      showToast("❌ 请确认敏感文件处理后再继续");
      return;
    }

    const initialLogs = buildSteps();
    setLogs(initialLogs);
    setStep("executing");

    let logIdx = 0;
    let cloneUrl = "";

    try {
      // 1. 生成 .gitignore
      if (!scan.has_gitignore && selectedTemplates.length > 0) {
        updateLog(logIdx, "pending", "写入中…");
        const content = selectedTemplates
          .map((t) => `# ${t}\n${GITIGNORE_TEMPLATES[t] ?? ""}`)
          .join("\n");
        const { invoke } = await import("@tauri-apps/api/core");
        await invoke("write_gitignore", { dir: localPath, content });
        updateLog(logIdx++, "ok");
      }

      // 2. 创建 GitHub 仓库
      updateLog(logIdx, "pending", "调用 GitHub API…");
      cloneUrl = await githubCreateRepo(repoName, repoDesc, isPrivate);
      updateLog(logIdx++, "ok", cloneUrl);

      // 3. 全新项目：git init + 提交所有文件
      const needCommit = !scan.has_git || !scan.has_commits;
      if (needCommit) {
        updateLog(logIdx, "pending", "git add & commit…");
        await gitInitAndCommit(localPath, commitMsg);
        updateLog(logIdx++, "ok");
      }

      // 4. 配置 remote
      updateLog(logIdx, "pending", "git remote set…");
      await gitRemoteSet(localPath, cloneUrl);
      updateLog(logIdx++, "ok");

      // 5. Push
      updateLog(logIdx, "pending", `git push origin ${branch}…`);
      await gitPushToGithub(localPath, branch);
      updateLog(logIdx++, "ok");

      // 6. 注册本地仓库 + 关联
      updateLog(logIdx, "pending", "写入本地仓库注册表…");
      await registerAndLinkRepo(
        project.id,
        cloneUrl,
        repoName,
        repoDesc || undefined,
        branch,
      );
      updateLog(logIdx++, "ok");

      qc.invalidateQueries({ queryKey: ["projects"] });
      qc.invalidateQueries({ queryKey: ["git-repos"] });
      setStep("done");
    } catch (e) {
      updateLog(logIdx, "error", String(e));
    }
  };

  // ── 渲染 ─────────────────────────────────────────────────────────────────

  const hasRemoteConflict = scan?.remotes.some(
    (r) => r.name === "origin" && !r.url.includes(repoName)
  );

  return (
    <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50">
      <div className="bg-white rounded-xl shadow-2xl w-[580px] max-h-[85vh] flex flex-col border border-gray-200">

        {/* 标题 */}
        <div className="px-5 py-4 border-b border-gray-100 flex items-center justify-between shrink-0">
          <div>
            <h2 className="text-base font-semibold text-gray-800">发布到 GitHub</h2>
            <p className="text-xs text-gray-400 mt-0.5">{project.name}</p>
          </div>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-xl leading-none">×</button>
        </div>

        <div className="flex-1 overflow-y-auto min-h-0 px-5 py-4 space-y-4">

          {/* ── 步骤1：扫描 ── */}
          {step === "scan" && (
            <div className="flex flex-col items-center justify-center py-10 gap-4">
              <p className="text-2xl">🔍</p>
              <p className="text-sm text-gray-600 text-center">
                点击扫描，检测本地项目 git 状态、敏感文件与技术栈
              </p>
              <p className="text-xs text-gray-400 font-mono bg-gray-50 px-3 py-1.5 rounded-lg">{localPath}</p>
              <button
                onClick={() => { setScanError(""); handleScan(); }}
                disabled={scanning}
                className="px-6 py-2 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700 disabled:opacity-50"
              >
                {scanning ? "扫描中…" : "开始扫描"}
              </button>
              {scanError && (
                <div className="w-full bg-red-50 border border-red-200 rounded-lg px-4 py-3 text-xs space-y-2">
                  <p className="font-semibold text-red-600">扫描失败</p>
                  <pre className="text-red-700 whitespace-pre-wrap break-all font-mono leading-relaxed">{scanError}</pre>
                  <button
                    onClick={() => navigator.clipboard.writeText(scanError).then(() => showToast("已复制 ✓"))}
                    className="px-3 py-1 rounded border border-red-200 text-red-500 hover:bg-red-100 text-xs"
                  >
                    复制错误信息
                  </button>
                </div>
              )}
            </div>
          )}

          {/* ── 步骤2：配置 ── */}
          {step === "config" && scan && (
            <>
              {/* 扫描结果摘要 */}
              <div className="bg-gray-50 rounded-lg px-4 py-3 text-xs space-y-1.5">
                <p className="font-semibold text-gray-600 mb-2">扫描结果</p>
                <div className="grid grid-cols-2 gap-x-4 gap-y-1">
                  <span className="text-gray-500">Git 仓库</span>
                  <span className={scan.has_git ? "text-green-600" : "text-orange-500"}>
                    {scan.has_git ? "✓ 已初始化" : "✗ 未初始化，将自动 init"}
                  </span>
                  <span className="text-gray-500">提交记录</span>
                  <span className={scan.has_commits ? "text-green-600" : "text-orange-500"}>
                    {scan.has_commits ? "✓ 有历史提交" : "✗ 无提交，将自动提交"}
                  </span>
                  <span className="text-gray-500">未提交改动</span>
                  <span className={scan.has_changes ? "text-orange-500" : "text-green-600"}>
                    {scan.has_changes ? `⚠ ${scan.changed_files.length} 个文件` : "✓ 工作区干净"}
                  </span>
                  <span className="text-gray-500">.gitignore</span>
                  <span className={scan.has_gitignore ? "text-green-600" : "text-orange-500"}>
                    {scan.has_gitignore ? "✓ 已存在" : "✗ 不存在"}
                  </span>
                  {scan.remotes.length > 0 && (
                    <>
                      <span className="text-gray-500">现有 remote</span>
                      <span className="text-gray-700 font-mono truncate">{scan.remotes[0].url}</span>
                    </>
                  )}
                </div>
              </div>

              {/* Remote 冲突警告 */}
              {hasRemoteConflict && (
                <div className="bg-red-50 border border-red-200 rounded-lg px-4 py-3 text-xs text-red-700">
                  ⚠ 当前 origin 指向不同地址，继续将覆盖 remote 配置，请确认。
                </div>
              )}

              {/* 敏感文件警告 */}
              {scan.suspicious_files.length > 0 && (
                <div className="bg-red-50 border border-red-200 rounded-lg px-4 py-3 text-xs space-y-2">
                  <p className="font-semibold text-red-700">🚨 检测到疑似敏感文件</p>
                  <ul className="space-y-0.5">
                    {scan.suspicious_files.map((f) => (
                      <li key={f} className="font-mono text-red-600">• {f}</li>
                    ))}
                  </ul>
                  <p className="text-red-500">请确认已将上述文件加入 .gitignore 或删除，否则将推送到公开仓库。</p>
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={confirmedSensitive}
                      onChange={(e) => setConfirmedSensitive(e.target.checked)}
                    />
                    <span className="text-red-700 font-medium">我已确认，这些文件不包含敏感信息</span>
                  </label>
                </div>
              )}

              {/* .gitignore 模板 */}
              {!scan.has_gitignore && scan.suggested_templates.length > 0 && (
                <div className="border border-gray-200 rounded-lg px-4 py-3 text-xs space-y-2">
                  <p className="font-semibold text-gray-600">自动生成 .gitignore（推荐）</p>
                  <div className="flex flex-wrap gap-2">
                    {scan.suggested_templates.map((t) => (
                      <label key={t} className="flex items-center gap-1.5 cursor-pointer">
                        <input
                          type="checkbox"
                          checked={selectedTemplates.includes(t)}
                          onChange={(e) =>
                            setSelectedTemplates((prev) =>
                              e.target.checked ? [...prev, t] : prev.filter((x) => x !== t)
                            )
                          }
                        />
                        <span>{t}</span>
                      </label>
                    ))}
                  </div>
                </div>
              )}

              {/* 未提交内容：阻断发布 */}
              {scan.has_changes && (
                <div className="bg-orange-50 border border-orange-200 rounded-lg px-4 py-3 text-xs space-y-2">
                  <p className="font-semibold text-orange-700">
                    ⚠ 存在 {scan.changed_files.length} 个未提交文件，请先提交后再发布
                  </p>
                  <div className="max-h-28 overflow-y-auto space-y-0.5">
                    {scan.changed_files.slice(0, 50).map((f, i) => (
                      <div key={i} className="flex items-center gap-2 font-mono text-gray-500">
                        <span className={`w-4 font-bold ${
                          f.status === "?" ? "text-green-500" :
                          f.status === "D" ? "text-red-500" : "text-yellow-500"
                        }`}>{f.status}</span>
                        <span className="truncate">{f.path}</span>
                      </div>
                    ))}
                    {scan.changed_files.length > 50 && (
                      <p className="text-gray-400">…还有 {scan.changed_files.length - 50} 个文件</p>
                    )}
                  </div>
                  <p className="text-orange-600">
                    请在 <span className="font-semibold">VSCode</span> 或 <span className="font-semibold">Claude</span> 中完成提交，然后重新扫描。
                  </p>
                </div>
              )}

              {/* 全新项目提示（无 git / 无提交记录，但工作区干净） */}
              {!scan.has_changes && (!scan.has_git || !scan.has_commits) && (
                <div className="border border-blue-100 bg-blue-50 rounded-lg px-4 py-3 text-xs space-y-2">
                  <p className="font-semibold text-blue-700">
                    {!scan.has_git ? "全新项目：将自动执行 git init 并提交所有文件" : "尚无提交记录：将自动提交当前所有文件"}
                  </p>
                  <div>
                    <label className="block text-blue-600 mb-1">初始 Commit 信息</label>
                    <input
                      className="w-full border border-blue-200 rounded-lg px-3 py-1.5 text-sm outline-none focus:ring-2 focus:ring-blue-200 bg-white"
                      value={commitMsg}
                      onChange={(e) => setCommitMsg(e.target.value)}
                    />
                  </div>
                </div>
              )}

              {/* GitHub 仓库配置 */}
              <div className="border border-gray-200 rounded-lg px-4 py-3 space-y-3">
                <p className="text-xs font-semibold text-gray-600">GitHub 仓库设置</p>
                <div className="grid grid-cols-2 gap-3 text-xs">
                  <div className="col-span-2">
                    <label className="block text-gray-500 mb-1">仓库名称</label>
                    <input
                      className="w-full border border-gray-200 rounded-lg px-3 py-1.5 text-sm font-mono outline-none focus:ring-2 focus:ring-blue-200"
                      value={repoName}
                      onChange={(e) => setRepoName(e.target.value)}
                    />
                  </div>
                  <div className="col-span-2">
                    <label className="block text-gray-500 mb-1">描述（可选）</label>
                    <input
                      className="w-full border border-gray-200 rounded-lg px-3 py-1.5 text-sm outline-none focus:ring-2 focus:ring-blue-200"
                      value={repoDesc}
                      onChange={(e) => setRepoDesc(e.target.value)}
                    />
                  </div>
                  <div>
                    <label className="block text-gray-500 mb-1">默认分支</label>
                    <input
                      className="w-full border border-gray-200 rounded-lg px-3 py-1.5 text-sm font-mono outline-none focus:ring-2 focus:ring-blue-200"
                      value={branch}
                      onChange={(e) => setBranch(e.target.value)}
                    />
                  </div>
                  <div className="flex items-end pb-1">
                    <label className="flex items-center gap-2 cursor-pointer text-sm text-gray-600">
                      <input
                        type="checkbox"
                        checked={isPrivate}
                        onChange={(e) => setIsPrivate(e.target.checked)}
                      />
                      私有仓库
                    </label>
                  </div>
                </div>
              </div>
            </>
          )}

          {/* ── 步骤3：执行进度 ── */}
          {(step === "executing" || step === "done") && (
            <div className="space-y-2">
              {logs.map((log, i) => (
                <div key={i} className="flex items-start gap-3 text-sm">
                  <span className="shrink-0 mt-0.5">
                    {log.status === "pending" && <span className="text-blue-400 animate-pulse">⏳</span>}
                    {log.status === "ok"      && <span className="text-green-500">✓</span>}
                    {log.status === "error"   && <span className="text-red-500">✗</span>}
                  </span>
                  <div className="flex-1 min-w-0">
                    <span className={log.status === "error" ? "text-red-600" : "text-gray-700"}>
                      {log.label}
                    </span>
                    {log.detail && (
                      <p className="text-xs text-gray-400 font-mono truncate mt-0.5">{log.detail}</p>
                    )}
                  </div>
                </div>
              ))}
              {step === "done" && (
                <div className="mt-4 bg-green-50 border border-green-200 rounded-lg px-4 py-3 text-sm text-green-700 text-center">
                  🎉 发布完成！三灯已全绿
                </div>
              )}
            </div>
          )}
        </div>

        {/* 底部按钮 */}
        <div className="flex justify-end gap-3 px-5 py-3 border-t border-gray-100 shrink-0">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm border border-gray-200 rounded-lg text-gray-600 hover:bg-gray-50"
          >
            {step === "done" ? "关闭" : "取消"}
          </button>
          {step === "config" && (
            <button
              onClick={handleExecute}
              disabled={
                !repoName.trim() ||
                !scan ||
                scan.has_changes ||
                (scan.suspicious_files.length > 0 && !confirmedSensitive)
              }
              className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
            >
              开始发布
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
