import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  getProjectServerLinks, getServers, linkServer, unlinkServer,
  type ProjectServerLink, type QuickLink,
} from "../../lib/commands";

function CopyBtn({ value }: { value: string }) {
  const [copied, setCopied] = useState(false);
  const handleCopy = async () => {
    await navigator.clipboard.writeText(value);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };
  return (
    <button onClick={handleCopy}
      className="shrink-0 px-1.5 py-0.5 rounded text-[11px] border border-gray-200 text-gray-400 hover:text-blue-500 hover:border-blue-300 hover:bg-blue-50 transition-colors">
      {copied ? "已复制" : "复制"}
    </button>
  );
}

function buildSshCmd(link: ProjectServerLink): string {
  const port = link.server_port && link.server_port !== "22" ? ` -p ${link.server_port}` : "";
  const key = link.ssh_key_path ? ` -i ${link.ssh_key_path}` : "";
  const user = link.username ? `${link.username}@` : "";
  return `ssh ${user}${link.server_host}${port}${key}`;
}

function buildDeployKeyCmd(link: ProjectServerLink): string {
  const keyPub = link.ssh_key_path
    ? link.ssh_key_path.replace(/(?:\.pub)?$/, ".pub")
    : "%USERPROFILE%\\.ssh\\id_ed25519.pub";
  const portFlag = link.server_port && link.server_port !== "22" ? ` -p ${link.server_port}` : "";
  const user = link.username ? `${link.username}@` : "";
  return `type ${keyPub} | ssh${portFlag} ${user}${link.server_host} "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"`;
}

// ── 已关联服务器条目 ────────────────────────────────────────────────────────

