import { clsx } from "clsx";
import {
  BadgeCheck,
  Download,
  ExternalLink,
  FolderOpen,
  GitBranch,
  Loader2,
  Package,
  Search,
  Server,
  Shield,
  ShieldAlert,
  ShieldCheck,
  Star,
  Terminal,
  TrendingUp,
  X,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { InstallDialog } from "@/components/extensions/install-dialog";
import { AgentMascot } from "@/components/shared/agent-mascot/agent-mascot";
import { HermesCategoryPicker } from "@/components/shared/hermes-category-picker";
import { Hint } from "@/components/shared/hint";
import { ScopeTargetField } from "@/components/shared/scope-target-field";
import { useScope } from "@/hooks/use-scope";
import { useScrollPassthrough } from "@/hooks/use-scroll-passthrough";
import { canInstallAtScope } from "@/lib/agent-capabilities";
import { humanizeError } from "@/lib/errors";
import { api } from "@/lib/invoke";
import {
  agentDisplayName,
  type ConfigScope,
  type MarketplaceItem,
  type SkillAuditInfo,
  scopeKey,
  sortAgents,
} from "@/lib/types";
import { useAgentStore } from "@/stores/agent-store";
import { useExtensionStore } from "@/stores/extension-store";
import { useMarketplaceStore } from "@/stores/marketplace-store";
import type { ScopeValue } from "@/stores/scope-store";
import { toast } from "@/stores/toast-store";

/** Extract install-related section from README markdown.
 *  Skips fenced code blocks so that `# shell comments` aren't mistaken for headings. */
function extractInstallSection(readme: string): string | null {
  const lines = readme.split("\n");
  const installHeadingRe =
    /^#{1,3}\s+.*?(install\w*|setup|getting\s+started|quick\s+start|usage|安装|快速开始)/i;
  const fenceRe = /^(`{3,}|~{3,})/;

  // First pass: mark which lines are inside fenced code blocks
  const inCodeBlock: boolean[] = new Array(lines.length);
  let insideFence = false;
  let fenceChar = "";
  let fenceLen = 0;
  for (let i = 0; i < lines.length; i++) {
    const m = lines[i].match(fenceRe);
    if (m) {
      if (!insideFence) {
        insideFence = true;
        fenceChar = m[1][0];
        fenceLen = m[1].length;
        inCodeBlock[i] = true;
        continue;
      }
      // Closing fence must use same char and at least same length
      if (lines[i].startsWith(fenceChar.repeat(fenceLen))) {
        inCodeBlock[i] = true;
        insideFence = false;
        continue;
      }
    }
    inCodeBlock[i] = insideFence;
  }

  // Second pass: find install heading outside code blocks
  for (let i = 0; i < lines.length; i++) {
    if (inCodeBlock[i]) continue;
    if (!installHeadingRe.test(lines[i])) continue;
    // Found an install heading — collect until next heading of same or higher level
    const level = (lines[i].match(/^(#+)/) ?? ["", "#"])[1].length;
    const sectionLines = [lines[i]];
    for (let j = i + 1; j < lines.length; j++) {
      if (!inCodeBlock[j]) {
        const hm = lines[j].match(/^(#+)\s+/);
        if (hm && hm[1].length <= level) break;
      }
      sectionLines.push(lines[j]);
    }
    const section = sectionLines.join("\n").trim();
    if (section.length > 20) return section;
  }
  return null;
}

function formatInstalls(n: number): string {
  if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
  if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
  return n.toString();
}

function RiskBadge({ risk }: { risk: string | null }) {
  const { t } = useTranslation("marketplace");
  if (!risk)
    return (
      <span className="text-xs text-muted-foreground">{t("risk.unknown")}</span>
    );
  const color =
    risk === "safe"
      ? "text-primary"
      : risk === "low"
        ? "text-muted-foreground"
        : "text-destructive";
  const Icon =
    risk === "safe" ? ShieldCheck : risk === "low" ? Shield : ShieldAlert;
  return (
    <span className={`flex items-center gap-1 text-xs font-medium ${color}`}>
      <Icon size={12} />
      {t(`risk.${risk}` as "risk.safe", { defaultValue: risk })}
    </span>
  );
}

function AuditSection({ audit }: { audit: SkillAuditInfo }) {
  const { t } = useTranslation("marketplace");
  return (
    <div className="space-y-2">
      {[
        { name: t("audit.ath"), data: audit.ath },
        { name: t("audit.socket"), data: audit.socket },
        { name: t("audit.snyk"), data: audit.snyk },
      ].map(({ name, data }) => (
        <div key={name} className="flex items-center justify-between text-xs">
          <span className="text-muted-foreground">{name}</span>
          <RiskBadge risk={data?.risk ?? null} />
        </div>
      ))}
      {audit.socket?.score != null && (
        <div className="flex items-center justify-between text-xs">
          <span className="text-muted-foreground">{t("audit.score")}</span>
          <span className="font-mono font-medium">
            {audit.socket.score}/100
          </span>
        </div>
      )}
    </div>
  );
}

function ItemRow({
  item,
  selected,
  onSelect,
  index,
}: {
  item: MarketplaceItem;
  selected: boolean;
  onSelect: () => void;
  index: number;
}) {
  const { t } = useTranslation("marketplace");
  return (
    <button
      onClick={onSelect}
      aria-label={t("item.viewDetails", { name: item.name })}
      className={clsx(
        "animate-fade-in flex w-full items-start gap-3 rounded-xl border px-4 py-3 text-left transition-[background-color,border-color,box-shadow] duration-200",
        selected
          ? "border-ring bg-accent shadow-sm"
          : "border-border bg-card hover:border-ring/50 hover:bg-accent/50 hover:shadow-sm",
      )}
      style={{ animationDelay: `${Math.min(index * 30, 300)}ms` }}
    >
      {item.icon_url && (
        <img
          src={item.icon_url}
          alt={item.name}
          loading="lazy"
          decoding="async"
          className="mt-0.5 h-8 w-8 shrink-0 rounded-lg"
        />
      )}
      <div className="min-w-0 flex-1">
        <div className="flex items-center gap-2">
          <span className="font-medium">{item.name}</span>
          {item.verified && (
            <BadgeCheck size={14} className="shrink-0 text-primary" />
          )}
        </div>
        <p className="mt-0.5 text-xs text-muted-foreground line-clamp-2">
          {item.description}
        </p>
        <p className="mt-0.5 text-xs text-muted-foreground/60">
          {item.kind === "cli" && item.stars != null ? (
            <>
              <Star size={10} className="inline -mt-0.5 mr-0.5" />
              {formatInstalls(item.stars)}
            </>
          ) : (
            <>
              {formatInstalls(item.installs)} {t("item.installs")}
            </>
          )}
          {item.categories.length > 0 &&
            ` · ${item.categories.slice(0, 2).join(", ")}`}
          {item.source && ` · ${item.source}`}
        </p>
      </div>
    </button>
  );
}

export default function MarketplacePage() {
  const { t } = useTranslation("marketplace");
  const { t: tc } = useTranslation("common");
  const {
    tab,
    setTab,
    query,
    setQuery,
    results,
    trending,
    loading,
    trendingLoading,
    search,
    loadTrending,
    selectedItem,
    selectItem,
    closePreview,
    previewContent,
    previewLoading,
    auditInfo,
    auditLoading,
    cliReadme,
    cliReadmeLoading,
    installing,
    install,
  } = useMarketplaceStore();
  const { agents, fetch: fetchAgents, agentOrder } = useAgentStore();
  const extensions = useExtensionStore((s) => s.extensions);
  const { scope, isAll } = useScope();
  const [installTargetScope, setInstallTargetScope] =
    useState<ConfigScope | null>(null);
  // In single-scope mode, the active scope IS the install target. In All-scopes
  // mode, the user must pick a scope via ScopeTargetField (null until picked).
  const effectiveTarget: ConfigScope | null = isAll
    ? installTargetScope
    : (scope as ConfigScope);
  const [installed, setInstalled] = useState<Set<string>>(new Set());
  const [justInstalled, setJustInstalled] = useState<Set<string>>(new Set());
  const [error, setError] = useState<string | null>(null);
  const [showInstall, setShowInstall] = useState(false);
  const [installMode, setInstallMode] = useState<"git" | "local">("git");
  // Hermes category picker state (marketplace install)
  const [hermesPending, setHermesPending] = useState<{
    item: MarketplaceItem;
    scope: ConfigScope;
  } | null>(null);
  const [hermesMarketCategories, setHermesMarketCategories] = useState<
    string[]
  >([]);
  const [hermesMarketCategory, setHermesMarketCategory] = useState("local");
  const detailPanelRef = useRef<HTMLDivElement>(null);

  const isItemInstalled = (
    item: MarketplaceItem,
    agentName: string,
    activeScope: ScopeValue,
  ) => {
    const targetKey =
      activeScope.type === "all" ? null : scopeKey(activeScope as ConfigScope);

    if (targetKey !== null) {
      if (installed.has(`${item.id}:${agentName}:${targetKey}`)) return true;
    } else {
      for (const k of installed) {
        if (k.startsWith(`${item.id}:${agentName}:`)) return true;
      }
    }

    return extensions.some((ext) => {
      if (!ext.agents.includes(agentName)) return false;

      if (item.kind === "skill") {
        if (!["skill", "plugin"].includes(ext.kind)) return false;
      } else {
        if (ext.kind !== item.kind) return false;
      }

      const extUrl =
        ext.install_meta?.url_resolved ??
        ext.install_meta?.url ??
        ext.source.url;
      let extSource = "";
      if (extUrl) {
        const cleanUrl = extUrl.split(/[?#]/)[0];
        const match = cleanUrl.match(/github\.com[:/]([^/]+\/[^/]+)/);
        extSource = match ? match[1].replace(/\.git$/, "") : cleanUrl;
      }
      if (!extSource && ext.pack) extSource = ext.pack;

      // GitHub repo slugs are case-insensitive; marketplace normalizes to
      // lowercase while scanner preserves original casing. Compare lowered
      // on both sides to avoid false negatives.
      const itemSourceLower = item.source.toLowerCase();
      if (!itemSourceLower) return false;
      const matchSource =
        extSource.toLowerCase() === itemSourceLower ||
        (ext.pack ?? "").toLowerCase() === itemSourceLower;

      let nameMatches: boolean;
      if (item.kind === "skill") {
        // Match strictly by name. The scanner sometimes classifies individual
        // items in a collection repo (e.g. github/awesome-copilot) as kind=plugin,
        // so "same source URL + kind=plugin" doesn't reliably mean the whole repo
        // is installed — it could be just one sibling. See PR #21 discussion.
        const targetName =
          item.skill_id && item.skill_id.length > 0 ? item.skill_id : item.name;
        nameMatches = ext.name.toLowerCase() === targetName.toLowerCase();
      } else {
        nameMatches = ext.name.toLowerCase() === item.name.toLowerCase();
      }
      if (!nameMatches || !matchSource) return false;

      // Scope-aware: in single-scope mode only count installs in the active
      // scope. In All-scopes mode (targetKey === null) any scope counts.
      if (targetKey === null) return true;
      return scopeKey(ext.scope) === targetKey;
    });
  };

  const prefersReducedMotion = () =>
    window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const handleNestedWheel = useScrollPassthrough();

  useEffect(() => {
    fetchAgents();
  }, [fetchAgents]);
  useEffect(() => {
    loadTrending(tab);
  }, [tab, loadTrending]);
  useEffect(() => {
    if (selectedItem) detailPanelRef.current?.focus({ preventScroll: true });
  }, [selectedItem]);

  const searchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const handleQueryChange = (value: string) => {
    setQuery(value);
    setError(null);
    if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
    searchTimerRef.current = setTimeout(() => {
      search();
    }, 300);
  };
  const handleInstall = async (
    item: MarketplaceItem,
    targetAgent: string | undefined,
    targetScope: ConfigScope,
    hermesCategory?: string,
  ) => {
    // For Hermes skill installs, show category picker first (unless category already provided)
    if (targetAgent === "hermes" && item.kind === "skill" && !hermesCategory) {
      const cats = await api.listHermesCategories().catch(() => []);
      setHermesMarketCategories(cats);
      setHermesMarketCategory(cats[0] ?? "local");
      setHermesPending({ item, scope: targetScope });
      return;
    }
    setError(null);
    try {
      const result = await install(
        item,
        targetAgent,
        targetScope,
        hermesCategory,
      );
      // Refresh extension store so audit page can resolve names immediately
      useExtensionStore.getState().fetch();
      const key = `${item.id}:${targetAgent ?? ""}`;
      const installedKey = `${key}:${scopeKey(targetScope)}`;
      setInstalled((prev) => new Set(prev).add(installedKey));
      toast.success(
        result.was_update
          ? t("toast.updated", { name: item.name })
          : t("toast.installed", { name: item.name }),
      );
      // Trigger flash animation
      if (!prefersReducedMotion()) {
        setJustInstalled((prev) => new Set(prev).add(key));
        setTimeout(() => {
          setJustInstalled((prev) => {
            const next = new Set(prev);
            next.delete(key);
            return next;
          });
        }, 500);
      }
    } catch (e) {
      setError(String(e));
      toast.error(t("toast.installationFailed"));
    }
  };

  const detectedAgents = sortAgents(
    agents.filter((a) => a.detected && a.enabled),
    agentOrder,
  );
  const displayItems = query.length >= 2 ? results : trending;
  const showTrending = query.length < 2;

  return (
    <div className="flex flex-1 flex-col min-h-0 -mb-6">
      {/* Fixed header */}
      <div className="shrink-0 space-y-4 pb-4">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <h2 className="text-2xl font-bold tracking-tight select-none">
              {t("page.title")}
            </h2>
            <button
              onClick={() => {
                setInstallMode("git");
                setShowInstall(!showInstall || installMode !== "git");
              }}
              className="flex items-center gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-xs font-medium text-foreground shadow-sm transition-[background-color,box-shadow] duration-200 hover:bg-accent hover:shadow-md"
            >
              <GitBranch size={12} />
              {t("page.installFromGit")}
            </button>
            <button
              onClick={() => {
                setInstallMode("local");
                setShowInstall(!showInstall || installMode !== "local");
              }}
              className="flex items-center gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-xs font-medium text-foreground shadow-sm transition-[background-color,box-shadow] duration-200 hover:bg-accent hover:shadow-md"
            >
              <FolderOpen size={12} />
              {t("page.installFromLocal")}
            </button>
          </div>
          <div className="flex rounded-lg border border-border">
            <button
              onClick={() => setTab("skill")}
              className={clsx(
                "flex items-center gap-1.5 rounded-l-lg px-3 py-1.5 text-xs font-medium transition-colors border-b-2",
                tab === "skill"
                  ? "bg-primary text-primary-foreground border-b-primary-foreground/50"
                  : "text-muted-foreground border-b-transparent hover:bg-accent",
              )}
            >
              <Package size={12} />
              {t("tabs.skill")}
            </button>
            <button
              onClick={() => setTab("cli")}
              className={clsx(
                "flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium transition-colors border-b-2",
                tab === "cli"
                  ? "bg-primary text-primary-foreground border-b-primary-foreground/50"
                  : "text-muted-foreground border-b-transparent hover:bg-accent",
              )}
            >
              <Terminal size={12} />
              {t("tabs.cli")}
            </button>
            <button
              onClick={() => setTab("mcp")}
              className={clsx(
                "flex items-center gap-1.5 rounded-r-lg px-3 py-1.5 text-xs font-medium transition-colors border-b-2",
                tab === "mcp"
                  ? "bg-primary text-primary-foreground border-b-primary-foreground/50"
                  : "text-muted-foreground border-b-transparent hover:bg-accent",
              )}
            >
              <Server size={12} />
              {t("tabs.mcp")}
            </button>
          </div>
        </div>

        <InstallDialog
          open={showInstall}
          mode={installMode}
          onClose={() => setShowInstall(false)}
        />

        <div className="relative max-w-md">
          <Search
            size={14}
            className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground"
          />
          <input
            type="text"
            value={query}
            onChange={(e) => handleQueryChange(e.target.value)}
            placeholder={
              tab === "skill"
                ? t("search.placeholderSkill")
                : tab === "mcp"
                  ? t("search.placeholderMcp")
                  : t("search.placeholderCli")
            }
            aria-label={t("search.aria")}
            className="w-full rounded-lg border border-border bg-card py-2 pl-9 pr-8 text-sm placeholder:text-muted-foreground transition-[background-color,border-color,box-shadow] duration-200 focus:border-ring focus:bg-background focus:shadow-md focus:outline-none"
          />
          {query && (
            <button
              onClick={() => handleQueryChange("")}
              aria-label={t("search.clear")}
              className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
            >
              <X size={14} />
            </button>
          )}
        </div>

        <Hint id="marketplace-intro">{t("hint")}</Hint>
      </div>

      {/* Scrollable content */}
      <div className="relative flex-1 min-h-0">
        <div className="absolute inset-0 overflow-y-auto space-y-4 pb-4">
          {error && (
            <p className="text-sm text-destructive">{humanizeError(error)}</p>
          )}

          {showTrending && !trendingLoading && trending.length > 0 && (
            <div className="flex items-center gap-2 text-sm font-medium text-foreground">
              <TrendingUp size={14} className="text-primary" />
              <span>
                {t("trending.prefix")}{" "}
                {tab === "skill"
                  ? t("trending.skill")
                  : tab === "mcp"
                    ? t("trending.mcp")
                    : t("trending.cli")}
              </span>
            </div>
          )}

          {(loading || trendingLoading) && displayItems.length === 0 && (
            <div
              className="flex justify-center py-12"
              aria-live="polite"
              role="status"
            >
              <Loader2
                size={24}
                className="animate-spin text-muted-foreground"
              />
            </div>
          )}

          {!loading &&
            !trendingLoading &&
            displayItems.length === 0 &&
            query.length >= 2 && (
              <div className="py-8 px-6">
                <p className="text-sm font-medium text-foreground">
                  {t("empty.nothingMatched", { query })}
                </p>
                <p className="mt-1 text-xs text-muted-foreground">
                  {t("empty.tryDifferent")}
                </p>
              </div>
            )}

          <div className="grid gap-2">
            {displayItems.map((item, i) => (
              <ItemRow
                key={item.id}
                item={item}
                selected={selectedItem?.id === item.id}
                onSelect={() => selectItem(item)}
                index={i}
              />
            ))}
          </div>
        </div>

        {/* Detail Panel */}
        {selectedItem && (
          <div className="absolute right-0 top-0 bottom-0 w-96 z-10">
            <div
              ref={detailPanelRef}
              tabIndex={-1}
              onWheel={(e) => e.stopPropagation()}
              className="animate-slide-in-right flex h-full flex-col rounded-xl border border-border bg-card shadow-sm outline-none"
            >
              {/* Fixed header */}
              <div className="shrink-0 flex items-start justify-between border-b border-border px-5 py-4">
                <div className="min-w-0">
                  <div className="flex items-center gap-2">
                    {selectedItem.icon_url && (
                      <img
                        src={selectedItem.icon_url}
                        alt={selectedItem.name}
                        loading="lazy"
                        decoding="async"
                        className="h-6 w-6 rounded"
                      />
                    )}
                    <h3 className="text-lg font-semibold">
                      {selectedItem.name}
                    </h3>
                    {selectedItem.verified && (
                      <BadgeCheck size={16} className="shrink-0 text-primary" />
                    )}
                  </div>
                  {selectedItem.source && (
                    <a
                      href={
                        selectedItem.repo_url ??
                        (selectedItem.kind === "mcp"
                          ? `https://smithery.ai/server/${selectedItem.source}`
                          : `https://github.com/${selectedItem.source}`)
                      }
                      target="_blank"
                      rel="noopener noreferrer"
                      className="mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
                    >
                      {selectedItem.source}
                      <ExternalLink size={10} className="shrink-0" />
                    </a>
                  )}
                  <p className="mt-1 text-xs text-muted-foreground/70">
                    {selectedItem.kind === "cli" &&
                    selectedItem.stars != null ? (
                      <>
                        <Star size={10} className="inline -mt-0.5 mr-0.5" />
                        {formatInstalls(selectedItem.stars)}
                      </>
                    ) : (
                      <>{formatInstalls(selectedItem.installs)} installs</>
                    )}
                  </p>
                </div>
                <button
                  onClick={closePreview}
                  aria-label={t("detail.closeAria")}
                  className="shrink-0 rounded-lg p-2.5 text-muted-foreground hover:text-foreground"
                >
                  <X size={18} />
                </button>
              </div>

              {/* Scrollable body */}
              <div className="flex-1 min-h-0 overflow-y-auto overscroll-contain px-5 py-4">
                {selectedItem.description && (
                  <p className="text-sm text-muted-foreground">
                    {selectedItem.description}
                  </p>
                )}

                {selectedItem.categories.length > 0 && (
                  <div className="mt-3 flex flex-wrap gap-1">
                    {selectedItem.categories.map((c) => (
                      <span
                        key={c}
                        className="rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground transition-colors hover:bg-accent"
                      >
                        {c}
                      </span>
                    ))}
                  </div>
                )}

                {/* MCP install guidance */}
                {selectedItem.kind === "mcp" && (
                  <div className="mt-4 rounded-lg border border-primary/20 bg-primary/5 p-4">
                    <p className="text-sm font-medium text-foreground">
                      {t("detail.installMcpTitle")}
                    </p>
                    <p className="mt-1 text-xs text-muted-foreground">
                      {t("detail.smitheryHint")}
                    </p>
                    <a
                      href={`https://smithery.ai/server/${selectedItem.source}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="mt-3 inline-flex items-center gap-1.5 rounded-lg bg-primary px-3.5 py-2 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90"
                    >
                      <Server size={12} />
                      {t("detail.setupOnSmithery")}
                      <ExternalLink size={10} />
                    </a>
                  </div>
                )}

                {/* CLI install guidance */}
                {selectedItem.kind === "cli" && (
                  <>
                    {selectedItem.repo_url && (
                      <a
                        href={selectedItem.repo_url}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="mt-3 inline-flex items-center gap-1.5 rounded-lg bg-primary px-3.5 py-2 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90"
                      >
                        {t("detail.viewOnGithub")}
                        <ExternalLink size={10} />
                      </a>
                    )}
                    <div className="mt-4">
                      <h4 className="mb-2 border-b border-border pb-1 text-xs font-medium text-muted-foreground">
                        {t("detail.installationGuide")}
                      </h4>
                      <div className="rounded-lg border border-border bg-card p-3">
                        {cliReadmeLoading ? (
                          <div className="flex justify-center py-6">
                            <Loader2
                              size={16}
                              className="animate-spin text-muted-foreground"
                            />
                          </div>
                        ) : cliReadme ? (
                          (() => {
                            const section = extractInstallSection(cliReadme);
                            return (
                              <pre
                                onWheel={handleNestedWheel}
                                className="whitespace-pre-wrap text-xs text-muted-foreground max-h-[40vh] overflow-y-auto"
                              >
                                {section ?? cliReadme.slice(0, 2000)}
                              </pre>
                            );
                          })()
                        ) : (
                          <p className="text-xs text-muted-foreground italic">
                            {t("detail.noReadme")}
                          </p>
                        )}
                      </div>
                    </div>
                  </>
                )}

                {/* Security Audit (skills only) */}
                {selectedItem.kind === "skill" && (
                  <div className="mt-4">
                    <h4 className="mb-2 border-b border-border pb-1 text-xs font-medium text-muted-foreground">
                      {t("detail.securityAudit")}
                    </h4>
                    <div className="rounded-lg border border-border bg-card p-3">
                      {auditLoading ? (
                        <div className="flex justify-center py-2">
                          <Loader2
                            size={14}
                            className="animate-spin text-muted-foreground"
                          />
                        </div>
                      ) : auditInfo ? (
                        <AuditSection audit={auditInfo} />
                      ) : (
                        <p className="text-xs text-muted-foreground italic">
                          {t("detail.noAuditData")}
                        </p>
                      )}
                    </div>
                  </div>
                )}

                {/* Install to agents */}
                {detectedAgents.length > 0 && selectedItem.kind === "skill" && (
                  <div className="mt-4">
                    <div className="mb-2 flex items-center gap-2 border-b border-border pb-1">
                      <h4 className="text-xs font-medium text-muted-foreground">
                        {t("detail.installToAgent")}
                      </h4>
                      {/* Single-scope mode: render the inline "· 📁 name" hint
                       * next to the header to save vertical space. All-scopes
                       * mode renders the picker on its own row below since the
                       * dropdown doesn't fit alongside the header. */}
                      {!isAll && (
                        <ScopeTargetField
                          value={effectiveTarget}
                          onChange={setInstallTargetScope}
                        />
                      )}
                    </div>
                    {isAll && (
                      <div className="mb-2.5">
                        <ScopeTargetField
                          value={effectiveTarget}
                          onChange={setInstallTargetScope}
                        />
                      </div>
                    )}
                    <div className="flex flex-wrap gap-1.5" aria-live="polite">
                      {detectedAgents.map((agent) => {
                        const key = `${selectedItem.id}:${agent.name}`;
                        // ConfigScope ⊂ ScopeValue (ScopeValue adds the "all"
                        // variant), so we can pass either through
                        // canInstallAtScope's ScopeValue parameter.
                        const targetScopeForCheck: ScopeValue =
                          effectiveTarget ?? scope;
                        const capabilityOk = canInstallAtScope(
                          agent.name,
                          "skill",
                          targetScopeForCheck,
                        );
                        const isInstalled = isItemInstalled(
                          selectedItem,
                          agent.name,
                          targetScopeForCheck,
                        );
                        const isFlashing = justInstalled.has(key);
                        const isInstallingThis = installing === key;
                        const isInstallingAny =
                          installing?.startsWith(`${selectedItem.id}:`) ??
                          false;
                        const disabled =
                          !effectiveTarget ||
                          isInstallingAny ||
                          isInstalled ||
                          !capabilityOk;
                        return (
                          <button
                            key={agent.name}
                            disabled={disabled}
                            aria-disabled={disabled}
                            title={
                              !effectiveTarget
                                ? t("detail.selectScopeFirst")
                                : !capabilityOk
                                  ? t("detail.kindNotSupported", {
                                      agent: agent.name,
                                    })
                                  : undefined
                            }
                            onClick={() =>
                              effectiveTarget &&
                              handleInstall(
                                selectedItem,
                                agent.name,
                                effectiveTarget,
                              )
                            }
                            className={clsx(
                              "flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-xs font-medium transition-[background-color,border-color] duration-300 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-primary/10 disabled:hover:border-border",
                              isFlashing
                                ? "border-primary/40 bg-primary/20 text-foreground"
                                : isInstalled
                                  ? "border-primary/20 bg-primary/10 text-foreground"
                                  : "border-border bg-primary/10 text-foreground hover:bg-primary/20 hover:border-ring",
                            )}
                          >
                            <div className={isInstalled ? "" : "opacity-90"}>
                              <AgentMascot name={agent.name} size={14} />
                            </div>
                            <span
                              className={
                                isInstalled ? "install-success-text" : ""
                              }
                            >
                              {agentDisplayName(agent.name)}
                            </span>
                            {isInstalled ? (
                              <ShieldCheck
                                size={14}
                                className="animate-scale-in text-primary shrink-0"
                              />
                            ) : isInstallingThis ? (
                              <Loader2
                                size={12}
                                className="animate-spin shrink-0 text-muted-foreground"
                              />
                            ) : (
                              <Download
                                size={12}
                                className="shrink-0 text-muted-foreground"
                              />
                            )}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                )}

                {/* Hermes category picker — shown when Hermes is clicked */}
                {hermesPending && hermesPending.item.id === selectedItem.id && (
                  <div className="mt-3 rounded-lg border border-border bg-muted/20 p-3">
                    <p className="mb-2 text-xs font-medium text-foreground">
                      {tc("hermesCategory.choose")}
                    </p>
                    <HermesCategoryPicker
                      categories={hermesMarketCategories}
                      value={hermesMarketCategory}
                      onChange={setHermesMarketCategory}
                      disabled={!!installing}
                    />
                    <div className="mt-2.5 flex items-center gap-2">
                      <button
                        disabled={!!installing}
                        onClick={() => {
                          const category =
                            hermesMarketCategory.trim() || "local";
                          const pending = hermesPending;
                          setHermesPending(null);
                          handleInstall(
                            pending.item,
                            "hermes",
                            pending.scope,
                            category,
                          );
                        }}
                        className="rounded-lg bg-primary px-3 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
                      >
                        {installing ? (
                          <Loader2
                            size={11}
                            className="animate-spin inline mr-1"
                          />
                        ) : null}
                        {tc("hermesCategory.install")}
                      </button>
                      <button
                        onClick={() => setHermesPending(null)}
                        className="text-xs text-muted-foreground hover:text-foreground"
                      >
                        {tc("cancel")}
                      </button>
                    </div>
                  </div>
                )}

                {/* SKILL.md content (skills only) */}
                {selectedItem.kind === "skill" && (
                  <div className="mt-4">
                    <h4 className="mb-2 border-b border-border pb-1 text-xs font-medium text-muted-foreground">
                      {t("detail.documentation")}
                    </h4>
                    <div className="rounded-lg border border-border bg-card p-3">
                      {previewLoading ? (
                        <div className="flex justify-center py-8">
                          <Loader2
                            size={20}
                            className="animate-spin text-muted-foreground"
                          />
                        </div>
                      ) : previewContent ? (
                        <pre
                          onWheel={handleNestedWheel}
                          className="whitespace-pre-wrap text-xs text-muted-foreground max-h-[40vh] overflow-y-auto"
                        >
                          {previewContent}
                        </pre>
                      ) : (
                        <p className="text-xs text-muted-foreground italic">
                          {t("detail.noPreview")}
                        </p>
                      )}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
