/**
 * Dashboard API module.
 *
 * Wraps `GET /api/dashboard/status` and `GET /api/dashboard/bans`.
 */

import { get } from "./client";
import { ENDPOINTS } from "./endpoints";
import type {
  BanOriginFilter,
  BansByJailResponse,
  BanTrendResponse,
  DashboardBanListResponse,
  TimeRange,
} from "../types/ban";
import type { ServerStatusResponse } from "../types/server";

/**
 * Fetch the cached fail2ban server status from the backend.
 *
 * @returns The server status response containing `online`, `version`,
 *   `active_jails`, `total_bans`, and `total_failures`.
 * @throws {ApiError} When the server returns a non-2xx status.
 */
export async function fetchServerStatus(): Promise<ServerStatusResponse> {
  return get<ServerStatusResponse>(ENDPOINTS.dashboardStatus);
}

/**
 * Fetch a paginated ban list for the selected time window.
 *
 * @param range    - Time-range preset: `"24h"`, `"7d"`, `"30d"`, or `"365d"`.
 * @param page     - 1-based page number (default `1`).
 * @param pageSize - Items per page (default `100`).
 * @param origin   - Origin filter: `"blocklist"`, `"selfblock"`, or `"all"`
 *   (default `"all"`, which omits the parameter entirely).
 * @returns Paginated {@link DashboardBanListResponse}.
 * @throws {ApiError} When the server returns a non-2xx status.
 */
export async function fetchBans(
  range: TimeRange,
  page = 1,
  pageSize = 100,
  origin: BanOriginFilter = "all",
  source: "fail2ban" | "archive" = "fail2ban",
  signal?: AbortSignal,
): Promise<DashboardBanListResponse> {
  const params = new URLSearchParams({
    range,
    page: String(page),
    page_size: String(pageSize),
  });
  if (origin !== "all") {
    params.set("origin", origin);
  }
  if (source !== "fail2ban") {
    params.set("source", source);
  }
  return get<DashboardBanListResponse>(`${ENDPOINTS.dashboardBans}?${params.toString()}`, signal);
}

/**
 * Fetch ban counts grouped into equal-width time buckets for the trend chart.
 *
 * @param range  - Time-range preset: `"24h"`, `"7d"`, `"30d"`, or `"365d"`.
 * @param origin - Origin filter: `"blocklist"`, `"selfblock"`, or `"all"`
 *   (default `"all"`, which omits the parameter entirely).
 * @returns {@link BanTrendResponse} with the ordered bucket list.
 * @throws {ApiError} When the server returns a non-2xx status.
 */
export async function fetchBanTrend(
  range: TimeRange,
  origin: BanOriginFilter = "all",
  source: "fail2ban" | "archive" = "fail2ban",
): Promise<BanTrendResponse> {
  const params = new URLSearchParams({ range });
  if (origin !== "all") {
    params.set("origin", origin);
  }
  if (source !== "fail2ban") {
    params.set("source", source);
  }
  return get<BanTrendResponse>(`${ENDPOINTS.dashboardBansTrend}?${params.toString()}`);
}

/**
 * Fetch ban counts aggregated by jail for the selected time window.
 *
 * @param range  - Time-range preset: `"24h"`, `"7d"`, `"30d"`, or `"365d"`.
 * @param origin - Origin filter: `"blocklist"`, `"selfblock"`, or `"all"`
 *   (default `"all"`, which omits the parameter entirely).
 * @returns {@link BansByJailResponse} with jails sorted by ban count descending.
 * @throws {ApiError} When the server returns a non-2xx status.
 */
export async function fetchBansByJail(
  range: TimeRange,
  origin: BanOriginFilter = "all",
  source: "fail2ban" | "archive" = "fail2ban",
): Promise<BansByJailResponse> {
  const params = new URLSearchParams({ range });
  if (origin !== "all") {
    params.set("origin", origin);
  }
  if (source !== "fail2ban") {
    params.set("source", source);
  }
  return get<BansByJailResponse>(`${ENDPOINTS.dashboardBansByJail}?${params.toString()}`);
}
