"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import type { RefObject } from "react";
import { Button, ButtonLink, RefreshButton, buttonClassName } from "@/components/ui/Button";
import { parseApiResponse } from "@/lib/api-client";
import { grayReleaseConfig } from "@/lib/gray-release";
import { getAllowedSections } from "@/lib/bump/section-policy";
import type { Architecture, ComponentType, Environment, Provider, Region, RegionSyncStatus, SectionKey } from "@/lib/types";

const ENV_FILTER_ORDER: Environment[] = ["prod", "staging", "dev"];
const ARCH_FILTER_ORDER: Architecture[] = ["dedicated", "nextgen", "serverless", "byoc"];
const PROVIDER_FILTER_ORDER: Provider[] = ["aws", "gcp", "azure", "alicloud"];
const COMPONENT_FILTER_ORDER: ComponentType[] = ["acs", "vector", "vmagent"];

const SYNC_STATUS_LABEL: Record<RegionSyncStatus, string> = {
  enabled: "Enabled",
  disabled: "Disabled",
  unknown: "Unknown",
};

const tableHeaderCellClass =
  "px-5 py-2.5 text-left text-xs font-semibold uppercase tracking-wider text-text-muted";
const tableBodyCellClass = "px-5 py-2.5";
const checkboxHeaderCellClass = "px-5 py-2.5 text-left w-10";
const checkboxBodyCellClass = "px-5 py-2.5";
const regionBadgeClass =
  "inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium uppercase";

const architectureBadgeClass: Record<Architecture, string> = {
  dedicated: "bg-arch-dedicated/10 text-arch-dedicated border-arch-dedicated/30",
  nextgen: "bg-arch-nextgen/10 text-arch-nextgen border-arch-nextgen/30",
  serverless: "bg-arch-serverless/10 text-arch-serverless border-arch-serverless/30",
  byoc: "bg-arch-byoc/10 text-arch-byoc border-arch-byoc/30",
};

const syncStatusBadgeClass: Record<RegionSyncStatus, string> = {
  enabled: "bg-success/10 text-success border-success/30",
  disabled: "bg-state-closed/10 text-state-closed border-state-closed/30",
  unknown: "bg-warning/10 text-warning border-warning/30",
};

const sectionBadgeClass: Record<SectionKey, string> = {
  k8s: "border-blue-500/30 bg-blue-500/10 text-blue-400",
  tidbcluster: "border-purple-500/30 bg-purple-500/10 text-purple-400",
  sharedpool: "border-rose-500/30 bg-rose-500/10 text-rose-400",
  tidbgroup: "border-cyan-500/30 bg-cyan-500/10 text-cyan-400",
};

const sectionBadgeBase = "inline-flex items-center rounded-md border px-1.5 py-px text-[11px] font-medium";

const sectionLabel: Record<SectionKey, string> = {
  k8s: "k8s",
  tidbcluster: "tidbcluster",
  sharedpool: "sharedpool",
  tidbgroup: "tidbgroup",
};

function SectionBadge({ section }: { section: SectionKey }) {
  return (
    <span className={`${sectionBadgeBase} ${sectionBadgeClass[section]}`}>
      {sectionLabel[section]}
    </span>
  );
}

function SectionTagCell({ region, component }: { region: Region; component: ComponentType }) {
  const sectionTags = region.sectionComponentTags;
  if (!sectionTags) {
    return <>{region.componentTags[component] || "—"}</>;
  }

  const allowedSections = getAllowedSections(component, [region.architecture]);

  const entries = allowedSections
    .filter((section) => sectionTags[section]?.[component])
    .map((section) => ({ section, tag: sectionTags[section][component]! }));

  if (entries.length === 0) {
    return <>{region.componentTags[component] || "—"}</>;
  }

  // Group all entries with the same tag (preserving section order)
  const groups: { sections: SectionKey[]; tag: string }[] = [];
  const tagIndex = new Map<string, number>();
  for (const { section, tag } of entries) {
    const idx = tagIndex.get(tag);
    if (idx !== undefined) {
      groups[idx].sections.push(section);
    } else {
      tagIndex.set(tag, groups.length);
      groups.push({ sections: [section], tag });
    }
  }

  return (
    <span className="inline-flex items-center gap-1.5 whitespace-nowrap">
      {groups.map((g, i) => (
        <span key={g.tag + i} className="inline-flex items-center gap-0.5">

          {g.sections.map((s) => (
            <span key={s}>

              <SectionBadge section={s} />
            </span>
          ))}

          <span className="ml-1">{g.tag}</span>
        </span>
      ))}
    </span>
  );
}

