import { createCoreAPIClient } from "@/lib/features/coreClient";
import type { CoreResponse } from "@/lib/features/types";
import type {
  EventAnalyticsFilters,
  EventRecordsResponse,
  EventTypeAnalyticsResponse,
  MemberAnalyticsResponse,
  MemberDetailResponse,
  SummaryResponse,
} from "./types";

const coreClient = createCoreAPIClient();

const BASE = "/v1/admin-console/event-analytics";

/** Filters -> query string. Empty values are omitted so cache keys stay stable. */
export function filtersToParams(
  filters: EventAnalyticsFilters,
  extra?: Record<string, string | number | undefined>,
): string {
  const params = new URLSearchParams();
  if (filters.from) params.set("from", filters.from);
  if (filters.to) params.set("to", filters.to);
  if (filters.eventTypes.length)
    params.set("eventTypes", filters.eventTypes.join(","));
  if (filters.memberId) params.set("memberId", filters.memberId);
  if (filters.currency) params.set("currency", filters.currency);
  if (filters.property) params.set("property", filters.property);
  if (filters.source) params.set("source", filters.source);
  if (filters.search) params.set("search", filters.search);
  for (const [key, value] of Object.entries(extra ?? {})) {
    if (value !== undefined && value !== "") params.set(key, String(value));
  }
  const qs = params.toString();
  return qs ? `?${qs}` : "";
}

export async function getEventSummary(
  filters: EventAnalyticsFilters,
  init?: RequestInit,
): Promise<CoreResponse<SummaryResponse>> {
  return await coreClient<SummaryResponse>(
    `${BASE}/summary${filtersToParams(filters)}`,
    {
      method: "GET",
      ...init,
    },
  );
}

export async function getMemberAnalytics(
  filters: EventAnalyticsFilters,
  opts: {
    page: number;
    pageSize: number;
    sortBy?: "events" | "revenue" | "points" | "lastSeen" | "member";
    sortDir?: "asc" | "desc";
    /** Narrows the member list by member number, before paging. */
    memberSearch?: string;
  },
  init?: RequestInit,
): Promise<CoreResponse<MemberAnalyticsResponse>> {
  const qs = filtersToParams(filters, {
    page: opts.page,
    pageSize: opts.pageSize,
    sortBy: opts.sortBy,
    sortDir: opts.sortDir,
    memberSearch: opts.memberSearch,
  });
  return await coreClient<MemberAnalyticsResponse>(`${BASE}/members${qs}`, {
    method: "GET",
    ...init,
  });
}

export async function getEventTypeAnalytics(
  filters: EventAnalyticsFilters,
  init?: RequestInit,
): Promise<CoreResponse<EventTypeAnalyticsResponse>> {
  return await coreClient<EventTypeAnalyticsResponse>(
    `${BASE}/events${filtersToParams(filters)}`,
    { method: "GET", ...init },
  );
}

/**
 * Profile, aggregates and recent events for one member, in one round trip.
 *
 * The member number is path-encoded rather than sent as a filter — the endpoint
 * forces its own `memberId`, so a filter carrying a different one would be
 * ignored anyway.
 */
export async function getMemberDetail(
  memberId: string,
  filters: EventAnalyticsFilters,
  init?: RequestInit,
): Promise<CoreResponse<MemberDetailResponse>> {
  return await coreClient<MemberDetailResponse>(
    `${BASE}/members/${encodeURIComponent(memberId)}${filtersToParams(filters)}`,
    { method: "GET", ...init },
  );
}

export async function getEventRecords(
  filters: EventAnalyticsFilters,
  opts: { pageSize: number; cursor?: string },
  init?: RequestInit,
): Promise<CoreResponse<EventRecordsResponse>> {
  const qs = filtersToParams(filters, {
    pageSize: opts.pageSize,
    cursor: opts.cursor,
  });
  return await coreClient<EventRecordsResponse>(`${BASE}/records${qs}`, {
    method: "GET",
    ...init,
  });
}
