"use client";

import * as React from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Check, Download, ListFilter, Search, Sigma, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { withParams } from "@/lib/admin/list";
import { adminTexts } from "@/lib/i18n/admin";
import { cn } from "@/lib/utils";
import type {
  AdminDateRange,
  AdminFacet,
  AdminSearchField,
  AdminTab,
} from "./types";

const t = adminTexts.table;

function countLabel(n: number): string {
  return n > 999 ? "999+" : String(n);
}

/** Tab pills — every tab is a real link so the server refetches. */
function Tabs({
  basePath,
  query,
  tabs,
  active,
  defaultTab,
}: {
  basePath: string;
  query: Record<string, string>;
  tabs: AdminTab[];
  active?: string;
  defaultTab?: string;
}) {
  return (
    <div className="-mx-1 flex items-center gap-1 overflow-x-auto px-1 pb-0.5">
      {tabs.map((tab) => {
        const isActive = (active ?? defaultTab ?? tabs[0]?.key) === tab.key;
        const href = withParams(basePath, query, {
          tab: tab.key === (defaultTab ?? tabs[0]?.key) ? null : tab.key,
          page: null,
        });
        return (
          <Link
            key={tab.key}
            href={href}
            aria-current={isActive ? "page" : undefined}
            className={cn(
              "inline-flex shrink-0 items-center gap-1.5 rounded-lg border px-2.5 py-1 text-sm font-medium transition-colors",
              isActive
                ? "border-blue-600/40 bg-blue-600/10 text-blue-700 dark:text-blue-400"
                : "border-transparent text-muted-foreground hover:bg-muted hover:text-foreground",
            )}
          >
            {tab.label}
            {typeof tab.count === "number" ? (
              <span
                className={cn(
                  "rounded-full px-1.5 py-px font-mono text-[10px] tabular-nums",
                  isActive
                    ? "bg-blue-600/15 text-blue-700 dark:text-blue-300"
                    : "bg-muted text-muted-foreground",
                )}
              >
                {countLabel(tab.count)}
              </span>
            ) : null}
            {tab.hint ? (
              <span className="font-mono text-[10px] text-muted-foreground">
                {tab.hint}
              </span>
            ) : null}
          </Link>
        );
      })}
    </div>
  );
}

