import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useQueryClient } from "@tanstack/react-query";
import { getGroups, getGroupMaps, getProjects, getSpaces, getTags, getAllProjectTagMaps, getGlobalTools, addGlobalTool, updateGlobalTool, removeGlobalTool, launchTool, type ProductGroup, type Project, type ProjectToolInput } from "../../lib/commands";
import { ProjectCard } from "./ProjectCard";
import { DeployModal } from "./DeployModal";
import { GroupResourceCanvas } from "./GroupResourceCanvas";
import { ManagePage } from "../manage/ManagePage";
import { ServerManagerPanel } from "./ServerManagerPanel";
import { ServerSoftwarePanel } from "./ServerSoftwareBlock";
import { ApiKeysPanel } from "./ApiKeysPanel";
import { CloudProductsPanel } from "./CloudProductsPanel";
import { BatchAddModal } from "./BatchAddModal";
import { MountRepoModal } from "./MountRepoModal";
import { ProjectToolsModal } from "./ProjectToolsModal";
import { StatusBadge } from "../ui/Badge";
import { openUrl } from "@tauri-apps/plugin-opener";
import { useUIStore } from "../../store/ui";

type DashView = "board" | "manage";
type BoardTab = "groups" | "standalone" | "servers" | "software" | "apikeys" | "cloud";
type GroupView = "default" | "resource";