function LinkedServerItem({ link, projectId }: { link: ProjectServerLink; projectId: string }) {
  const qc = useQueryClient();
  const [showPwd, setShowPwd] = useState(false);

  const unlinkMut = useMutation({
    mutationFn: () => unlinkServer(projectId, link.server_id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["project-servers", projectId] });
      qc.invalidateQueries({ queryKey: ["server-projects", link.server_id] });
    },
  });

  const sshCmd = buildSshCmd(link);
  const links: QuickLink[] = (() => {
    try { return link.quick_links ? JSON.parse(link.quick_links) : []; } catch { return []; }
  })();

  return (
    <div className="bg-gray-50 border border-gray-100 rounded-lg px-3 py-2.5 space-y-1.5">
      {/* 标题行 */}
      <div className="flex items-center gap-2">
        <span className="text-xs font-semibold text-gray-700">{link.server_name}</span>
        <span className="text-[11px] text-gray-400 font-mono">{link.server_host}</span>
        {link.role && (
          <span className="text-[10px] px-1.5 py-0.5 rounded-full bg-purple-50 text-purple-600 border border-purple-100 font-medium">
            {link.role}
          </span>
        )}
        <button onClick={() => unlinkMut.mutate()}
          className="ml-auto text-[11px] text-gray-300 hover:text-red-400 transition-colors">
          取消关联
        </button>
      </div>

      {/* 信息行 */}
      <div className="flex flex-wrap gap-x-4 gap-y-1.5 text-[11px]">
        {link.deploy_type && (
          <div className="flex items-center gap-1">
            <span className={`px-1.5 py-0.5 rounded-full font-medium border ${
              link.deploy_type === "docker"
                ? "bg-sky-50 text-sky-600 border-sky-200"
                : "bg-emerald-50 text-emerald-600 border-emerald-200"
            }`}>
              {link.deploy_type === "docker" ? "Docker" : "裸机"}
            </span>
          </div>
        )}
        {link.username && (
          <div className="flex items-center gap-1">
            <span className="text-gray-400">用户:</span>
            <span className="font-mono text-gray-600">{link.username}</span>
            <CopyBtn value={link.username} />
          </div>
        )}
        {link.password && (
          <div className="flex items-center gap-1">
            <span className="text-gray-400">密码:</span>
            <span className="font-mono text-gray-600">{showPwd ? link.password : "••••"}</span>
            <button onClick={() => setShowPwd((v) => !v)}
              className="px-1 py-0.5 rounded text-[10px] border border-gray-200 text-gray-400 hover:text-gray-600 transition-colors">
              {showPwd ? "隐藏" : "显示"}
            </button>
            <CopyBtn value={link.password} />
          </div>
        )}
        {link.deploy_path && (
          <div className="flex items-center gap-1">
            <span className="text-gray-400">{link.deploy_type === "docker" ? "Compose:" : "路径:"}</span>
            <span className="font-mono text-gray-600">{link.deploy_path}</span>
            <CopyBtn value={link.deploy_path} />
          </div>
        )}
        {link.container_name && (
          <div className="flex items-center gap-1">
            <span className="text-gray-400">容器:</span>
            <span className="font-mono text-gray-600">{link.container_name}</span>
            <CopyBtn value={link.container_name} />
          </div>
        )}
        {link.start_command && (
          <div className="flex items-center gap-1">
            <span className="text-gray-400">启动:</span>
            <span className="font-mono text-gray-600">{link.start_command}</span>
            <CopyBtn value={link.start_command} />
          </div>
        )}
      </div>

      {/* SSH 命令 */}
      <div className="flex items-center gap-2 px-2.5 py-1.5 bg-gray-800 rounded-md">
        <span className="text-[11px] text-green-400 font-mono flex-1 truncate">$ {sshCmd}</span>
        <CopyBtn value={sshCmd} />
      </div>

      {/* 部署公钥命令 */}
      <details className="group">
        <summary className="text-[11px] text-gray-400 cursor-pointer hover:text-gray-600 transition-colors select-none flex items-center gap-1">
          <span className="text-gray-300 group-open:rotate-90 transition-transform inline-block">&#9654;</span>
          部署公钥（CMD）
        </summary>
        <div className="mt-1 flex items-start gap-2 px-2.5 py-1.5 bg-amber-950 rounded-md">
          <span className="text-[10px] text-amber-300 font-mono flex-1 break-all leading-relaxed">
            &gt; {buildDeployKeyCmd(link)}
          </span>
          <CopyBtn value={buildDeployKeyCmd(link)} />
        </div>
      </details>

      {/* 快速链接 */}
      {links.length > 0 && (
        <div className="flex flex-wrap gap-2">
          {links.map((l, i) => (
            <div key={i} className="flex items-center gap-1">
              <a href={l.url} target="_blank" rel="noopener noreferrer"
                className="text-[11px] text-blue-500 hover:text-blue-700 hover:underline transition-colors">
                {l.label || l.url}
              </a>
              <CopyBtn value={l.url} />
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── 关联选择器 ──────────────────────────────────────────────────────────────

function LinkSelector({ projectId, linkedIds }: { projectId: string; linkedIds: Set<string> }) {
  const qc = useQueryClient();
  const [selectedServerId, setSelectedServerId] = useState("");
  const [role, setRole] = useState("production");
  const [deployType, setDeployType] = useState<"bare" | "docker">("bare");
  const [deployPath, setDeployPath] = useState("");
  const [containerName, setContainerName] = useState("");
  const [startCommand, setStartCommand] = useState("");

  const { data: allServers = [] } = useQuery({
    queryKey: ["servers"],
    queryFn: getServers,
    staleTime: 30000,
  });

  const available = allServers.filter((s) => !linkedIds.has(s.id));

  const linkMut = useMutation({
    mutationFn: () => linkServer(projectId, selectedServerId, {
      role: role || undefined,
      deploy_type: deployType,
      deploy_path: deployPath || undefined,
      container_name: containerName || undefined,
      start_command: startCommand || undefined,
    }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["project-servers", projectId] });
      qc.invalidateQueries({ queryKey: ["server-projects", selectedServerId] });
      setSelectedServerId("");
      setRole("production");
      setDeployType("bare");
      setDeployPath("");
      setContainerName("");
      setStartCommand("");
    },
  });

  if (available.length === 0) {
    return (
      <p className="text-[11px] text-gray-300 text-center py-1">
        {allServers.length === 0 ? "请先在「服务器」Tab 中添加服务器" : "所有服务器已关联"}
      </p>
    );
  }

  const inputCls = "text-xs px-2.5 py-2 rounded-md border border-gray-200 bg-white focus:outline-none focus:border-blue-300 focus:ring-1 focus:ring-blue-100";

  return (
    <div className="bg-gray-50 border border-gray-100 rounded-lg p-4 space-y-3">
      {/* 第一行：服务器 + 角色 + 部署方式 */}
      <div className="grid grid-cols-3 gap-3">
        <div className="flex flex-col gap-1">
          <label className="text-[11px] text-gray-400 font-medium">服务器</label>
          <select value={selectedServerId} onChange={(e) => setSelectedServerId(e.target.value)} className={inputCls}>
            <option value="">选择服务器…</option>
            {available.map((s) => (
              <option key={s.id} value={s.id}>{s.name} ({s.server_host})</option>
            ))}
          </select>
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[11px] text-gray-400 font-medium">角色</label>
          <select value={role} onChange={(e) => setRole(e.target.value)} className={inputCls}>
            <option value="production">production</option>
            <option value="staging">staging</option>
            <option value="development">development</option>
          </select>
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[11px] text-gray-400 font-medium">部署方式</label>
          <div className="flex rounded-md border border-gray-200 overflow-hidden h-[34px]">
            <button
              onClick={() => setDeployType("bare")}
              className={`flex-1 text-xs font-medium transition-colors ${
                deployType === "bare" ? "bg-emerald-50 text-emerald-700 border-r border-gray-200" : "bg-white text-gray-400 border-r border-gray-200 hover:bg-gray-50"
              }`}
            >
              裸机
            </button>
            <button
              onClick={() => setDeployType("docker")}
              className={`flex-1 text-xs font-medium transition-colors ${
                deployType === "docker" ? "bg-sky-50 text-sky-700" : "bg-white text-gray-400 hover:bg-gray-50"
              }`}
            >
              Docker
            </button>
          </div>
        </div>
      </div>

      {/* 第二行：根据部署类型显示不同字段 */}
      <div className="grid grid-cols-2 gap-3">
        {deployType === "bare" ? (
          <>
            <div className="flex flex-col gap-1">
              <label className="text-[11px] text-gray-400 font-medium">部署路径</label>
              <input value={deployPath} onChange={(e) => setDeployPath(e.target.value)}
                placeholder="/var/www/app" className={inputCls} />
            </div>
            <div className="flex flex-col gap-1">
              <label className="text-[11px] text-gray-400 font-medium">启动/重启命令</label>
              <input value={startCommand} onChange={(e) => setStartCommand(e.target.value)}
                placeholder="pm2 restart app" className={inputCls} />
            </div>
          </>
        ) : (
          <>
            <div className="flex flex-col gap-1">
              <label className="text-[11px] text-gray-400 font-medium">容器/服务名</label>
              <input value={containerName} onChange={(e) => setContainerName(e.target.value)}
                placeholder="my-app" className={inputCls} />
            </div>
            <div className="flex flex-col gap-1">
              <label className="text-[11px] text-gray-400 font-medium">Compose 路径</label>
              <input value={deployPath} onChange={(e) => setDeployPath(e.target.value)}
                placeholder="/opt/docker/compose.yml" className={inputCls} />
            </div>
          </>
        )}
      </div>

      {/* Docker 额外行：启动命令 */}
      {deployType === "docker" && (
        <div className="flex flex-col gap-1">
          <label className="text-[11px] text-gray-400 font-medium">启动命令</label>
          <input value={startCommand} onChange={(e) => setStartCommand(e.target.value)}
            placeholder="docker compose up -d" className={inputCls} />
        </div>
      )}

      <div className="flex justify-end">
        <button onClick={() => linkMut.mutate()} disabled={!selectedServerId || linkMut.isPending}
          className="px-4 py-1.5 rounded-md text-xs font-medium border border-blue-300 bg-blue-50 text-blue-600 hover:bg-blue-100 transition-colors disabled:opacity-50">
          关联服务器
        </button>
      </div>
    </div>
  );
}

// ── 主面板（嵌入 ProjectCard） ──────────────────────────────────────────────

export function ProjectServerPanel({ projectId }: { projectId: string }) {
  const [showLink, setShowLink] = useState(false);

  const { data: links = [] } = useQuery({
    queryKey: ["project-servers", projectId],
    queryFn: () => getProjectServerLinks(projectId),
  });

  const linkedIds = new Set(links.map((l) => l.server_id));

  return (
    <div className="mt-3 mx-1 border border-gray-100 rounded-lg bg-white p-4 space-y-3">
      <div className="flex items-center justify-between">
        <span className="text-xs font-semibold text-gray-600">关联服务器</span>
        <button onClick={() => setShowLink((v) => !v)}
          className={`text-[11px] px-2 py-0.5 rounded border transition-colors ${
            showLink
              ? "border-blue-300 bg-blue-50 text-blue-600"
              : "border-gray-200 text-gray-400 hover:text-gray-600"
          }`}>
          {showLink ? "收起" : "+ 关联"}
        </button>
      </div>

      {showLink && <LinkSelector projectId={projectId} linkedIds={linkedIds} />}

      {links.length === 0 && !showLink && (
        <p className="text-[11px] text-gray-300 text-center py-2">暂未关联服务器</p>
      )}

      {links.map((link) => (
        <LinkedServerItem key={link.server_id} link={link} projectId={projectId} />
      ))}
    </div>
  );
}