function FacetControl({
  facet,
  value,
  onChange,
}: {
  facet: AdminFacet;
  value: string;
  onChange: (next: string | null) => void;
}) {
  const allLabel = facet.allLabel ?? t.allOf.replace("{label}", facet.label.toLowerCase());

  if (!facet.multi) {
    return (
      <NativeSelect
        size="sm"
        aria-label={facet.label}
        value={value}
        onChange={(e) => onChange(e.target.value || null)}
        className="max-w-[13rem]"
      >
        <NativeSelectOption value="">{allLabel}</NativeSelectOption>
        {facet.options.map((o) => (
          <NativeSelectOption key={o.value} value={o.value}>
            {o.count === undefined ? o.label : `${o.label} (${o.count})`}
          </NativeSelectOption>
        ))}
      </NativeSelect>
    );
  }

  const selected = value ? value.split(",").filter(Boolean) : [];

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button type="button" variant="outline" size="sm" className="gap-1.5">
          <ListFilter className="size-3.5" />
          {facet.label}
          {selected.length ? (
            <span className="rounded-full bg-blue-600/15 px-1.5 font-mono text-[10px] text-blue-700 tabular-nums dark:text-blue-300">
              {selected.length}
            </span>
          ) : null}
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="start" className="max-h-80 w-56 overflow-y-auto">
        <DropdownMenuLabel className="text-[11px]">{facet.label}</DropdownMenuLabel>
        <DropdownMenuSeparator />
        {facet.options.map((o) => {
          const checked = selected.includes(o.value);
          return (
            <DropdownMenuCheckboxItem
              key={o.value}
              checked={checked}
              onSelect={(e) => e.preventDefault()}
              onCheckedChange={() => {
                const next = checked
                  ? selected.filter((v) => v !== o.value)
                  : [...selected, o.value];
                onChange(next.length ? next.join(",") : null);
              }}
            >
              <span className="truncate">{o.label}</span>
              {o.count === undefined ? null : (
                <span className="ml-auto font-mono text-[10px] text-muted-foreground">
                  {o.count}
                </span>
              )}
            </DropdownMenuCheckboxItem>
          );
        })}
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

export function AdminTableToolbar({
  basePath,
  query,
  tabs,
  activeTab,
  defaultTab,
  searchFields,
  q,
  qField,
  searchPlaceholder,
  facetFilters,
  dateRange,
  totalsEnabled,
  hasTotals,
  exportHref,
  extra,
}: {
  basePath: string;
  query: Record<string, string>;
  tabs?: AdminTab[];
  activeTab?: string;
  defaultTab?: string;
  searchFields?: AdminSearchField[];
  q?: string;
  qField?: string;
  searchPlaceholder?: string;
  facetFilters?: AdminFacet[];
  dateRange?: AdminDateRange;
  totalsEnabled?: boolean;
  hasTotals?: boolean;
  exportHref?: string;
  extra?: React.ReactNode;
}) {
  const router = useRouter();
  const [, startTransition] = React.useTransition();
  const [term, setTerm] = React.useState(q ?? "");
  const [field, setField] = React.useState(qField ?? searchFields?.[0]?.key ?? "");
  const [from, setFrom] = React.useState(dateRange?.from ?? "");
  const [to, setTo] = React.useState(dateRange?.to ?? "");

  React.useEffect(() => setTerm(q ?? ""), [q]);
  React.useEffect(() => setFrom(dateRange?.from ?? ""), [dateRange?.from]);
  React.useEffect(() => setTo(dateRange?.to ?? ""), [dateRange?.to]);

  const go = React.useCallback(
    (patch: Record<string, string | number | null>) => {
      startTransition(() => {
        router.push(withParams(basePath, query, { page: null, ...patch }), {
          scroll: false,
        });
      });
    },
    [basePath, query, router],
  );

  const hasSearch = Boolean(searchFields?.length) || q !== undefined;
  const activeFilters =
    (facetFilters ?? []).filter((f) => query[f.key]).length +
    (query.q ? 1 : 0) +
    (query.from || query.to ? 1 : 0);

  const totalsHref = withParams(basePath, query, {
    totals: totalsEnabled ? null : 1,
  });
  const clearHref = withParams(
    basePath,
    Object.fromEntries(
      Object.entries(query).filter(([k]) => k === "tab" || k === "perPage"),
    ),
  );

  return (
    <div className="flex flex-col gap-2.5 border-b px-3 py-2.5">
      {tabs?.length ? (
        <Tabs
          basePath={basePath}
          query={query}
          tabs={tabs}
          active={activeTab}
          defaultTab={defaultTab}
        />
      ) : null}

      <div className="flex flex-wrap items-center gap-2">
        {hasSearch ? (
          <form
            className="flex min-w-0 items-center gap-1.5"
            onSubmit={(e) => {
              e.preventDefault();
              go({ q: term.trim() || null, qf: field || null });
            }}
          >
            {searchFields?.length ? (
              <NativeSelect
                size="sm"
                aria-label={t.searchIn}
                value={field}
                onChange={(e) => setField(e.target.value)}
                className="hidden sm:block"
              >
                {searchFields.map((f) => (
                  <NativeSelectOption key={f.key} value={f.key}>
                    {f.label}
                  </NativeSelectOption>
                ))}
              </NativeSelect>
            ) : null}

            <div className="relative">
              <Search className="pointer-events-none absolute top-1/2 left-2 size-3.5 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={term}
                onChange={(e) => setTerm(e.target.value)}
                placeholder={searchPlaceholder ?? t.searchPlaceholder}
                aria-label={t.search}
                className="h-7 w-40 pl-7 text-sm sm:w-56"
              />
            </div>
            <Button type="submit" size="sm" variant="outline">
              {t.search}
            </Button>
          </form>
        ) : null}

        {(facetFilters ?? []).map((facet) => (
          <FacetControl
            key={facet.key}
            facet={facet}
            value={query[facet.key] ?? ""}
            onChange={(next) => go({ [facet.key]: next })}
          />
        ))}

        {dateRange?.enabled ? (
          <form
            className="flex items-center gap-1.5"
            onSubmit={(e) => {
              e.preventDefault();
              go({ from: from || null, to: to || null });
            }}
          >
            <Input
              type="date"
              value={from}
              onChange={(e) => setFrom(e.target.value)}
              aria-label={t.from}
              className="h-7 w-[8.5rem] text-sm"
            />
            <span className="text-xs text-muted-foreground">–</span>
            <Input
              type="date"
              value={to}
              onChange={(e) => setTo(e.target.value)}
              aria-label={t.to}
              className="h-7 w-[8.5rem] text-sm"
            />
            <Button type="submit" size="icon-sm" variant="outline" aria-label={t.apply}>
              <Check className="size-3.5" />
            </Button>
          </form>
        ) : null}

        {activeFilters > 0 ? (
          <Button asChild size="sm" variant="ghost" className="text-muted-foreground">
            <Link href={clearHref}>
              <X className="size-3.5" />
              {t.clearFilters}
            </Link>
          </Button>
        ) : null}

        <div className="ml-auto flex items-center gap-2">
          {extra}
          {hasTotals ? (
            <Button
              asChild
              size="sm"
              variant={totalsEnabled ? "secondary" : "outline"}
            >
              <Link href={totalsHref}>
                <Sigma className="size-3.5" />
                <span className="hidden sm:inline">
                  {totalsEnabled ? t.hideTotals : t.showTotals}
                </span>
              </Link>
            </Button>
          ) : null}
          {exportHref ? (
            <Button asChild size="sm" variant="outline">
              <a href={exportHref}>
                <Download className="size-3.5" />
                <span className="hidden sm:inline">{t.exportCsv}</span>
              </a>
            </Button>
          ) : null}
        </div>
      </div>
    </div>
  );
}

export default AdminTableToolbar;
