import { useCallback, useMemo } from "react";
import { useSearchParams } from "react-router";
import {
  EMPTY_FILTERS,
  type EventAnalyticsFilters,
} from "@/lib/features/event-analytics/types";

/**
 * Filter state, held in the URL rather than component state.
 *
 * A filtered analytics view is something people paste to each other and reload,
 * so the URL is the single source of truth: every panel reads the same object,
 * the back button works, and a link carries the exact view the sender saw.
 */
export function useEventFilters() {
  const [searchParams, setSearchParams] = useSearchParams();

  const filters = useMemo<EventAnalyticsFilters>(
    () => ({
      from: searchParams.get("from"),
      to: searchParams.get("to"),
      eventTypes:
        searchParams.get("eventTypes")?.split(",").filter(Boolean) ?? [],
      memberId: searchParams.get("memberId"),
      currency: searchParams.get("currency"),
      property: searchParams.get("property"),
      source: searchParams.get("source"),
      search: searchParams.get("search"),
    }),
    [searchParams],
  );

  const setFilters = useCallback(
    (next: Partial<EventAnalyticsFilters>) => {
      const merged = { ...filters, ...next };
      const params = new URLSearchParams();
      if (merged.from) params.set("from", merged.from);
      if (merged.to) params.set("to", merged.to);
      if (merged.eventTypes.length)
        params.set("eventTypes", merged.eventTypes.join(","));
      if (merged.memberId) params.set("memberId", merged.memberId);
      if (merged.currency) params.set("currency", merged.currency);
      if (merged.property) params.set("property", merged.property);
      if (merged.source) params.set("source", merged.source);
      if (merged.search) params.set("search", merged.search);
      // `replace` so adjusting a filter does not bury the previous page under a
      // stack of history entries the user has to click back through.
      setSearchParams(params, { replace: true });
    },
    [filters, setSearchParams],
  );

  const resetFilters = useCallback(
    () => setSearchParams(new URLSearchParams(), { replace: true }),
    [setSearchParams],
  );

  const hasActiveFilters =
    Boolean(filters.from) ||
    Boolean(filters.to) ||
    filters.eventTypes.length > 0 ||
    Boolean(filters.memberId) ||
    Boolean(filters.currency) ||
    Boolean(filters.property) ||
    Boolean(filters.source) ||
    Boolean(filters.search);

  /** Human-readable filter list, for the export's approval note and Filters sheet. */
  const filterRows = useMemo(() => {
    const rows: { label: string; value: string }[] = [];
    rows.push({
      label: "Date range",
      value:
        filters.from || filters.to
          ? `${filters.from ?? "beginning"} to ${filters.to ?? "now"}`
          : "All time",
    });
    if (filters.eventTypes.length)
      rows.push({ label: "Event types", value: filters.eventTypes.join(", ") });
    if (filters.memberId)
      rows.push({ label: "Member ID", value: filters.memberId });
    if (filters.currency)
      rows.push({ label: "Currency", value: filters.currency });
    if (filters.property)
      rows.push({ label: "Property", value: filters.property });
    if (filters.source) rows.push({ label: "Source", value: filters.source });
    if (filters.search) rows.push({ label: "Search", value: filters.search });
    return rows;
  }, [filters]);

  const filtersSummary = filterRows
    .map((r) => `${r.label}: ${r.value}`)
    .join(" · ");

  return {
    filters,
    setFilters,
    resetFilters,
    hasActiveFilters,
    filterRows,
    filtersSummary,
    EMPTY_FILTERS,
  };
}
