// CI/CD 部署配置与运行管理
// 完整部署教程与踩坑指南见 docs/tauri-cicd-guide.md
// 涵盖：签名密钥、Workflow 模板、OSS 上传、Tauri v2 更新格式等
// 运行历史/手动触发（原 GitHub Actions API）已随 GitHub 退役移除，待 Gitea Actions 接入后重建
import { useState, useEffect } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  getCicdConfig,
  saveCicdConfig,
  generateWorkflow,
  resolveWslPath,
  type CicdConfig,
} from "../../lib/commands";
import { useUIStore } from "../../store/ui";

interface Props {
  projectId: string;
  projectName: string;
  winPath?: string;
  wslPath?: string;
  platform?: string;
  onClose: () => void;
}

const DEFAULT_CONFIG: Omit<CicdConfig, "id" | "project_id" | "created_at"> = {
  config_type: "web_ssh",
  trigger_branch: "main",
  build_command: "pnpm build",
  node_version: "20",
  server_host: "",
  server_user: "ubuntu",
  deploy_path: "/app/project",
  start_command: "pm2 restart app",
  oss_endpoint: "oss-cn-hangzhou.aliyuncs.com",
};

export function CicdModal({
  projectId,
  projectName,
  winPath,
  wslPath,
  platform,
  onClose,
}: Props) {
  const queryClient = useQueryClient();
  const showToast = useUIStore((s) => s.showToast);
  const [form, setForm] = useState<Omit<CicdConfig, "id" | "project_id" | "created_at">>({
    ...DEFAULT_CONFIG,
    config_type: platform === "windows" ? "tauri_oss" : "web_ssh",
  });
  const [generatedSecrets, setGeneratedSecrets] = useState<string[] | null>(null);
  const [generating, setGenerating] = useState(false);

  // 加载已保存配置
  const { data: saved } = useQuery<CicdConfig | null>({
    queryKey: ["cicdConfig", projectId],
    queryFn: () => getCicdConfig(projectId),
  });

  useEffect(() => {
    if (saved) {
      setForm({
        config_type: saved.config_type,
        trigger_branch: saved.trigger_branch,
        build_command: saved.build_command ?? DEFAULT_CONFIG.build_command,
        node_version: saved.node_version ?? DEFAULT_CONFIG.node_version,
        server_host: saved.server_host ?? "",
        server_user: saved.server_user ?? DEFAULT_CONFIG.server_user,
        deploy_path: saved.deploy_path ?? DEFAULT_CONFIG.deploy_path,
        start_command: saved.start_command ?? DEFAULT_CONFIG.start_command,
        oss_endpoint: saved.oss_endpoint ?? DEFAULT_CONFIG.oss_endpoint,
      });
    }
  }, [saved]);

  const saveMutation = useMutation({
    mutationFn: () =>
      saveCicdConfig({
        id: saved?.id ?? "",
        project_id: projectId,
        ...form,
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["cicdConfig", projectId] });
      showToast("配置已保存");
    },
    onError: (e) => showToast(`保存失败: ${e}`),
  });

  async function handleGenerate() {
    setGenerating(true);
    setGeneratedSecrets(null);
    try {
      // 优先 win_path，WSL 项目则转换 wsl_path → UNC 路径
      let projectPath = winPath;
      if (!projectPath && wslPath) {
        projectPath = await resolveWslPath(wslPath);
      }
      if (!projectPath) {
        showToast("项目路径未配置，无法生成 workflow 文件");
        return;
      }
      const result = await generateWorkflow(projectId, projectPath);
      setGeneratedSecrets(result.secrets);
      showToast(`✅ 已生成 ${result.path}`);
    } catch (e) {
      showToast(`生成失败: ${e}`);
    } finally {
      setGenerating(false);
    }
  }

  const isWebSsh = form.config_type === "web_ssh";
  const hasSavedConfig = !!saved?.id;
  const hasPath = !!(winPath || wslPath);

  return (
    <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50">
      <div className="bg-zinc-900 rounded-xl shadow-2xl w-[600px] max-h-[85vh] flex flex-col border border-zinc-700">
        {/* 标题 */}
        <div className="px-5 py-4 border-b border-zinc-700 flex items-center justify-between">
          <div>
            <h2 className="text-base font-semibold text-white">CI/CD 控制台</h2>
            <p className="text-xs text-zinc-400 mt-0.5">{projectName}</p>
          </div>
          <button onClick={onClose} className="text-zinc-400 hover:text-white text-xl leading-none">
            ×
          </button>
        </div>

        <div className="flex-1 overflow-y-auto min-h-0 p-4">
          <div className="space-y-4">
              {/* 类型选择 */}
              <div>
                <label className="text-xs text-zinc-400 mb-1 block">部署类型</label>
                <div className="flex gap-2">
                  {[
                    { value: "web_ssh", label: "Web 项目（SSH 部署）", desc: "WSL / Linux 服务器" },
                    { value: "tauri_oss", label: "桌面客户端（OSS 分发）", desc: "Tauri / Windows 安装包" },
                  ].map((opt) => (
                    <button
                      key={opt.value}
                      onClick={() => setForm((f) => ({ ...f, config_type: opt.value }))}
                      className={`flex-1 rounded-lg px-3 py-2.5 text-left border transition-colors ${
                        form.config_type === opt.value
                          ? "border-blue-500 bg-blue-500/10"
                          : "border-zinc-700 bg-zinc-800 hover:border-zinc-500"
                      }`}
                    >
                      <p className="text-sm text-white font-medium">{opt.label}</p>
                      <p className="text-xs text-zinc-400 mt-0.5">{opt.desc}</p>
                    </button>
                  ))}
                </div>
              </div>

              {/* 公共字段 */}
              <div className="grid grid-cols-2 gap-3">
                <Field
                  label="触发分支"
                  value={form.trigger_branch}
                  onChange={(v) => setForm((f) => ({ ...f, trigger_branch: v }))}
                  placeholder="main"
                />
                <Field
                  label="Node.js 版本"
                  value={form.node_version ?? ""}
                  onChange={(v) => setForm((f) => ({ ...f, node_version: v }))}
                  placeholder="20"
                />
              </div>
              <Field
                label="构建命令"
                value={form.build_command ?? ""}
                onChange={(v) => setForm((f) => ({ ...f, build_command: v }))}
                placeholder="pnpm build"
                mono
              />

              {/* web_ssh 专属字段 */}
              {isWebSsh && (
                <>
                  <div className="grid grid-cols-2 gap-3">
                    <Field
                      label="服务器地址"
                      value={form.server_host ?? ""}
                      onChange={(v) => setForm((f) => ({ ...f, server_host: v }))}
                      placeholder="your-server.com"
                      hint="仅用于生成 workflow，实际通过 Secrets 注入"
                    />
                    <Field
                      label="SSH 用户名"
                      value={form.server_user ?? ""}
                      onChange={(v) => setForm((f) => ({ ...f, server_user: v }))}
                      placeholder="ubuntu"
                    />
                  </div>
                  <Field
                    label="部署路径（服务器上）"
                    value={form.deploy_path ?? ""}
                    onChange={(v) => setForm((f) => ({ ...f, deploy_path: v }))}
                    placeholder="/app/my-project"
                    mono
                  />
                  <Field
                    label="启动命令（服务器上）"
                    value={form.start_command ?? ""}
                    onChange={(v) => setForm((f) => ({ ...f, start_command: v }))}
                    placeholder="pm2 restart app"
                    mono
                  />
                </>
              )}

              {/* tauri_oss 专属字段 */}
              {!isWebSsh && (
                <Field
                  label="阿里云 OSS Endpoint"
                  value={form.oss_endpoint ?? ""}
                  onChange={(v) => setForm((f) => ({ ...f, oss_endpoint: v }))}
                  placeholder="oss-cn-hangzhou.aliyuncs.com"
                  hint="触发方式：push tag（v1.0.0）"
                  mono
                />
              )}

              {/* 操作按钮 */}
              <div className="flex gap-2 pt-1">
                <button
                  onClick={() => saveMutation.mutate()}
                  disabled={saveMutation.isPending}
                  className="px-4 py-2 bg-blue-600 hover:bg-blue-500 disabled:opacity-50 text-white text-sm rounded-lg transition-colors"
                >
                  {saveMutation.isPending ? "保存中…" : "保存配置"}
                </button>
                <button
                  onClick={handleGenerate}
                  disabled={!hasSavedConfig || !hasPath || generating}
                  title={
                    !hasSavedConfig
                      ? "请先保存配置"
                      : !hasPath
                      ? "项目未配置本地路径"
                      : ""
                  }
                  className="px-4 py-2 bg-emerald-700 hover:bg-emerald-600 disabled:opacity-40 text-white text-sm rounded-lg transition-colors"
                >
                  {generating ? "生成中…" : "生成 Workflow 文件"}
                </button>
              </div>

              {/* Secrets 清单 */}
              {generatedSecrets && (
                <div className="bg-zinc-800 rounded-lg p-3 space-y-2">
                  <p className="text-xs font-medium text-zinc-300">
                    ✅ Workflow 已生成（.gitea/workflows/），请在 Gitea 仓库设置以下 Secrets：
                  </p>
                  <p className="text-xs text-zinc-500">
                    仓库 Settings → Actions → Secrets → Add Secret
                  </p>
                  <div className="flex flex-wrap gap-1.5 mt-1">
                    {generatedSecrets.map((s) => (
                      <code
                        key={s}
                        className="bg-zinc-900 text-amber-300 text-xs px-2 py-0.5 rounded font-mono"
                      >
                        {s}
                      </code>
                    ))}
                  </div>
                  {isWebSsh && (
                    <p className="text-xs text-zinc-500 mt-1">
                      SSH_KEY：服务器私钥内容（cat ~/.ssh/id_rsa）
                    </p>
                  )}
                </div>
              )}
            </div>
        </div>
      </div>
    </div>
  );
}

// ── 通用输入框组件 ─────────────────────────────────────────────────────────────

function Field({
  label,
  value,
  onChange,
  placeholder,
  hint,
  mono,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
  hint?: string;
  mono?: boolean;
}) {
  return (
    <div>
      <label className="text-xs text-zinc-400 mb-1 block">{label}</label>
      {hint && <p className="text-xs text-zinc-500 mb-1">{hint}</p>}
      <input
        type="text"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={placeholder}
        className={`w-full bg-zinc-800 text-white text-sm rounded-lg px-3 py-2 outline-none focus:ring-1 focus:ring-blue-500 placeholder:text-zinc-600 ${
          mono ? "font-mono" : ""
        }`}
      />
    </div>
  );
}
