import { useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
  getGitRepos,
  importGitRepos,
  updateGitRepoDeploy,
  deleteGitRepo,
  githubGetToken,
  githubListRepos,
  type GitRepo,
  type UpdateGitRepoDeployInput,
} from "../../lib/commands";
import { useUIStore } from "../../store/ui";

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

type Tab = "registry" | "sync";

// ── 部署信息编辑表单 ──────────────────────────────────────────────────────────

function DeployForm({
  repo,
  onSaved,
  onCancel,
}: {
  repo: GitRepo;
  onSaved: () => void;
  onCancel: () => void;
}) {
  const showToast = useUIStore((s) => s.showToast);
  const qc = useQueryClient();
  const [form, setForm] = useState<UpdateGitRepoDeployInput>({
    staging_url: repo.staging_url ?? "",
    prod_url: repo.prod_url ?? "",
    server_note: repo.server_note ?? "",
    upstream_url: repo.upstream_url ?? "",
    tech_stack: repo.tech_stack ?? "",
    status: repo.status ?? "active",
    priority: repo.priority ?? "mid",
  });
  const [saving, setSaving] = useState(false);

  const set = (k: keyof UpdateGitRepoDeployInput) =>
    (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) =>
      setForm((f) => ({ ...f, [k]: e.target.value }));

  const handleSave = async () => {
    setSaving(true);
    try {
      await updateGitRepoDeploy(repo.id, form);
      qc.invalidateQueries({ queryKey: ["git-repos"] });
      showToast("已保存 ✓");
      onSaved();
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally {
      setSaving(false);
    }
  };

  const inputCls = "w-full border border-gray-200 rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-blue-200";

  return (
    <div className="border-t border-blue-100 px-4 py-4 space-y-3 bg-blue-50/30">
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">生产环境 URL</label>
          <input className={inputCls} value={form.prod_url ?? ""} onChange={set("prod_url")} placeholder="https://example.com" />
        </div>
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">预发 / 测试 URL</label>
          <input className={inputCls} value={form.staging_url ?? ""} onChange={set("staging_url")} placeholder="https://staging.example.com" />
        </div>
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">公司上游仓库</label>
          <input className={inputCls} value={form.upstream_url ?? ""} onChange={set("upstream_url")} placeholder="https://github.com/company/repo.git" />
        </div>
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">技术栈</label>
          <input className={inputCls} value={form.tech_stack ?? ""} onChange={set("tech_stack")} placeholder="React / Rust / Node" />
        </div>
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">状态</label>
          <select className={inputCls} value={form.status ?? "active"} onChange={set("status")}>
            <option value="active">进行中</option>
            <option value="paused">暂停</option>
            <option value="archived">归档</option>
          </select>
        </div>
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">优先级</label>
          <select className={inputCls} value={form.priority ?? "mid"} onChange={set("priority")}>
            <option value="high">高</option>
            <option value="mid">中</option>
            <option value="low">低</option>
          </select>
        </div>
      </div>
      <div>
        <label className="block text-xs font-medium text-gray-500 mb-1">服务器备注</label>
        <textarea
          className={`${inputCls} resize-none`}
          rows={2}
          value={form.server_note ?? ""}
          onChange={set("server_note")}
          placeholder="服务器地址、SSH Key 路径…"
        />
      </div>
      <div className="flex justify-end gap-2">
        <button onClick={onCancel} className="px-3 py-1.5 text-xs border border-gray-200 rounded-lg text-gray-500 hover:bg-gray-50">取消</button>
        <button
          onClick={handleSave}
          disabled={saving}
          className="px-3 py-1.5 text-xs bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
        >
          {saving ? "保存中…" : "保存"}
        </button>
      </div>
    </div>
  );
}

// ── 已注册仓库列表 ────────────────────────────────────────────────────────────

function RegistryTab() {
  const showToast = useUIStore((s) => s.showToast);
  const qc = useQueryClient();
  const [expandedId, setExpandedId] = useState<string | null>(null);

  const { data: repos = [], isLoading } = useQuery({
    queryKey: ["git-repos"],
    queryFn: getGitRepos,
  });

  const handleDelete = async (id: string, name: string) => {
    if (!confirm(`确定删除仓库「${name}」？关联的工作区也会被删除。`)) return;
    try {
      await deleteGitRepo(id);
      qc.invalidateQueries({ queryKey: ["git-repos"] });
      qc.invalidateQueries({ queryKey: ["projects"] });
      showToast("已删除");
    } catch (e) {
      showToast(`❌ ${e}`);
    }
  };

  if (isLoading) {
    return <div className="flex-1 flex items-center justify-center text-gray-400 text-sm">加载中…</div>;
  }

  if (repos.length === 0) {
    return (
      <div className="flex-1 flex flex-col items-center justify-center text-gray-400 py-16 gap-2">
        <p className="text-2xl">📦</p>
        <p className="text-sm">还没有注册仓库，切换到「从 GitHub 同步」标签页导入</p>
      </div>
    );
  }

  return (
    <div className="flex-1 overflow-y-auto min-h-0">
      {repos.map((repo) => {
        const isExpanded = expandedId === repo.id;
        return (
          <div key={repo.id} className="border-b border-gray-100 last:border-0">
            <div className="flex items-center gap-3 px-4 py-3 hover:bg-gray-50 transition-colors">
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2 flex-wrap">
                  <span className="text-sm font-medium text-gray-800">{repo.name}</span>
                  {repo.tech_stack && <span className="text-xs text-gray-400">{repo.tech_stack}</span>}
                  {repo.default_branch && (
                    <span className="px-1.5 py-0.5 rounded text-xs bg-gray-100 text-gray-500 font-mono">{repo.default_branch}</span>
                  )}
                  {repo.status && repo.status !== "active" && (
                    <span className={`text-xs px-1.5 py-0.5 rounded ${repo.status === "archived" ? "bg-gray-100 text-gray-400" : "bg-yellow-50 text-yellow-600"}`}>
                      {repo.status === "archived" ? "已归档" : "暂停"}
                    </span>
                  )}
                </div>
                <p className="text-xs text-gray-400 truncate mt-0.5 font-mono">{repo.repo_url}</p>
                {(repo.prod_url || repo.staging_url) && (
                  <div className="flex gap-3 mt-1">
                    {repo.prod_url && <span className="text-xs text-green-600 truncate">生产: {repo.prod_url}</span>}
                    {repo.staging_url && <span className="text-xs text-blue-500 truncate">预发: {repo.staging_url}</span>}
                  </div>
                )}
              </div>
              <div className="flex gap-1.5 shrink-0">
                <button
                  onClick={() => setExpandedId(isExpanded ? null : repo.id)}
                  className={`px-2.5 py-1.5 rounded-lg text-xs border transition-colors ${
                    isExpanded
                      ? "border-blue-300 bg-blue-50 text-blue-700"
                      : "border-gray-200 text-gray-500 hover:bg-gray-50"
                  }`}
                >
                  {isExpanded ? "收起" : "部署信息"}
                </button>
                <button
                  onClick={() => handleDelete(repo.id, repo.name)}
                  className="px-2.5 py-1.5 rounded-lg text-xs border border-gray-200 text-red-400 hover:bg-red-50 hover:border-red-200 transition-colors"
                >
                  删除
                </button>
              </div>
            </div>
            {isExpanded && (
              <DeployForm
                repo={repo}
                onSaved={() => setExpandedId(null)}
                onCancel={() => setExpandedId(null)}
              />
            )}
          </div>
        );
      })}
    </div>
  );
}

// ── 从 GitHub 同步标签 ───────────────────────────────────────────────────────

function SyncTab() {
  const showToast = useUIStore((s) => s.showToast);
  const qc = useQueryClient();
  const [search, setSearch] = useState("");
  const [selected, setSelected] = useState<Set<number>>(new Set());
  const [importing, setImporting] = useState(false);

  const { data: repos = [], isLoading, error } = useQuery({
    queryKey: ["github-repos"],
    queryFn: async () => {
      const token = await githubGetToken();
      if (!token) throw new Error("未登录 GitHub");
      return githubListRepos(token);
    },
  });

  const { data: existingRepos = [] } = useQuery({
    queryKey: ["git-repos"],
    queryFn: getGitRepos,
  });

  const existingUrls = new Set(existingRepos.map((r) => r.repo_url));

  const filtered = repos.filter(
    (r) =>
      r.name.toLowerCase().includes(search.toLowerCase()) ||
      r.full_name.toLowerCase().includes(search.toLowerCase())
  );

  const toggleSelect = (id: number) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const selectAll = () => {
    const newRepos = filtered.filter((r) => !existingUrls.has(r.clone_url));
    setSelected(new Set(newRepos.map((r) => r.id)));
  };

  const handleImport = async () => {
    const toImport = repos.filter((r) => selected.has(r.id));
    if (toImport.length === 0) return;
    setImporting(true);
    try {
      const inputs = toImport.map((r) => ({
        id: crypto.randomUUID(),
        repo_url: r.clone_url,
        name: r.name,
        description: r.description,
        default_branch: r.default_branch,
      }));
      const imported = await importGitRepos(inputs);
      qc.invalidateQueries({ queryKey: ["git-repos"] });
      setSelected(new Set());
      showToast(`已导入 ${imported.length} 个仓库 ✓`);
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally {
      setImporting(false);
    }
  };

  if (isLoading) return <div className="flex-1 flex items-center justify-center text-gray-400 text-sm">加载 GitHub 仓库…</div>;
  if (error) return <div className="flex-1 flex items-center justify-center text-red-400 text-sm p-6">{String(error)}</div>;

  return (
    <>
      <div className="px-4 py-3 border-b border-gray-100 flex gap-2">
        <input
          type="text"
          placeholder="搜索仓库…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="flex-1 border border-gray-200 text-sm rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-200"
        />
        <button onClick={selectAll} className="px-3 py-2 text-xs border border-gray-200 rounded-lg text-gray-500 hover:bg-gray-50 shrink-0">
          全选未导入
        </button>
        <button
          onClick={handleImport}
          disabled={selected.size === 0 || importing}
          className="px-3 py-2 text-xs bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 shrink-0"
        >
          {importing ? "导入中…" : `导入 ${selected.size} 个`}
        </button>
      </div>

      <div className="flex-1 overflow-y-auto min-h-0">
        {filtered.map((repo) => {
          const alreadyImported = existingUrls.has(repo.clone_url);
          const isSelected = selected.has(repo.id);
          return (
            <button
              key={repo.id}
              onClick={() => !alreadyImported && toggleSelect(repo.id)}
              disabled={alreadyImported}
              className={`w-full text-left px-4 py-3 border-b border-gray-100 transition-colors flex items-center gap-3 ${
                alreadyImported
                  ? "opacity-40 cursor-not-allowed"
                  : isSelected
                  ? "bg-blue-50"
                  : "hover:bg-gray-50"
              }`}
            >
              <div className={`w-4 h-4 rounded border flex items-center justify-center shrink-0 ${
                alreadyImported ? "border-gray-200 bg-gray-100" :
                isSelected ? "border-blue-500 bg-blue-500" : "border-gray-300"
              }`}>
                {(isSelected || alreadyImported) && (
                  <svg className="w-2.5 h-2.5 text-white" viewBox="0 0 16 16" fill="currentColor">
                    <path d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/>
                  </svg>
                )}
              </div>
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-gray-800">{repo.name}</span>
                  {repo.private && <span className="text-xs px-1.5 py-0.5 bg-gray-100 text-gray-500 rounded">私有</span>}
                  {alreadyImported && <span className="text-xs px-1.5 py-0.5 bg-green-100 text-green-600 rounded">已注册</span>}
                  <span className="text-xs text-gray-400 ml-auto font-mono">{repo.default_branch}</span>
                </div>
                {repo.description && <p className="text-xs text-gray-400 mt-0.5 truncate">{repo.description}</p>}
              </div>
            </button>
          );
        })}
        {filtered.length === 0 && (
          <div className="text-center text-gray-400 text-sm py-8">没有找到匹配的仓库</div>
        )}
      </div>
    </>
  );
}

// ── 主模态框 ──────────────────────────────────────────────────────────────────

export function RepoRegistryModal({ onClose }: Props) {
  const [tab, setTab] = useState<Tab>("registry");

  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-[700px] 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">
          <h2 className="text-base font-semibold text-gray-800">仓库管理</h2>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-xl leading-none">×</button>
        </div>

        <div className="border-b border-gray-100 px-5 flex">
          {([
            { id: "registry" as Tab, label: "已注册仓库" },
            { id: "sync" as Tab, label: "从 GitHub 同步" },
          ]).map(({ id, label }) => (
            <button
              key={id}
              onClick={() => setTab(id)}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                tab === id
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-500 hover:text-gray-700"
              }`}
            >
              {label}
            </button>
          ))}
        </div>

        <div className="flex flex-col flex-1 min-h-0">
          {tab === "registry" ? <RegistryTab /> : <SyncTab />}
        </div>
      </div>
    </div>
  );
}
