import type { DisplayStatus } from "./status";

// The dashboard's state lives in the URL (?status=&q=&sort=&dir=&page=) so
// views are linkable and Refresh keeps the current filter. Shared by the
// page, its links and the server query.

export const SORT_KEYS = ["status", "code", "name", "checkedAt", "responseTime"] as const;
export type SortKey = (typeof SORT_KEYS)[number];
export type SortDir = "asc" | "desc";

export type DashboardQuery = {
  status: DisplayStatus | null; // null = All
  q: string;
  sort: SortKey;
  dir: SortDir;
  page: number;
};

// Problems first: Not Working, Slow, Not checked yet, Working, Monitoring Disabled.
export const DEFAULT_QUERY: DashboardQuery = { status: null, q: "", sort: "status", dir: "asc", page: 1 };

export const STATUS_PARAMS: Record<string, DisplayStatus> = {
  working: "WORKING",
  slow: "SLOW",
  "not-working": "NOT_WORKING",
  disabled: "DISABLED",
  pending: "PENDING",
};

type RawParams = { [key: string]: string | string[] | undefined };

function first(value: string | string[] | undefined): string {
  return (Array.isArray(value) ? value[0] : value) ?? "";
}

export function parseDashboardQuery(params: RawParams): DashboardQuery {
  const sort = first(params.sort) as SortKey;
  const dir = first(params.dir);
  return {
    status: STATUS_PARAMS[first(params.status)] ?? null,
    q: first(params.q).trim().slice(0, 100),
    sort: SORT_KEYS.includes(sort) ? sort : DEFAULT_QUERY.sort,
    dir: dir === "desc" ? "desc" : "asc",
    page: Math.max(1, Number.parseInt(first(params.page), 10) || 1),
  };
}

export function statusParam(status: DisplayStatus | null): string {
  return Object.entries(STATUS_PARAMS).find(([, value]) => value === status)?.[0] ?? "";
}

/** Href for the dashboard with `changes` applied; defaults are left out of the URL. */
export function dashboardHref(current: DashboardQuery, changes: Partial<DashboardQuery> = {}): string {
  const next = { ...current, ...changes };
  const params = new URLSearchParams();
  if (next.status) params.set("status", statusParam(next.status));
  if (next.q) params.set("q", next.q);
  if (next.sort !== DEFAULT_QUERY.sort || next.dir !== DEFAULT_QUERY.dir) {
    params.set("sort", next.sort);
    params.set("dir", next.dir);
  }
  if (next.page > 1) params.set("page", String(next.page));
  const query = params.toString();
  return query ? `/?${query}` : "/";
}