// ── Skeleton ───────────────────────────────────────────────────────

function RegionsSkeleton() {
  return (
    <div className="space-y-4 animate-pulse">
      <div className="flex items-center justify-between">
        <div className="h-6 w-40 bg-surface-1 rounded" />
        <div className="h-4 w-16 bg-surface-1 rounded" />
      </div>
      <div className="flex gap-3">
        <div className="h-9 flex-1 bg-surface-1 rounded-lg" />
        <div className="h-9 w-36 bg-surface-1 rounded-lg" />
        <div className="h-9 w-36 bg-surface-1 rounded-lg" />
        <div className="h-9 w-36 bg-surface-1 rounded-lg" />
      </div>
      <div className="bg-surface-0 border border-surface-2 rounded-lg overflow-hidden">
        <div className="h-10 bg-surface-1" />
        {Array.from({ length: 8 }).map((_, i) => (
          <div key={i} className="h-9 border-b border-surface-2/50" />
        ))}
      </div>
    </div>
  );
}

// ── Page ───────────────────────────────────────────────────────────

export default function RegionsPage() {
  const [regions, setRegions] = useState<Region[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [search, setSearch] = useState("");
  const [filterArchs, setFilterArchs] = useState<Set<Architecture>>(new Set());
  const [filterEnvs, setFilterEnvs] = useState<Set<Environment>>(new Set());
  const [filterProviders, setFilterProviders] = useState<Set<Provider>>(new Set());
  const [filterComponent, setFilterComponent] = useState<ComponentType>("acs");
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [activeGrayPreset, setActiveGrayPreset] = useState<string | null>(null);
  const archFilterRef = useRef<HTMLDetailsElement>(null);
  const envFilterRef = useRef<HTMLDetailsElement>(null);
  const providerFilterRef = useRef<HTMLDetailsElement>(null);
  const grayReleaseRef = useRef<HTMLDetailsElement>(null);
  const componentFilterRef = useRef<HTMLDetailsElement>(null);

  const grayReleasePresetByRegionId = useMemo(() => {
    const presetByRegionId = new Map<string, string>();
    for (const preset of grayReleaseConfig.presets) {
      for (const regionId of preset.regionIds) {
        presetByRegionId.set(regionId, preset.label);
      }
    }
    return presetByRegionId;
  }, []);

  const closeOtherFilters = (currentRef: RefObject<HTMLDetailsElement | null>) => {
    [
      archFilterRef,
      envFilterRef,
      providerFilterRef,
      grayReleaseRef,
      componentFilterRef,
    ].forEach((ref) => {
      if (ref !== currentRef && ref.current) ref.current.open = false;
    });
  };

  async function fetchRegionsData() {
    const res = await fetch("/api/regions");
    const payload = await parseApiResponse<{ regions: Region[] }>(res);
    if (!payload.ok) {
      throw new Error(payload.error.message || "Failed to load regions");
    }
    return payload.data.regions;
  }

  const refreshRegions = () => {
    setLoading(true);
    setError("");
    fetchRegionsData()
      .then((data) => setRegions(data))
      .catch((e) => setError((e as Error).message))
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    setLoading(true);
    setError("");
    fetchRegionsData()
      .then((data) => setRegions(data))
      .catch((e) => setError((e as Error).message))
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => {
    const refs = [
      archFilterRef,
      envFilterRef,
      providerFilterRef,
      grayReleaseRef,
      componentFilterRef,
    ];

    const closeAllFilters = () => {
      refs.forEach((ref) => {
        if (ref.current) ref.current.open = false;
      });
    };

    const onPointerDown = (event: PointerEvent) => {
      const target = event.target;
      if (!(target instanceof Node)) {
        closeAllFilters();
        return;
      }

      const clickedInsideAnyFilter = refs.some((ref) => {
        return !!ref.current && ref.current.contains(target);
      });
      if (!clickedInsideAnyFilter) closeAllFilters();
    };

    document.addEventListener("pointerdown", onPointerDown, { capture: true });
    return () => {
      document.removeEventListener("pointerdown", onPointerDown, { capture: true });
    };
  }, []);

  const filtered = regions.filter((r) => {
    if (filterArchs.size > 0 && !filterArchs.has(r.architecture)) return false;
    if (filterEnvs.size > 0 && !filterEnvs.has(r.environment)) return false;
    if (filterProviders.size > 0 && !filterProviders.has(r.provider)) return false;
    if (search) {
      const s = search.toLowerCase();
      const tag = r.componentTags[filterComponent] || r.currentTag;
      const sectionTagText =
        filterComponent !== "acs" && r.sectionComponentTags
          ? Object.values(r.sectionComponentTags)
              .map((sc) => sc[filterComponent])
              .filter(Boolean)
              .join(" ")
          : "";
      return (
        r.regionName.toLowerCase().includes(s) ||
        r.directoryPath.toLowerCase().includes(s) ||
        tag.toLowerCase().includes(s) ||
        sectionTagText.toLowerCase().includes(s) ||
        r.provider.toLowerCase().includes(s)
      );
    }
    return true;
  });

  const toggle = (id: string) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
    setActiveGrayPreset(null);
  };

  const selectAll = () => {
    if (selected.size === filtered.length) {
      setSelected(new Set());
    } else {
      setSelected(new Set(filtered.map((r) => r.id)));
    }
    setActiveGrayPreset(null);
  };

  const selectGrayReleasePreset = (presetKey: string, regionIds: string[]) => {
    const presetRegionIds = new Set(regionIds);
    setSelected(
      new Set(
        filtered
          .map((region) => region.id)
          .filter((regionId) => presetRegionIds.has(regionId))
      )
    );
    setActiveGrayPreset(presetKey);
    if (grayReleaseRef.current) grayReleaseRef.current.open = false;
  };

  if (loading) return <RegionsSkeleton />;

  if (error) {
    return (
      <div className="bg-danger-muted border border-danger/20 rounded-lg p-4 flex items-start gap-3">
        <div className="w-5 h-5 rounded-full bg-danger/20 flex items-center justify-center shrink-0 mt-0.5">
          <span className="text-danger text-xs font-bold">!</span>
        </div>
        <div>
          <p className="text-sm text-danger font-medium">{error}</p>
          <Button
            onClick={() => {
              setLoading(true);
              setError("");
              fetchRegionsData()
                .then((data) => setRegions(data))
                .catch((e) => setError((e as Error).message))
                .finally(() => setLoading(false));
            }}
            variant="danger"
            size="sm"
            className="mt-2"
          >
            Try again
          </Button>
        </div>
      </div>
    );
  }

  const componentLabel =
    filterComponent === "acs"
      ? "ACS"
      : filterComponent === "vector"
        ? "Vector"
      : "VMagent";

  const bulkActionClass =
    selected.size === filtered.length && filtered.length > 0
      ? buttonClassName({ variant: "secondary", size: "sm" })
      : buttonClassName({ variant: "primary", size: "sm" });

  return (
    <div className="space-y-6 animate-fade-in">
      <section className="flex items-center">
        <h2 className="text-xl font-semibold tracking-tight">
          Regions{" "}
          <span className="text-text-muted font-normal text-base">
            ({regions.length} total)
          </span>
        </h2>
      </section>

      {/* Filters */}
      <section className="flex w-full gap-3 flex-wrap items-center">
        <div className="relative flex-1 min-w-64">
          <svg
            className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-text-muted pointer-events-none"
            viewBox="0 0 16 16"
            fill="currentColor"
          >
            <path d="M11.742 10.344a6.5 6.5 0 10-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 001.415-1.414l-3.85-3.85a1.007 1.007 0 00-.115-.1zM12 6.5a5.5 5.5 0 11-11 0 5.5 5.5 0 0111 0z" />
          </svg>
          <input
            type="text"
            placeholder="Search regions..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="w-full pl-9 pr-3 py-2 bg-surface-0 border border-surface-2 rounded-lg text-sm placeholder:text-text-muted focus:border-accent focus:ring-1 focus:ring-accent/30 transition-colors outline-none"
            aria-label="Search regions"
          />
        </div>
        <div className="relative min-w-44">
          <details ref={archFilterRef} className="group relative">
            <summary
              aria-label="Filter by architecture"
              onClick={() => closeOtherFilters(archFilterRef)}
              className="list-none px-3 py-2 bg-surface-0 border border-surface-2 rounded-lg text-sm text-text-secondary cursor-pointer hover:bg-surface-1 focus-visible:outline-none focus-visible:border-accent transition-colors flex items-center justify-between gap-2 [&::-webkit-details-marker]:hidden"
            >
              <span className="flex items-center gap-1.5 min-w-0">
                <span className="text-xs font-medium text-text-muted shrink-0">
                  Architectures
                </span>
                {filterArchs.size === 0 ? (
                  <span className="text-text-secondary">All</span>
                ) : (
                  ARCH_FILTER_ORDER.filter((arch) => filterArchs.has(arch)).map((arch) => (
                    <span
                      key={arch}
                      className="px-1.5 py-0.5 rounded-md bg-accent/10 text-accent text-xs uppercase tracking-wide"
                    >
                      {arch}
                    </span>
                  ))
                )}
              </span>
              <span className="text-text-muted text-xs shrink-0 group-open:rotate-180 transition-transform">
                ▾
              </span>
            </summary>

            <div className="absolute z-20 mt-1 w-44 rounded-lg border border-surface-2 bg-surface-0 shadow-lg p-2">
              {ARCH_FILTER_ORDER.map((arch) => (
                <label
                  key={arch}
                  className="flex items-center justify-between gap-2 px-2 py-1.5 rounded-md text-sm text-text-secondary hover:bg-surface-1 cursor-pointer"
                >
                  <span className="uppercase tracking-wide">{arch}</span>
                  <span className="relative inline-flex">
                    <input
                      type="checkbox"
                      aria-label={`Architecture ${arch}`}
                      checked={filterArchs.has(arch)}
                      onChange={() => {
                        setFilterArchs((prev) => {
                          const next = new Set(prev);
                          if (next.has(arch)) next.delete(arch);
                          else next.add(arch);
                          return next;
                        });
                      }}
                      className="peer sr-only"
                    />
                    <span className="w-4 h-4 rounded border border-surface-2 bg-surface-1 peer-checked:bg-accent peer-checked:border-accent transition-colors" />
                    <span className="absolute inset-0 grid place-items-center text-[10px] text-white opacity-0 peer-checked:opacity-100 transition-opacity">
                      ✓
                    </span>
                  </span>
                </label>
              ))}

              <div className="mt-2 pt-2 border-t border-surface-2 flex items-center justify-between gap-2 text-xs">
                <span className="text-text-muted">
                  {filterArchs.size === 0 ? "Showing all" : `${filterArchs.size} selected`}
                </span>
                <button
                  type="button"
                  onClick={() => setFilterArchs(new Set())}
                  disabled={filterArchs.size === 0}
                  className="px-2 py-1 rounded-md border border-surface-2 text-text-secondary hover:bg-surface-1 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  Clear
                </button>
              </div>
            </div>
          </details>
        </div>
        <div className="relative min-w-44">
          <details ref={envFilterRef} className="group relative">
            <summary
              aria-label="Filter by environment"
              onClick={() => closeOtherFilters(envFilterRef)}
              className="list-none px-3 py-2 bg-surface-0 border border-surface-2 rounded-lg text-sm text-text-secondary cursor-pointer hover:bg-surface-1 focus-visible:outline-none focus-visible:border-accent transition-colors flex items-center justify-between gap-2 [&::-webkit-details-marker]:hidden"
            >
              <span className="flex items-center gap-1.5 min-w-0">
                <span className="text-xs font-medium text-text-muted shrink-0">
                  Environments
                </span>
                {filterEnvs.size === 0 ? (
                  <span className="text-text-secondary">All</span>
                ) : (
                  ENV_FILTER_ORDER.filter((env) => filterEnvs.has(env)).map((env) => (
                    <span
                      key={env}
                      className="px-1.5 py-0.5 rounded-md bg-accent/10 text-accent text-xs uppercase tracking-wide"
                    >
                      {env}
                    </span>
                  ))
                )}
              </span>
              <span className="text-text-muted text-xs shrink-0 group-open:rotate-180 transition-transform">
                ▾
              </span>
            </summary>

            <div className="absolute z-20 mt-1 w-40 rounded-lg border border-surface-2 bg-surface-0 shadow-lg p-2">
              {ENV_FILTER_ORDER.map((env) => (
                <label
                  key={env}
                  className="flex items-center justify-between gap-2 px-2 py-1.5 rounded-md text-sm text-text-secondary hover:bg-surface-1 cursor-pointer"
                >
                  <span className="uppercase tracking-wide">{env}</span>
                  <span className="relative inline-flex">
                    <input
                      type="checkbox"
                      aria-label={`Environment ${env}`}
                      checked={filterEnvs.has(env)}
                      onChange={() => {
                        setFilterEnvs((prev) => {
                          const next = new Set(prev);
                          if (next.has(env)) next.delete(env);
                          else next.add(env);
                          return next;
                        });
                      }}
                      className="peer sr-only"
                    />
                    <span className="w-4 h-4 rounded border border-surface-2 bg-surface-1 peer-checked:bg-accent peer-checked:border-accent transition-colors" />
                    <span className="absolute inset-0 grid place-items-center text-[10px] text-white opacity-0 peer-checked:opacity-100 transition-opacity">
                      ✓
                    </span>
                  </span>
                </label>
              ))}

              <div className="mt-2 pt-2 border-t border-surface-2 flex items-center justify-between gap-2 text-xs">
                <span className="text-text-muted">
                  {filterEnvs.size === 0 ? "Showing all" : `${filterEnvs.size} selected`}
                </span>
                <button
                  type="button"
                  onClick={() => setFilterEnvs(new Set())}
                  disabled={filterEnvs.size === 0}
                  className="px-2 py-1 rounded-md border border-surface-2 text-text-secondary hover:bg-surface-1 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  Clear
                </button>
              </div>
            </div>
          </details>
        </div>
        <div className="relative min-w-40">
          <details ref={providerFilterRef} className="group relative">
            <summary
              aria-label="Filter by provider"
              onClick={() => closeOtherFilters(providerFilterRef)}
              className="list-none px-3 py-2 bg-surface-0 border border-surface-2 rounded-lg text-sm text-text-secondary cursor-pointer hover:bg-surface-1 focus-visible:outline-none focus-visible:border-accent transition-colors flex items-center justify-between gap-2 [&::-webkit-details-marker]:hidden"
            >
              <span className="flex items-center gap-1.5 min-w-0">
                <span className="text-xs font-medium text-text-muted shrink-0">
                  Providers
                </span>
                {filterProviders.size === 0 ? (
                  <span className="text-text-secondary">All</span>
                ) : (
                  PROVIDER_FILTER_ORDER.filter((provider) => filterProviders.has(provider)).map(
                    (provider) => (
                      <span
                        key={provider}
                        className="px-1.5 py-0.5 rounded-md bg-accent/10 text-accent text-xs uppercase tracking-wide"
                      >
                        {provider}
                      </span>
                    )
                  )
                )}
              </span>
              <span className="text-text-muted text-xs shrink-0 group-open:rotate-180 transition-transform">
                ▾
              </span>
            </summary>

            <div className="absolute z-20 mt-1 w-40 rounded-lg border border-surface-2 bg-surface-0 shadow-lg p-2">
              {PROVIDER_FILTER_ORDER.map((provider) => (
                <label
                  key={provider}
                  className="flex items-center justify-between gap-2 px-2 py-1.5 rounded-md text-sm text-text-secondary hover:bg-surface-1 cursor-pointer"
                >
                  <span className="uppercase tracking-wide">{provider}</span>
                  <span className="relative inline-flex">
                    <input
                      type="checkbox"
                      aria-label={`Provider ${provider}`}
                      checked={filterProviders.has(provider)}
                      onChange={() => {
                        setFilterProviders((prev) => {
                          const next = new Set(prev);
                          if (next.has(provider)) next.delete(provider);
                          else next.add(provider);
                          return next;
                        });
                      }}
                      className="peer sr-only"
                    />
                    <span className="w-4 h-4 rounded border border-surface-2 bg-surface-1 peer-checked:bg-accent peer-checked:border-accent transition-colors" />
                    <span className="absolute inset-0 grid place-items-center text-[10px] text-white opacity-0 peer-checked:opacity-100 transition-opacity">
                      ✓
                    </span>
                  </span>
                </label>
              ))}

              <div className="mt-2 pt-2 border-t border-surface-2 flex items-center justify-between gap-2 text-xs">
                <span className="text-text-muted">
                  {filterProviders.size === 0
                    ? "Showing all"
                    : `${filterProviders.size} selected`}
                </span>
                <button
                  type="button"
                  onClick={() => setFilterProviders(new Set())}
                  disabled={filterProviders.size === 0}
                  className="px-2 py-1 rounded-md border border-surface-2 text-text-secondary hover:bg-surface-1 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  Clear
                </button>
              </div>
            </div>
          </details>
        </div>
        {grayReleaseConfig.presets.length > 0 && (
          <div className="relative min-w-44">
            <details ref={grayReleaseRef} className="group relative">
              <summary
                aria-label="Select gray release preset"
                onClick={() => closeOtherFilters(grayReleaseRef)}
                className="list-none px-3 py-2 bg-surface-0 border border-surface-2 rounded-lg text-sm text-text-secondary cursor-pointer hover:bg-surface-1 focus-visible:outline-none focus-visible:border-accent transition-colors flex items-center justify-between gap-2 [&::-webkit-details-marker]:hidden"
              >
                <span className="flex items-center gap-1.5 min-w-0">
                  <span className="text-xs font-medium text-text-muted shrink-0">
                    Gray Release
                  </span>
                  {activeGrayPreset ? (
                    <span className="px-1.5 py-0.5 rounded-md bg-accent/10 text-accent text-xs uppercase tracking-wide">                      {activeGrayPreset}
                    </span>
                  ) : (
                    <span className="text-text-secondary">Unset</span>
                  )}
                </span>
                <span className="text-text-muted text-xs shrink-0 group-open:rotate-180 transition-transform">
                  ▾
                </span>
              </summary>

              <div className="absolute z-20 mt-1 w-44 rounded-lg border border-surface-2 bg-surface-0 shadow-lg p-2">
                {grayReleaseConfig.presets.map((preset) => {
                  const presetRegionIds = new Set(preset.regionIds);
                  const availableCount = filtered.filter((region) =>
                    presetRegionIds.has(region.id)
                  ).length;

                  return (
                    <button
                      key={preset.key}
                      type="button"
                      aria-label={`Select gray release ${preset.label}`}
                      onClick={() => selectGrayReleasePreset(preset.key, preset.regionIds)}
                      className="w-full flex items-center justify-between gap-3 px-2 py-1.5 rounded-md text-sm text-text-secondary hover:bg-surface-1 cursor-pointer"
                    >
                      <span className="uppercase tracking-wide">{preset.label}</span>
                      <span className="text-xs text-text-muted">
                        {availableCount}/{preset.regionIds.length}
                      </span>
                    </button>
                  );
                })}

                <div className="mt-2 pt-2 border-t border-surface-2 flex items-center justify-between gap-2 text-xs">
                  <span className="text-text-muted">
                    {activeGrayPreset ? `${activeGrayPreset} selected` : "Unset"}
                  </span>
                  <button
                    type="button"
                    onClick={() => { setActiveGrayPreset(null); setSelected(new Set()); }}
                    disabled={!activeGrayPreset}
                    className="px-2 py-1 rounded-md border border-surface-2 text-text-secondary hover:bg-surface-1 disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    Clear
                  </button>
                </div>
              </div>
            </details>
          </div>
        )}
        <div className="relative w-44">
          <details ref={componentFilterRef} className="group relative">
            <summary
              aria-label="Filter by component"
              onClick={() => closeOtherFilters(componentFilterRef)}
              className="list-none px-3 py-2 bg-surface-0 border border-surface-2 rounded-lg text-sm text-text-secondary cursor-pointer hover:bg-surface-1 focus-visible:outline-none focus-visible:border-accent transition-colors flex items-center justify-between gap-2 [&::-webkit-details-marker]:hidden"
            >
              <span className="flex items-center gap-1.5 min-w-0">
                <span className="text-xs font-medium text-text-muted shrink-0">
                  Component
                </span>
                <span className="text-text-secondary">{componentLabel}</span>
              </span>
              <span className="text-text-muted text-xs shrink-0 group-open:rotate-180 transition-transform">
                ▾
              </span>
            </summary>

            <div className="absolute z-20 mt-1 w-36 rounded-lg border border-surface-2 bg-surface-0 shadow-lg p-2">
              {COMPONENT_FILTER_ORDER.map((component) => {
                const label =
                  component === "acs" ? "ACS" : component === "vector" ? "Vector" : "VMagent";
                const selectedComponent = filterComponent === component;

                return (
                  <button
                    key={component}
                    type="button"
                    aria-label={`Select component ${label}`}
                    aria-pressed={selectedComponent}
                    onClick={() => {
                      setFilterComponent(component);
                      if (componentFilterRef.current) componentFilterRef.current.open = false;
                    }}
                    className={`w-full flex items-center justify-between gap-2 px-2 py-1.5 rounded-md text-sm cursor-pointer hover:bg-surface-1 ${
                      selectedComponent ? "text-accent" : "text-text-secondary"
                    }`}
                  >
                    <span>{label}</span>
                    {selectedComponent ? (
                      <span className="text-xs text-accent">✓</span>
                    ) : null}
                  </button>
                );
              })}
            </div>
          </details>
        </div>
        <RefreshButton
          aria-label="Refresh"
          disabled={loading}
          onClick={refreshRegions}
          busy={loading}
        />
      </section>

      {/* Selection action bar */}
      <section>
      {selected.size > 0 ? (
        <div className="bg-accent-muted border border-accent/20 rounded-lg px-4 py-2.5 flex items-center gap-3 animate-fade-in">
          <span className="text-sm text-accent font-medium">
            {selected.size} selected
          </span>
          <span className="text-text-muted text-sm">
            of {filtered.length} shown
          </span>
          <button
            onClick={() => setSelected(new Set())}
            className="inline-flex items-center gap-1 text-sm text-text-muted hover:text-accent transition-colors"
          >
            <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor">
              <path d="M5.5 5.5A.5.5 0 016 6v6a.5.5 0 01-1 0V6a.5.5 0 01.5-.5zm2.5 0a.5.5 0 01.5.5v6a.5.5 0 01-1 0V6a.5.5 0 01.5-.5zm3 .5a.5.5 0 00-1 0v6a.5.5 0 001 0V6z" />
              <path fillRule="evenodd" d="M14.5 3a1 1 0 01-1 1H13v9a2 2 0 01-2 2H5a2 2 0 01-2-2V4h-.5a1 1 0 01-1-1V2a1 1 0 011-1H5.5a1 1 0 011-1h3a1 1 0 011 1h2.5a1 1 0 011 1v1zM4.118 4L4 4.059V13a1 1 0 001 1h6a1 1 0 001-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
            </svg>
            Clear
          </button>
          <div className="flex-1" />
          <ButtonLink
            href={`/bump?regions=${encodeURIComponent(Array.from(selected).join(","))}`}
            size="sm"
          >
            Bump
          </ButtonLink>
          <ButtonLink
            href={`/observe?regions=${encodeURIComponent(Array.from(selected).join(","))}&component=acs`}
            variant="subtle"
            size="sm"
          >
            Observe
          </ButtonLink>
          <ButtonLink
            href={`/agents?regions=${encodeURIComponent(Array.from(selected).join(","))}`}
            variant="subtle"
            size="sm"
          >
            Agents
          </ButtonLink>
        </div>
      ) : (
        <div className="flex items-center gap-2 text-sm">
          <button
            onClick={selectAll}
            className={bulkActionClass}
          >
            {selected.size === filtered.length ? "Deselect All" : "Select All"}
          </button>
          <span className="text-text-muted">
            {filtered.length} regions shown
          </span>
        </div>
      )}
      </section>

      {/* Table */}
      <section className="bg-surface-0 rounded-lg border border-surface-2 overflow-hidden">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-surface-2">
              <th className={checkboxHeaderCellClass}></th>
              <th className={tableHeaderCellClass}>
                Architecture
              </th>
              <th className={tableHeaderCellClass}>
                Environment
              </th>
              <th className={tableHeaderCellClass}>
                Provider
              </th>
              <th className={tableHeaderCellClass}>
                Region
              </th>
              <th className={tableHeaderCellClass}>
                Sync
              </th>
              <th className={tableHeaderCellClass}>
                Tag ({componentLabel})
              </th>
            </tr>
          </thead>
          <tbody>
            {filtered.map((r) => {
              const syncStatus: RegionSyncStatus = r.syncStatus ?? "unknown";
              const grayReleasePresetLabel = grayReleasePresetByRegionId.get(r.id);
              const syncStatusClass = syncStatusBadgeClass[syncStatus];

              const unknownHint =
                syncStatus === "unknown"
                  ? r.syncStatusReason ||
                    `Failed to load sync source: ${r.syncStatusSource || "unknown source"}`
                  : undefined;

              return (
                <tr
                  key={r.id}
                  className={`border-b border-surface-2/50 last:border-0 transition-colors ${
                    selected.has(r.id)
                      ? "bg-accent/5"
                      : "hover:bg-surface-1"
                  }`}
                >
                  <td className={checkboxBodyCellClass}>
                    <input
                      type="checkbox"
                      checked={selected.has(r.id)}
                      onChange={() => toggle(r.id)}
                      aria-label={`Select ${r.regionName}`}
                      className="accent-accent"
                    />
                  </td>
                  <td className={tableBodyCellClass}>
                    <span
                      className={`${regionBadgeClass} ${architectureBadgeClass[r.architecture]}`}
                    >
                      {r.architecture}
                    </span>
                  </td>
                  <td className={`${tableBodyCellClass} text-text-secondary`}>
                    {r.environment}
                  </td>
                  <td className={`${tableBodyCellClass} text-text-secondary`}>
                    {r.provider}
                  </td>
                  <td className={tableBodyCellClass}>
                    <span className="inline-flex items-center gap-2">
                      <span className="font-mono text-[13px] text-accent">{r.regionName}</span>
                      {grayReleasePresetLabel ? (
                        <span
                          aria-label={`${r.regionName} is in ${grayReleasePresetLabel} gray release preset`}
                          title={`Built-in ${grayReleasePresetLabel} gray release region`}
                          className={`${regionBadgeClass} border-text-muted/30 bg-text-muted/10 text-text-muted`}
                        >
                          Gray
                        </span>
                      ) : null}
                    </span>
                  </td>
                  <td className={tableBodyCellClass}>
                    <span
                      title={unknownHint}
                      className={`${regionBadgeClass} ${syncStatusClass}`}
                    >
                      {SYNC_STATUS_LABEL[syncStatus]}
                    </span>
                  </td>
                  <td className={`${tableBodyCellClass} font-mono text-[13px] text-text-secondary`}>
                    {filterComponent === "acs"
                      ? (r.componentTags.acs || "—")
                      : <SectionTagCell region={r} component={filterComponent} />}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </section>
    </div>
  );
}
