"use client";

import Link from "next/link";
import { Suspense, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
import { useSearchParams } from "next/navigation";
import { Button } from "@/components/Button";
import { DashboardPageContainer } from "@/components/dashboard/DashboardPageContainer";
import { DashboardShell } from "@/components/dashboard/DashboardShell";
import { InviteCreatorDialog } from "@/components/dashboard/InviteCreatorDialog";
import { EmptyState } from "@/components/ui/EmptyState";
import { ErrorState } from "@/components/ui/ErrorState";
import { fieldClassName } from "@/components/ui/field-styles";
import { PageHeader, SectionHeader } from "@/components/ui/PageHeader";
import { Skeleton } from "@/components/ui/Skeleton";
import { creatorSearchApi, publicProfilePath } from "@/lib/api";
import { cn } from "@/lib/cn";
import { CREATOR_NICHE_OPTIONS, publicCreatorFactsLine } from "@/lib/creator-personal-info";
import { formatMetricCount, formatMetricPercent } from "@/lib/format";
import { SOCIAL_PROVIDERS, socialProviderLabel } from "@/lib/social-providers";
import type { CreatorSearchMeta, SearchCreator } from "@/types/profile";

type FilterState = {
  platforms: string[];
  niche: string;
  followers: string;
  engagement: string;
  country: string;
};

const defaultFilters: FilterState = {
  platforms: [],
  niche: "all",
  followers: "any",
  engagement: "any",
  country: "any",
};

function filtersFromSearchParams(params: { get: (key: string) => string | null }): FilterState {
  const platformKeys = new Set<string>(SOCIAL_PROVIDERS.map((provider) => provider.key));
  const platforms = (params.get("platforms") ?? "")
    .split(",")
    .map((value) => value.trim())
    .filter((value) => platformKeys.has(value));
  const nicheParam = params.get("niche");
  const niche = CREATOR_NICHE_OPTIONS.some((option) => option.value === nicheParam)
    ? (nicheParam as string)
    : "all";
  const countryParam = params.get("country");
  const country =
    countryParam === "us" || countryParam === "uk" || countryParam === "ca" ? countryParam : "any";

  return {
    ...defaultFilters,
    platforms,
    niche,
    country,
  };
}

const PER_PAGE = 20;

function nicheLabel(value: string | null): string {
  if (!value) {
    return "—";
  }

  return CREATOR_NICHE_OPTIONS.find((option) => option.value === value)?.label ?? value;
}

function platformsLabel(platforms: string[]): string {
  if (platforms.length === 0) {
    return "—";
  }

  return platforms.map((platform) => socialProviderLabel(platform)).join(", ");
}

function countActiveFilters(filters: FilterState): number {
  let count = 0;
  if (filters.platforms.length > 0) count += 1;
  if (filters.niche !== "all") count += 1;
  if (filters.country !== "any") count += 1;
  if (filters.followers !== "any") count += 1;
  if (filters.engagement !== "any") count += 1;
  return count;
}

function pageWindow(current: number, last: number): (number | "ellipsis")[] {
  if (last <= 7) {
    return Array.from({ length: last }, (_, index) => index + 1);
  }

  const pages = new Set<number>([1, last, current, current - 1, current + 1]);
  if (current <= 3) {
    pages.add(2);
    pages.add(3);
    pages.add(4);
  }
  if (current >= last - 2) {
    pages.add(last - 1);
    pages.add(last - 2);
    pages.add(last - 3);
  }

  const sorted = [...pages].filter((page) => page >= 1 && page <= last).sort((a, b) => a - b);
  const result: (number | "ellipsis")[] = [];

  for (let index = 0; index < sorted.length; index += 1) {
    const page = sorted[index];
    const previous = sorted[index - 1];
    if (previous !== undefined && page - previous > 1) {
      result.push("ellipsis");
    }
    result.push(page);
  }

  return result;
}

function CreatorAvatar({ name, src }: { name: string; src: string | null }) {
  if (src) {
    return (
      // eslint-disable-next-line @next/next/no-img-element
      <img className="size-9 shrink-0 rounded-full object-cover bg-line" alt="" src={src} />
    );
  }

  return (
    <span className="inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-primary text-[0.6875rem] font-semibold text-white">
      {name.slice(0, 2).toUpperCase()}
    </span>
  );
}

function DiscoverSkeleton() {
  return (
    <div className="space-y-2" aria-busy="true" aria-live="polite">
      <div className="hidden overflow-hidden rounded-pv border border-line bg-surface md:block">
        {Array.from({ length: 6 }).map((_, index) => (
          <div
            key={index}
            className="grid grid-cols-[minmax(12rem,1.6fr)_0.9fr_0.9fr_0.9fr_0.7fr_0.7fr_6.5rem] items-center gap-3 border-b border-line px-3 py-3 last:border-b-0"
          >
            <div className="flex items-center gap-2.5">
              <Skeleton className="size-9 shrink-0 rounded-full" />
              <div className="min-w-0 flex-1 space-y-1.5">
                <Skeleton className="h-3.5 w-28" />
                <Skeleton className="h-3 w-20" />
              </div>
            </div>
            <Skeleton className="h-3.5 w-16" />
            <Skeleton className="h-3.5 w-20" />
            <Skeleton className="h-3.5 w-24" />
            <Skeleton className="h-3.5 w-12" />
            <Skeleton className="h-3.5 w-10" />
            <Skeleton className="ml-auto h-8 w-24" />
          </div>
        ))}
      </div>
      <div className="space-y-2 md:hidden">
        {Array.from({ length: 4 }).map((_, index) => (
          <div key={index} className="rounded-pv border border-line bg-surface p-3">
            <div className="flex items-center gap-2.5">
              <Skeleton className="size-9 shrink-0 rounded-full" />
              <div className="min-w-0 flex-1 space-y-1.5">
                <Skeleton className="h-3.5 w-28" />
                <Skeleton className="h-3 w-20" />
              </div>
            </div>
            <div className="mt-3 grid grid-cols-2 gap-2">
              <Skeleton className="h-3 w-20" />
              <Skeleton className="h-3 w-16" />
              <Skeleton className="h-3 w-24" />
              <Skeleton className="h-3 w-14" />
            </div>
            <Skeleton className="mt-3 h-8 w-full" />
          </div>
        ))}
      </div>
      <p className="sr-only">Loading creators…</p>
    </div>
  );
}

function FilterSelects({
  filters,
  onChange,
  idPrefix,
}: {
  filters: FilterState;
  onChange: <K extends keyof FilterState>(key: K, value: FilterState[K]) => void;
  idPrefix: string;
}) {
  const selectClass = fieldClassName;

  function togglePlatform(platform: string) {
    const exists = filters.platforms.includes(platform);
    onChange(
      "platforms",
      exists
        ? filters.platforms.filter((item) => item !== platform)
        : [...filters.platforms, platform],
    );
  }

  return (
    <>
      <fieldset className="col-span-full flex min-w-0 flex-col gap-1">
        <legend className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
          Platform
        </legend>
        <div id={`${idPrefix}-platforms`} className="flex flex-wrap gap-1.5">
          {SOCIAL_PROVIDERS.map((provider) => {
            const selected = filters.platforms.includes(provider.key);
            return (
              <button
                key={provider.key}
                type="button"
                aria-pressed={selected}
                className={cn(
                  "inline-flex h-10 items-center rounded-pv border px-2.5 text-[0.8125rem] font-medium transition focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
                  selected
                    ? "border-accent bg-accent text-white"
                    : "border-line bg-surface text-ink-60 hover:border-primary/40",
                )}
                onClick={() => togglePlatform(provider.key)}
              >
                {provider.label}
              </button>
            );
          })}
        </div>
      </fieldset>
      <label className="flex min-w-0 flex-col gap-1">
        <span className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
          Category
        </span>
        <select
          id={`${idPrefix}-category`}
          className={selectClass}
          value={filters.niche}
          onChange={(event) => onChange("niche", event.target.value)}
        >
          <option value="all">All</option>
          {CREATOR_NICHE_OPTIONS.map((option) => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
      </label>
      <label className="flex min-w-0 flex-col gap-1">
        <span className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
          Country
        </span>
        <select
          id={`${idPrefix}-country`}
          className={selectClass}
          value={filters.country}
          onChange={(event) => onChange("country", event.target.value)}
        >
          <option value="any">All</option>
          <option value="us">United States</option>
          <option value="uk">United Kingdom</option>
          <option value="ca">Canada</option>
        </select>
      </label>
      <label className="flex min-w-0 flex-col gap-1">
        <span className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
          Followers
        </span>
        <select
          id={`${idPrefix}-followers`}
          className={selectClass}
          value={filters.followers}
          onChange={(event) => onChange("followers", event.target.value)}
        >
          <option value="any">All</option>
          <option value="under-10k">Under 10K</option>
          <option value="10k-1m">10K – 1M</option>
          <option value="1m-plus">1M+</option>
        </select>
      </label>
      <label className="flex min-w-0 flex-col gap-1">
        <span className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
          Engagement
        </span>
        <select
          id={`${idPrefix}-engagement`}
          className={selectClass}
          value={filters.engagement}
          onChange={(event) => onChange("engagement", event.target.value)}
        >
          <option value="any">All</option>
          <option value="1-10">1% – 10%</option>
          <option value="10-plus">10%+</option>
        </select>
      </label>
    </>
  );
}

function FiltersSheet({
  open,
  filters,
  draft,
  onDraftChange,
  onApply,
  onClear,
  onClose,
}: {
  open: boolean;
  filters: FilterState;
  draft: FilterState;
  onDraftChange: <K extends keyof FilterState>(key: K, value: FilterState[K]) => void;
  onApply: () => void;
  onClear: () => void;
  onClose: () => void;
}) {
  const titleId = useId();
  const activeCount = countActiveFilters(filters);

  useEffect(() => {
    document.body.classList.toggle("overflow-hidden", open);
    return () => document.body.classList.remove("overflow-hidden");
  }, [open]);

  useEffect(() => {
    if (!open) {
      return;
    }

    function onKey(event: KeyboardEvent) {
      if (event.key === "Escape") {
        onClose();
      }
    }

    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  if (!open) {
    return null;
  }

  return (
    <div className="fixed inset-0 z-50 md:hidden">
      <button
        type="button"
        className="absolute inset-0 bg-primary/35"
        aria-label="Close filters"
        onClick={onClose}
      />
      <div
        className="absolute inset-x-0 bottom-0 max-h-[85dvh] overflow-y-auto rounded-t-pv border border-line bg-surface p-4 shadow-[0_-12px_32px_-18px_rgba(23,37,84,0.45)]"
        role="dialog"
        aria-modal="true"
        aria-labelledby={titleId}
      >
        <div className="mb-3 flex items-center justify-between gap-2">
          <h2 id={titleId} className="text-[0.9375rem] font-semibold text-primary">
            Filters{activeCount > 0 ? ` · ${activeCount}` : ""}
          </h2>
          <button
            type="button"
            className="text-[0.8125rem] font-medium text-ink-60 hover:text-primary"
            onClick={onClose}
          >
            Close
          </button>
        </div>
        <div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2">
          <FilterSelects filters={draft} onChange={onDraftChange} idPrefix="mobile-filter" />
        </div>
        <div className="mt-4 flex items-center gap-2">
          <Button type="button" className="flex-1" size="sm" onClick={onApply}>
            Apply filters
          </Button>
          <Button type="button" className="flex-1" size="sm" variant="secondary" onClick={onClear}>
            Clear filters
          </Button>
        </div>
      </div>
    </div>
  );
}

function ResultsPagination({
  meta,
  onPageChange,
}: {
  meta: CreatorSearchMeta;
  onPageChange: (page: number) => void;
}) {
  if (meta.total === 0 || meta.last_page <= 1) {
    return null;
  }

  const from = (meta.current_page - 1) * meta.per_page + 1;
  const to = Math.min(meta.current_page * meta.per_page, meta.total);
  const pages = pageWindow(meta.current_page, meta.last_page);

  return (
    <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
      <p className="text-[0.8125rem] text-ink-60">
        Showing {from}–{to} of {meta.total}
      </p>
      <nav className="flex flex-wrap items-center gap-1" aria-label="Pagination">
        <button
          type="button"
          className="h-8 rounded-pv border border-line bg-surface px-2.5 text-[0.8125rem] font-medium text-primary hover:border-primary disabled:cursor-not-allowed disabled:opacity-50"
          disabled={meta.current_page <= 1}
          onClick={() => onPageChange(meta.current_page - 1)}
        >
          Previous
        </button>
        {pages.map((page, index) =>
          page === "ellipsis" ? (
            <span key={`ellipsis-${index}`} className="px-1 text-[0.8125rem] text-ink-40">
              …
            </span>
          ) : (
            <button
              key={page}
              type="button"
              aria-current={page === meta.current_page ? "page" : undefined}
              className={cn(
                "h-8 min-w-8 rounded-pv border px-2 text-[0.8125rem] font-medium tabular-nums",
                page === meta.current_page
                  ? "border-primary bg-primary text-white"
                  : "border-line bg-surface text-primary hover:border-primary",
              )}
              onClick={() => onPageChange(page)}
            >
              {page}
            </button>
          ),
        )}
        <button
          type="button"
          className="h-8 rounded-pv border border-line bg-surface px-2.5 text-[0.8125rem] font-medium text-primary hover:border-primary disabled:cursor-not-allowed disabled:opacity-50"
          disabled={meta.current_page >= meta.last_page}
          onClick={() => onPageChange(meta.current_page + 1)}
        >
          Next
        </button>
      </nav>
    </div>
  );
}

function CreatorResultCard({
  creator,
  onInvite,
}: {
  creator: SearchCreator;
  onInvite: (username: string) => void;
}) {
  const name = creator.display_name?.trim() || creator.username;
  const facts = publicCreatorFactsLine(creator.gender, creator.gender_label, creator.age);
  const category = nicheLabel(creator.niche);
  const platforms = platformsLabel(creator.platforms);

  return (
    <article className="rounded-pv border border-line bg-surface p-3">
      <div className="flex min-w-0 items-start gap-2.5">
        <CreatorAvatar name={name} src={creator.profile_image} />
        <div className="min-w-0 flex-1">
          <p className="truncate text-[0.875rem] font-medium text-primary">{name}</p>
          <p className="truncate text-[0.75rem] text-ink-60">@{creator.username}</p>
          {facts ? <p className="mt-0.5 truncate text-[0.6875rem] text-ink-40">{facts}</p> : null}
        </div>
      </div>
      <dl className="mt-3 grid grid-cols-2 gap-x-3 gap-y-1.5 text-[0.75rem]">
        <div>
          <dt className="text-ink-40">Platform</dt>
          <dd className="font-medium text-primary">{platforms}</dd>
        </div>
        <div>
          <dt className="text-ink-40">Category</dt>
          <dd className="font-medium text-primary">{category}</dd>
        </div>
        <div>
          <dt className="text-ink-40">Country</dt>
          <dd className="font-medium text-primary">{creator.country || "—"}</dd>
        </div>
        <div>
          <dt className="text-ink-40">Followers</dt>
          <dd className="font-medium tabular-nums text-primary">
            {formatMetricCount(creator.followers)}
          </dd>
        </div>
        <div>
          <dt className="text-ink-40">Engagement</dt>
          <dd className="font-medium tabular-nums text-primary">
            {formatMetricPercent(creator.engagement_rate)}
          </dd>
        </div>
      </dl>
      <div className="mt-3 flex flex-col gap-2">
        <Button
          type="button"
          size="sm"
          className="w-full"
          onClick={() => onInvite(creator.username)}
        >
          Invite
        </Button>
        <Button
          href={publicProfilePath(creator.username, { from: "discover" })}
          size="sm"
          variant="secondary"
          className="w-full"
        >
          View profile
        </Button>
      </div>
    </article>
  );
}

function BrandDiscoverContent() {
  const searchParams = useSearchParams();
  const initialFilters = filtersFromSearchParams(searchParams);
  const campaignParam = Number.parseInt(searchParams.get("campaign") ?? "", 10);
  const preferredCampaignId =
    Number.isInteger(campaignParam) && campaignParam > 0 ? campaignParam : null;
  const [searchInput, setSearchInput] = useState("");
  const [debouncedQ, setDebouncedQ] = useState("");
  const [filters, setFilters] = useState<FilterState>(initialFilters);
  const [draftFilters, setDraftFilters] = useState<FilterState>(initialFilters);
  const [filtersOpen, setFiltersOpen] = useState(false);
  const [creators, setCreators] = useState<SearchCreator[]>([]);
  const [meta, setMeta] = useState<CreatorSearchMeta | null>(null);
  const [page, setPage] = useState(1);
  const [isLoading, setIsLoading] = useState(true);
  const [loadError, setLoadError] = useState(false);
  const [sortKey, setSortKey] = useState<"followers" | "views">("followers");
  const [sortDir, setSortDir] = useState<"asc" | "desc">("desc");
  const [inviteUsername, setInviteUsername] = useState<string | null>(null);
  const requestIdRef = useRef(0);
  const searchInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    const timeout = window.setTimeout(() => {
      const next = searchInput.trim();
      setDebouncedQ((previous) => {
        if (previous !== next) {
          setPage(1);
        }
        return next;
      });
    }, 300);
    return () => window.clearTimeout(timeout);
  }, [searchInput]);

  const activeFilterCount = useMemo(() => countActiveFilters(filters), [filters]);

  const load = useCallback(
    async (pageToLoad: number) => {
      const requestId = requestIdRef.current + 1;
      requestIdRef.current = requestId;
      setIsLoading(true);
      setLoadError(false);

      try {
        const results = await creatorSearchApi.search({
          q: debouncedQ,
          platforms: filters.platforms,
          niche: filters.niche,
          country: filters.country,
          followers: filters.followers,
          engagement: filters.engagement,
          sort: sortKey,
          sort_dir: sortDir,
          page: pageToLoad,
          per_page: PER_PAGE,
        });

        if (requestId !== requestIdRef.current) {
          return;
        }

        setMeta(results.meta);
        setCreators(results.creators);
      } catch {
        if (requestId !== requestIdRef.current) {
          return;
        }

        setCreators([]);
        setMeta(null);
        setLoadError(true);
      } finally {
        if (requestId === requestIdRef.current) {
          setIsLoading(false);
        }
      }
    },
    [debouncedQ, filters, sortDir, sortKey],
  );

  useEffect(() => {
    void load(page);
  }, [load, page]);

  function updateFilter<K extends keyof FilterState>(key: K, value: FilterState[K]) {
    setFilters((current) => ({ ...current, [key]: value }));
    setPage(1);
  }

  function updateDraftFilter<K extends keyof FilterState>(key: K, value: FilterState[K]) {
    setDraftFilters((current) => ({ ...current, [key]: value }));
  }

  function clearFilters() {
    setFilters(defaultFilters);
    setDraftFilters(defaultFilters);
    setSearchInput("");
    setDebouncedQ("");
    setPage(1);
    setFiltersOpen(false);
  }

  function clearSearch() {
    setSearchInput("");
    setDebouncedQ("");
    setPage(1);
    searchInputRef.current?.focus();
  }

  function openFilters() {
    setDraftFilters(filters);
    setFiltersOpen(true);
  }

  function applyMobileFilters() {
    setFilters(draftFilters);
    setPage(1);
    setFiltersOpen(false);
  }

  function clearMobileFilters() {
    setDraftFilters(defaultFilters);
    setFilters(defaultFilters);
    setPage(1);
    setFiltersOpen(false);
  }

  const hasQueryOrFilters = debouncedQ !== "" || activeFilterCount > 0;
  const showingRange =
    meta && meta.total > 0
      ? `Showing ${(meta.current_page - 1) * meta.per_page + 1}–${Math.min(meta.current_page * meta.per_page, meta.total)} of ${meta.total}`
      : null;

  return (
    <DashboardPageContainer className="max-w-none space-y-4">
      <PageHeader description="Find creators that match your campaign requirements." />

      <div className="space-y-2.5">
        <label className="relative block">
          <span className="sr-only">Search creators by name or username</span>
          <input
            ref={searchInputRef}
            className={cn(fieldClassName, "h-10 max-h-10 pr-20")}
            type="search"
            placeholder="Search creators by name or username"
            value={searchInput}
            onChange={(event) => setSearchInput(event.target.value)}
            autoComplete="off"
          />
          {searchInput ? (
            <button
              type="button"
              className="absolute top-1/2 right-2 -translate-y-1/2 rounded-pv px-2 py-1 text-[0.75rem] font-medium text-ink-60 hover:text-primary"
              onClick={clearSearch}
            >
              Clear
            </button>
          ) : null}
        </label>

        <div className="hidden items-start gap-2 md:flex">
          <div className="grid min-w-0 flex-1 grid-cols-2 gap-2 lg:grid-cols-4">
            <FilterSelects filters={filters} onChange={updateFilter} idPrefix="desktop-filter" />
          </div>
          <button
            type="button"
            className="mt-[1.35rem] h-9 shrink-0 rounded-pv border border-line bg-surface px-3 text-[0.8125rem] font-medium text-ink-60 hover:border-primary hover:text-primary disabled:cursor-not-allowed disabled:opacity-50"
            disabled={activeFilterCount === 0 && searchInput === ""}
            onClick={clearFilters}
          >
            Clear filters
          </button>
        </div>

        <div className="flex items-center gap-2 md:hidden">
          <button
            type="button"
            className="inline-flex h-9 items-center rounded-pv border border-line bg-surface px-3 text-[0.8125rem] font-medium text-primary hover:border-primary"
            onClick={openFilters}
          >
            Filters{activeFilterCount > 0 ? ` · ${activeFilterCount}` : ""}
          </button>
          {(activeFilterCount > 0 || searchInput) && (
            <button
              type="button"
              className="text-[0.8125rem] font-medium text-ink-60 hover:text-primary"
              onClick={clearFilters}
            >
              Clear filters
            </button>
          )}
        </div>
      </div>

      <FiltersSheet
        open={filtersOpen}
        filters={filters}
        draft={draftFilters}
        onDraftChange={updateDraftFilter}
        onApply={applyMobileFilters}
        onClear={clearMobileFilters}
        onClose={() => setFiltersOpen(false)}
      />

      <section aria-labelledby="discover-results-heading" className="space-y-3">
        <SectionHeader
          id="discover-results-heading"
          title="Creators"
          description={
            isLoading
              ? "Searching…"
              : loadError
                ? undefined
                : showingRange ??
                  (hasQueryOrFilters
                    ? "No creators match the current search."
                    : "Browse public creator profiles.")
          }
          action={
            <label className="flex items-center gap-1.5 text-[0.8125rem] text-ink-60">
              <span className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
                Sort
              </span>
              <select
                className={cn(fieldClassName, "w-auto min-w-[9.5rem]")}
                value={`${sortKey}:${sortDir}`}
                onChange={(event) => {
                  const [nextKey, nextDir] = event.target.value.split(":") as [
                    "followers" | "views",
                    "asc" | "desc",
                  ];
                  setSortKey(nextKey);
                  setSortDir(nextDir);
                  setPage(1);
                }}
              >
                <option value="followers:desc">Most followers</option>
                <option value="followers:asc">Fewest followers</option>
                <option value="views:desc">Most views</option>
                <option value="views:asc">Fewest views</option>
              </select>
            </label>
          }
        />

        {loadError ? (
          <ErrorState
            title="Couldn't load creators"
            message="Please try again."
            retryLabel="Retry"
            onRetry={() => void load(page)}
          />
        ) : null}

        {isLoading && !loadError ? <DiscoverSkeleton /> : null}

        {!isLoading && !loadError && creators.length === 0 ? (
          <EmptyState
            title="No creators found"
            description="Try adjusting your search or filters."
            action={
              <Button type="button" size="sm" variant="secondary" onClick={clearFilters}>
                Clear filters
              </Button>
            }
          />
        ) : null}

        {!isLoading && !loadError && creators.length > 0 ? (
          <>
            <div className="hidden overflow-hidden rounded-pv border border-line bg-surface md:block">
              <table className="w-full border-collapse text-left">
                <thead>
                  <tr className="border-b border-line text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
                    <th className="px-3 py-2.5 font-medium">Creator</th>
                    <th className="px-3 py-2.5 font-medium">Platform</th>
                    <th className="px-3 py-2.5 font-medium">Category</th>
                    <th className="px-3 py-2.5 font-medium">Country</th>
                    <th className="px-3 py-2.5 font-medium">Followers</th>
                    <th className="px-3 py-2.5 font-medium">Engagement</th>
                    <th className="px-3 py-2.5 font-medium">
                      <span className="sr-only">Action</span>
                    </th>
                  </tr>
                </thead>
                <tbody>
                  {creators.map((creator) => {
                    const name = creator.display_name?.trim() || creator.username;
                    const facts = publicCreatorFactsLine(
                      creator.gender,
                      creator.gender_label,
                      creator.age,
                    );

                    return (
                      <tr
                        key={creator.username}
                        className="border-b border-line last:border-b-0 hover:bg-bg/80"
                      >
                        <td className="px-3 py-2.5 align-middle">
                          <div className="flex min-w-0 items-center gap-2.5">
                            <CreatorAvatar name={name} src={creator.profile_image} />
                            <div className="min-w-0">
                              <p className="truncate text-[0.8125rem] font-medium text-primary">
                                {name}
                              </p>
                              <p className="truncate text-[0.75rem] text-ink-60">
                                <Link
                                  href={publicProfilePath(creator.username, { from: "discover" })}
                                  className="hover:text-accent hover:underline"
                                >
                                  @{creator.username}
                                </Link>
                              </p>
                              {facts ? (
                                <p className="mt-0.5 truncate text-[0.6875rem] text-ink-40">
                                  {facts}
                                </p>
                              ) : null}
                            </div>
                          </div>
                        </td>
                        <td className="px-3 py-2.5 align-middle text-[0.8125rem] text-ink-60">
                          {platformsLabel(creator.platforms)}
                        </td>
                        <td className="px-3 py-2.5 align-middle text-[0.8125rem] text-ink-60">
                          {nicheLabel(creator.niche)}
                        </td>
                        <td className="max-w-[10rem] px-3 py-2.5 align-middle text-[0.8125rem] text-ink-60">
                          <span className="line-clamp-2">{creator.country || "—"}</span>
                        </td>
                        <td className="px-3 py-2.5 align-middle text-[0.8125rem] font-medium tabular-nums text-primary">
                          {formatMetricCount(creator.followers)}
                        </td>
                        <td className="px-3 py-2.5 align-middle text-[0.8125rem] tabular-nums text-ink-60">
                          {formatMetricPercent(creator.engagement_rate)}
                        </td>
                        <td className="px-3 py-2.5 align-middle text-right">
                          <div className="flex flex-wrap justify-end gap-1.5">
                            <Button
                              type="button"
                              size="sm"
                              onClick={() => setInviteUsername(creator.username)}
                            >
                              Invite
                            </Button>
                            <Button
                              href={publicProfilePath(creator.username, { from: "discover" })}
                              size="sm"
                              variant="secondary"
                            >
                              View
                            </Button>
                          </div>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>

            <div className="grid grid-cols-1 gap-2 md:hidden">
              {creators.map((creator) => (
                <CreatorResultCard
                  key={creator.username}
                  creator={creator}
                  onInvite={setInviteUsername}
                />
              ))}
            </div>

            {meta ? <ResultsPagination meta={meta} onPageChange={setPage} /> : null}
          </>
        ) : null}
      </section>

      <InviteCreatorDialog
        username={inviteUsername ?? ""}
        open={inviteUsername !== null}
        preferredCampaignId={preferredCampaignId}
        onClose={() => setInviteUsername(null)}
      />
    </DashboardPageContainer>
  );
}

const BRAND_ONLY = ["brand"] as const;

export function BrandDiscoverPage() {
  return (
    <DashboardShell title="Discover Creators" allowedAccountTypes={BRAND_ONLY}>
      {() => (
        <Suspense
          fallback={
            <DashboardPageContainer>
              <DiscoverSkeleton />
            </DashboardPageContainer>
          }
        >
          <BrandDiscoverContent />
        </Suspense>
      )}
    </DashboardShell>
  );
}