export function Dashboard() {
  const [view, setView] = useState<DashView>("board");
  const [boardTab, setBoardTab] = useState<BoardTab>("groups");
  const [showBatch, setShowBatch] = useState(false);
  const [showMount, setShowMount] = useState(false);
  const qc = useQueryClient();

  const { data: spaces = [] } = useQuery({
    queryKey: ["spaces"],
    queryFn: getSpaces,
  });
  const currentSpace = spaces.find((s) => s.is_current);

  const { data: projects = [] } = useQuery({
    queryKey: ["projects", currentSpace?.id],
    queryFn: () => getProjects(undefined, currentSpace?.id),
  });
  const { data: groups = [] } = useQuery({
    queryKey: ["groups", currentSpace?.id],
    queryFn: () => getGroups(currentSpace?.id),
  });
  const { data: maps = [] } = useQuery({ queryKey: ["maps"], queryFn: getGroupMaps });

  const mappedIds = new Set(maps.map((m) => m.project_id));
  const standalone = projects.filter((p) => !mappedIds.has(p.id));

  return (
    <div className="flex flex-col h-full">
      {/* 子导航栏 */}
      <div className="border-b border-gray-100 bg-white px-4 flex items-center gap-1">
        {(["board", "manage"] as DashView[]).map((v) => (
          <button
            key={v}
            onClick={() => setView(v)}
            className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
              view === v
                ? "border-blue-500 text-blue-600"
                : "border-transparent text-gray-500 hover:text-gray-700"
            }`}
          >
            {v === "board" ? "看板" : "管理"}
          </button>
        ))}
        <div className="flex-1" />
        {view === "board" && (
          <div className="flex gap-2 py-1.5">
            <button
              onClick={() => setShowBatch(true)}
              className="px-3 py-1.5 rounded-md text-xs font-medium border border-gray-200 text-gray-600 hover:bg-gray-50 transition-colors"
            >
              批量添加
            </button>
            <button
              onClick={() => setShowMount(true)}
              className="px-3 py-1.5 rounded-md text-xs font-medium border border-gray-200 text-gray-600 hover:bg-gray-50 transition-colors"
            >
              从仓库导入
            </button>
          </div>
        )}
      </div>

      {showBatch && <BatchAddModal onClose={() => { setShowBatch(false); qc.invalidateQueries({ queryKey: ["projects"] }); }} />}
      {showMount && currentSpace && (
        <MountRepoModal
          spaceId={currentSpace.id}
          onClose={() => setShowMount(false)}
        />
      )}

      {/* 内容区 */}
      {view === "manage" ? (
        <div className="flex-1 min-h-0">
          <ManagePage />
        </div>
      ) : (
        <div className="flex-1 flex flex-col min-h-0">
          {/* 看板子标签 */}
          <div className="shrink-0 border-b border-gray-100 bg-white px-8 flex items-center gap-1">
            <button
              onClick={() => setBoardTab("groups")}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                boardTab === "groups"
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-400 hover:text-gray-600"
              }`}
            >
              产品组
              {groups.filter((g) => maps.some((m) => m.group_id === g.id)).length > 0 && (
                <span className="ml-1.5 text-xs bg-gray-100 text-gray-500 rounded-full px-1.5 py-0.5">
                  {groups.filter((g) => maps.some((m) => m.group_id === g.id)).length}
                </span>
              )}
            </button>
            <button
              onClick={() => setBoardTab("standalone")}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                boardTab === "standalone"
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-400 hover:text-gray-600"
              }`}
            >
              独立项目
              {standalone.length > 0 && (
                <span className="ml-1.5 text-xs bg-gray-100 text-gray-500 rounded-full px-1.5 py-0.5">
                  {standalone.length}
                </span>
              )}
            </button>
            <button
              onClick={() => setBoardTab("servers")}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                boardTab === "servers"
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-400 hover:text-gray-600"
              }`}
            >
              服务器
            </button>
            <button
              onClick={() => setBoardTab("software")}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                boardTab === "software"
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-400 hover:text-gray-600"
              }`}
            >
              软件仓库
            </button>
            <button
              onClick={() => setBoardTab("apikeys")}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                boardTab === "apikeys"
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-400 hover:text-gray-600"
              }`}
            >
              API 管理
            </button>
            <button
              onClick={() => setBoardTab("cloud")}
              className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
                boardTab === "cloud"
                  ? "border-blue-500 text-blue-600"
                  : "border-transparent text-gray-400 hover:text-gray-600"
              }`}
            >
              云产品
            </button>
          </div>

          <GlobalQuickLaunchBar />

          <div className="flex-1 overflow-y-auto min-h-0">
            <div className="w-full px-8 py-8 space-y-8 pb-16">

              {/* ── 产品组标签 ── */}
              {boardTab === "groups" && (
                <>
                  {groups.map((g) => {
                    const members = maps
                      .filter((m) => m.group_id === g.id)
                      .map((m) => ({ project: projects.find((p) => p.id === m.project_id), role: m.role }))
                      .filter((x): x is { project: NonNullable<typeof x.project>; role: typeof x.role } => !!x.project);

                    if (members.length === 0) return null;

                    return (
                      <GroupBoardSection
                        key={g.id}
                        group={g}
                        members={members}
                      />
                    );
                  })}
                  {groups.every((g) => !maps.some((m) => m.group_id === g.id)) && (
                    <div className="text-center py-24 text-gray-400">
                      <p className="text-4xl mb-4">🗂</p>
                      <p className="text-sm">还没有产品组，在「管理」中创建产品组并添加项目</p>
                    </div>
                  )}
                </>
              )}

              {/* ── 独立项目标签 ── */}
              {boardTab === "standalone" && (
                <>
                  {standalone.length > 0 ? (
                    <StandaloneBoardSection standalone={standalone} />
                  ) : (
                    <div className="text-center py-24 text-gray-400">
                      <p className="text-4xl mb-4">📂</p>
                      <p className="text-sm">没有独立项目，所有项目已归属产品组</p>
                    </div>
                  )}
                </>
              )}

              {/* ── 服务器管理标签 ── */}
              {boardTab === "servers" && <ServerManagerPanel />}

              {/* ── 软件仓库标签 ── */}
              {boardTab === "software" && (
                <div className="w-full px-8 py-8 pb-16">
                  <ServerSoftwarePanel />
                </div>
              )}

              {/* ── API 管理标签 ── */}
              {boardTab === "apikeys" && <ApiKeysPanel />}

              {/* ── 云产品标签 ── */}
              {boardTab === "cloud" && <CloudProductsPanel />}

            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* ── GroupBoardSection ─────────────────────────────────────────────────────── */

interface GroupMember {
  project: Project;
  role: string | null | undefined;
}

interface GroupBoardSectionProps {
  group: ProductGroup;
  members: GroupMember[];
}

function GroupBoardSection({ group: g, members }: GroupBoardSectionProps) {
  const [deployTarget, setDeployTarget] = useState<Project | null>(null);
  const [groupView, setGroupView] = useState<GroupView>("default");

  const winMembers = members.filter(({ project: p }) => p.platform !== "wsl");
  const wslMembers = members.filter(({ project: p }) => p.platform === "wsl");

  return (
    <section className="bg-white rounded-2xl border border-gray-200 shadow-sm overflow-hidden">
      {/* 产品组标题栏 */}
      <div className="flex items-center gap-3 px-6 py-3.5 border-b border-gray-100 bg-gray-50/80">
        <h2 className="text-sm font-bold text-gray-800 tracking-tight">{g.name}</h2>
        {g.description && (
          <span className="text-xs text-gray-400 border-l border-gray-200 pl-3">{g.description}</span>
        )}
        <span className="ml-auto text-xs text-gray-400 bg-white border border-gray-200 rounded-full px-2.5 py-0.5">
          {members.length} 个项目
        </span>
        {/* 视图切换 */}
        <div className="flex items-center rounded-lg border border-gray-200 overflow-hidden text-[11px] font-medium">
          <button
            onClick={() => setGroupView("default")}
            className={`px-2.5 py-1 transition-colors ${
              groupView === "default"
                ? "bg-gray-700 text-white"
                : "bg-white text-gray-500 hover:bg-gray-50"
            }`}
          >
            默认视图
          </button>
          <button
            onClick={() => setGroupView("resource")}
            className={`px-2.5 py-1 transition-colors border-l border-gray-200 ${
              groupView === "resource"
                ? "bg-gray-700 text-white"
                : "bg-white text-gray-500 hover:bg-gray-50"
            }`}
          >
            资源视角
          </button>
        </div>
      </div>

      {/* ── 资源视角画布 ── */}
      {groupView === "resource" && (
        <GroupResourceCanvas members={members} groupId={g.id} />
      )}

      {/* ── 默认视图 ── */}
      {groupView === "default" && (
        <>
          {/* 列头 */}
          <div className="flex border-b border-gray-100 bg-gray-50/60">
            <div className="flex-1 px-5 py-2 text-xs font-semibold text-gray-400">本地项目</div>
            <div className="w-72 shrink-0 px-4 py-2 text-xs font-semibold text-gray-400 border-l border-gray-100">部署信息</div>
          </div>

          {/* 主体：每个项目一行，左=卡片 右=部署信息，平台分组作行标题 */}
          <div className="flex flex-col">
            {/* Windows 分组 */}
            <div className="flex items-center gap-2 px-5 py-2 bg-blue-50/40 border-b border-gray-100">
              <p className="text-xs font-semibold text-blue-500 uppercase tracking-widest">Windows</p>
              <span className="text-[10px] text-blue-400">{winMembers.length} 个</span>
            </div>
            {winMembers.length > 0
              ? winMembers.map(({ project, role }) => (
                  <ProjectRow
                    key={project.id}
                    project={project}
                    role={role ?? undefined}
                    onDeploy={setDeployTarget}
                  />
                ))
              : <p className="text-xs text-gray-300 py-5 text-center border-b border-gray-50">暂无</p>
            }

            {/* WSL 分组 */}
            <div className="flex items-center gap-2 px-5 py-2 bg-green-50/40 border-b border-gray-100">
              <p className="text-xs font-semibold text-green-600 uppercase tracking-widest">WSL / Linux</p>
              <span className="text-[10px] text-green-500">{wslMembers.length} 个</span>
            </div>
            {wslMembers.length > 0
              ? wslMembers.map(({ project, role }) => (
                  <ProjectRow
                    key={project.id}
                    project={project}
                    role={role ?? undefined}
                    onDeploy={setDeployTarget}
                  />
                ))
              : <p className="text-xs text-gray-300 py-5 text-center">暂无</p>
            }
          </div>
        </>
      )}

      {deployTarget && (
        <DeployModal
          projectId={deployTarget.id}
          projectName={deployTarget.name}
          projectPath={deployTarget.win_path ?? undefined}
          projectWslPath={deployTarget.wsl_path ?? undefined}
          onClose={() => setDeployTarget(null)}
        />
      )}
    </section>
  );
}

/* ── ProjectRow ────────────────────────────────────────────────────────────── */

function ProjectRow({
  project: p, role, onDeploy,
}: {
  project: Project;
  role?: string;
  onDeploy: (p: Project) => void;
}) {
  return (
    <div className="flex divide-x divide-gray-100 border-b border-gray-50 last:border-b-0">
      {/* 左：项目卡片 */}
      <div className="flex-1 min-w-0 p-4">
        <ProjectCard project={p} role={role} />
      </div>

      {/* 右：部署信息 */}
      <div className="w-72 shrink-0 p-4 flex flex-col gap-2.5">
        {/* 状态 + 角色 + 时间 */}
        <div className="flex items-center gap-1.5 flex-wrap">
          {p.status && <StatusBadge status={p.status} />}
          {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">
              {role}
            </span>
          )}
          {p.updated_at && (
            <span className="text-[10px] text-gray-300 ml-auto">{p.updated_at.slice(0, 10)}</span>
          )}
        </div>

        {/* 当前专注 */}
        {p.recent_focus && (
          <div className="bg-indigo-50 border border-indigo-100 rounded-md px-2.5 py-2">
            <p className="text-[11px] text-indigo-600 leading-relaxed line-clamp-3">
              📌 {p.recent_focus}
            </p>
          </div>
        )}

        {/* 部署环境入口 */}
        {(p.prod_url || p.staging_url) && (
          <div className="flex flex-col gap-1.5">
            {p.prod_url && (
              <button
                onClick={() => openUrl(p.prod_url!).catch(() => {})}
                className="flex items-center gap-2 text-[11px] px-2.5 py-2 rounded-md bg-emerald-50 text-emerald-700 border border-emerald-200 hover:bg-emerald-100 transition-colors w-full text-left"
                title={p.prod_url}
              >
                <span>🌐</span>
                <span className="font-medium">生产环境</span>
                <svg className="w-3 h-3 ml-auto text-emerald-400 shrink-0" viewBox="0 0 16 16" fill="currentColor">
                  <path d="M6.22 8.72a.75.75 0 001.06 1.06l5.22-5.22v1.69a.75.75 0 001.5 0V3a.75.75 0 00-.75-.75H9.5a.75.75 0 000 1.5h1.69L6.22 8.72z"/><path d="M3.5 6.75a.75.75 0 00-.75.75v5.75c0 .414.336.75.75.75h5.75a.75.75 0 000-1.5H4.25V7.5a.75.75 0 00-.75-.75z"/>
                </svg>
              </button>
            )}
            {p.staging_url && (
              <button
                onClick={() => openUrl(p.staging_url!).catch(() => {})}
                className="flex items-center gap-2 text-[11px] px-2.5 py-2 rounded-md bg-amber-50 text-amber-700 border border-amber-200 hover:bg-amber-100 transition-colors w-full text-left"
                title={p.staging_url}
              >
                <span>🧪</span>
                <span className="font-medium">测试环境</span>
                <svg className="w-3 h-3 ml-auto text-amber-400 shrink-0" viewBox="0 0 16 16" fill="currentColor">
                  <path d="M6.22 8.72a.75.75 0 001.06 1.06l5.22-5.22v1.69a.75.75 0 001.5 0V3a.75.75 0 00-.75-.75H9.5a.75.75 0 000 1.5h1.69L6.22 8.72z"/><path d="M3.5 6.75a.75.75 0 00-.75.75v5.75c0 .414.336.75.75.75h5.75a.75.75 0 000-1.5H4.25V7.5a.75.75 0 00-.75-.75z"/>
                </svg>
              </button>
            )}
          </div>
        )}

        {/* 服务器备注 */}
        {p.server_note && (
          <div className="bg-gray-50 border border-gray-100 rounded-md px-2.5 py-2">
            <p className="text-[11px] text-gray-500 leading-relaxed">🖥 {p.server_note}</p>
          </div>
        )}

        {/* 无信息提示 */}
        {!p.prod_url && !p.staging_url && !p.server_note && !p.recent_focus && (
          <p className="text-[11px] text-gray-300 italic">未配置部署信息</p>
        )}

        {/* 部署配置按钮 */}
        <div className="mt-auto pt-1">
          <button
            onClick={() => onDeploy(p)}
            className="w-full px-2.5 py-1.5 rounded-md text-[11px] border border-gray-200 text-gray-500 hover:bg-gray-50 transition-colors"
          >
            🚀 部署配置
          </button>
        </div>
      </div>
    </div>
  );
}

/* ── GlobalQuickLaunchBar ──────────────────────────────────────────────────── */

const GLOBAL_QUERY_KEY = ["globalTools"];

const globalToolCmds = {
  getTools: () => getGlobalTools(),
  addTool: (input: ProjectToolInput) => addGlobalTool(input),
  updateTool: (id: string, input: ProjectToolInput) => updateGlobalTool(id, input),
  removeTool: (id: string) => removeGlobalTool(id),
};

function GlobalQuickLaunchBar() {
  const showToast = useUIStore((s) => s.showToast);
  const [showMgr, setShowMgr] = useState(false);
  const [mgrDefaultAdd, setMgrDefaultAdd] = useState(false);

  const { data: tools = [] } = useQuery({
    queryKey: GLOBAL_QUERY_KEY,
    queryFn: () => getGlobalTools(),
    staleTime: 30000,
  });

  const handleLaunch = async (exePath: string, args: string | null | undefined, name: string) => {
    try {
      await launchTool(exePath, args ?? undefined);
      showToast(`已启动 ${name} ✓`);
    } catch (e) {
      showToast(`❌ ${e}`);
    }
  };

  return (
    <div className="shrink-0 border-b border-gray-100 bg-white px-8 py-2 flex items-center gap-2 flex-wrap">
      <span className="text-[11px] font-semibold text-orange-600 bg-orange-50 border border-orange-200 rounded px-1.5 py-0.5 shrink-0">
        快启
      </span>
      {tools.length > 0 ? (
        <>
          {tools.map((tool) => (
            <button
              key={tool.id}
              onClick={() => handleLaunch(tool.exe_path, tool.args, tool.name)}
              title={tool.exe_path}
              className="px-2.5 py-1 rounded-md text-xs border border-gray-200 text-gray-600 hover:bg-orange-50 hover:border-orange-300 hover:text-orange-800 transition-colors"
            >
              {tool.icon} {tool.name}
            </button>
          ))}
          <button
            onClick={() => { setMgrDefaultAdd(true); setShowMgr(true); }}
            className="px-2 py-1 rounded-md text-xs border border-dashed border-orange-200 text-orange-400 hover:border-orange-400 hover:text-orange-600 hover:bg-orange-50 transition-colors"
            title="添加快启应用"
          >
            +
          </button>
        </>
      ) : (
        <button
          onClick={() => { setMgrDefaultAdd(true); setShowMgr(true); }}
          className="px-2.5 py-1 rounded-md text-xs border border-dashed border-orange-200 text-orange-400 hover:border-orange-400 hover:text-orange-600 hover:bg-orange-50 transition-colors"
        >
          + 配置日常应用
        </button>
      )}
      <button
        onClick={() => { setMgrDefaultAdd(false); setShowMgr(true); }}
        className="ml-auto text-gray-300 hover:text-gray-500 transition-colors"
        title="管理快启应用"
      >
        <svg className="w-3.5 h-3.5" viewBox="0 0 20 20" fill="currentColor">
          <path fillRule="evenodd" d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z" clipRule="evenodd" />
        </svg>
      </button>
      {showMgr && (
        <ProjectToolsModal
          projectId="__global__"
          projectName="日常应用"
          defaultOpenAdd={mgrDefaultAdd}
          commands={globalToolCmds}
          queryKey={GLOBAL_QUERY_KEY}
          onClose={() => { setShowMgr(false); setMgrDefaultAdd(false); }}
        />
      )}
    </div>
  );
}

/* ── StandaloneBoardSection ────────────────────────────────────────────────── */

function StandaloneBoardSection({
  standalone,
}: {
  standalone: Project[];
}) {
  const [deployTarget, setDeployTarget] = useState<Project | null>(null);
  const [selectedTagIds, setSelectedTagIds] = useState<Set<string>>(new Set());
  const [search, setSearch] = useState("");

  const { data: allTags = [] } = useQuery({ queryKey: ["tags"], queryFn: getTags });
  const { data: tagMaps = [] } = useQuery({ queryKey: ["tagMaps"], queryFn: getAllProjectTagMaps });

  const toggleTag = (tagId: string) => {
    setSelectedTagIds((prev) => {
      const next = new Set(prev);
      next.has(tagId) ? next.delete(tagId) : next.add(tagId);
      return next;
    });
  };

  const filtered = standalone.filter((p) => {
    if (search.trim() && !p.name.toLowerCase().includes(search.trim().toLowerCase())) return false;
    if (selectedTagIds.size === 0) return true;
    const projectTagIds = tagMaps
      .filter((m) => m.profile_id === p.profile_id)
      .map((m) => m.tag_id);
    return [...selectedTagIds].some((id) => projectTagIds.includes(id));
  });

  const winProjects = filtered.filter((p) => p.platform !== "wsl");
  const wslProjects = filtered.filter((p) => p.platform === "wsl");

  return (
    <section className="bg-white rounded-2xl border border-gray-200 shadow-sm overflow-hidden">
      {/* 搜索 + 标签筛选栏（始终显示） */}
      <div className="px-5 py-3 border-b border-gray-100 flex flex-col gap-2 bg-gray-50/40">
        {/* 搜索框 */}
        <div className="flex items-center gap-2">
          <input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="搜索项目名称…"
            className="flex-1 border border-gray-200 rounded-lg px-3 py-1.5 text-xs outline-none focus:ring-2 focus:ring-violet-200 bg-white"
          />
          <span className="text-[11px] text-gray-300 shrink-0">
            {filtered.length} / {standalone.length} 个
          </span>
          {(search || selectedTagIds.size > 0) && (
            <button
              onClick={() => { setSearch(""); setSelectedTagIds(new Set()); }}
              className="text-[11px] text-gray-400 hover:text-gray-600 shrink-0"
            >
              清除
            </button>
          )}
        </div>
        {/* 标签筛选 chips */}
        {allTags.length > 0 && (
          <div className="flex items-center gap-1.5 flex-wrap">
            <span className="text-[11px] text-gray-300 shrink-0">标签：</span>
            {allTags.map((tag) => (
              <button
                key={tag.id}
                onClick={() => toggleTag(tag.id)}
                className={`px-2.5 py-0.5 rounded-full text-xs font-medium border-2 transition-colors ${
                  selectedTagIds.has(tag.id) ? "text-white border-transparent" : "bg-white border-gray-200 text-gray-500"
                }`}
                style={selectedTagIds.has(tag.id) ? { backgroundColor: tag.color, borderColor: tag.color } : {}}
              >
                {tag.name}
              </button>
            ))}
          </div>
        )}
        {allTags.length === 0 && (
          <p className="text-[11px] text-gray-300">暂无标签，在「管理-标签」里创建后可在此筛选</p>
        )}
      </div>

      {/* 列头 */}
      <div className="flex border-b border-gray-100 bg-gray-50/60">
        <div className="flex-1 px-5 py-2 text-xs font-semibold text-gray-400">本地项目</div>
        <div className="w-72 shrink-0 px-4 py-2 text-xs font-semibold text-gray-400 border-l border-gray-100">部署信息</div>
      </div>

      <div className="flex flex-col">
        {/* Windows */}
        <div className="flex items-center gap-2 px-5 py-2 bg-blue-50/40 border-b border-gray-100">
          <p className="text-xs font-semibold text-blue-500 uppercase tracking-widest">Windows</p>
          <span className="text-[10px] text-blue-400">{winProjects.length} 个</span>
        </div>
        {winProjects.length > 0
          ? winProjects.map((p) => (
              <ProjectRow key={p.id} project={p} onDeploy={setDeployTarget} />
            ))
          : <p className="text-xs text-gray-300 py-5 text-center border-b border-gray-50">暂无</p>
        }

        {/* WSL */}
        <div className="flex items-center gap-2 px-5 py-2 bg-green-50/40 border-b border-gray-100">
          <p className="text-xs font-semibold text-green-600 uppercase tracking-widest">WSL / Linux</p>
          <span className="text-[10px] text-green-500">{wslProjects.length} 个</span>
        </div>
        {wslProjects.length > 0
          ? wslProjects.map((p) => (
              <ProjectRow key={p.id} project={p} onDeploy={setDeployTarget} />
            ))
          : <p className="text-xs text-gray-300 py-5 text-center">暂无</p>
        }
      </div>

      {deployTarget && (
        <DeployModal
          projectId={deployTarget.id}
          projectName={deployTarget.name}
          projectPath={deployTarget.win_path ?? undefined}
          projectWslPath={deployTarget.wsl_path ?? undefined}
          onClose={() => setDeployTarget(null)}
        />
      )}
    </section>
  );
}
