import { createCoreAPIClient } from "@/lib/features/coreClient";
import { getAdminActivityLogs } from "@/lib/features/activity-logs/query";
import type { CoreResponse } from "@/lib/features/types";
import type { PromoCode, PromoCodeListQueryParams } from "./types";

const coreClient = createCoreAPIClient();

export async function listPromoCodes(
  query?: PromoCodeListQueryParams,
  headers?: HeadersInit,
): Promise<CoreResponse<{ data: PromoCode[]; pagination: any }>> {
  const params = new URLSearchParams();
  if (typeof query?.isActive === "string" && query.isActive.length > 0) {
    params.set("isActive", query.isActive);
  }
  if (
    typeof query?.onlyPromoCodes === "string" &&
    query.onlyPromoCodes.length > 0
  ) {
    params.set("onlyPromoCodes", query.onlyPromoCodes);
  }
  if (
    typeof query?.onlyMemberReferralCodes === "string" &&
    query.onlyMemberReferralCodes.length > 0
  ) {
    params.set("onlyMemberReferralCodes", query.onlyMemberReferralCodes);
  }
  if (
    typeof query?.includeExpired === "string" &&
    query.includeExpired.length > 0
  ) {
    params.set("includeExpired", query.includeExpired);
  }
  if (typeof query?.searchTerm === "string" && query.searchTerm.length > 0) {
    params.set("searchTerm", query.searchTerm);
  }
  if (typeof query?.limit === "number" && Number.isFinite(query.limit)) {
    params.set("limit", String(query.limit));
  }
  if (typeof query?.offset === "number" && Number.isFinite(query.offset)) {
    params.set("offset", String(query.offset));
  }

  const queryString = params.toString();
  const url = queryString
    ? `/v1/admin-console/promo-codes?${queryString}`
    : "/v1/admin-console/promo-codes";

  return await coreClient<any>(url, {
    method: "GET",
    headers,
  });
}

export async function getPromoCodeByCode(
  code: string,
  headers?: HeadersInit,
): Promise<CoreResponse<PromoCode>> {
  return await coreClient<PromoCode>(`/v1/admin-console/promo-codes/${code}`, {
    method: "GET",
    headers,
  });
}

/**
 * The single-promo GET hands back the upstream envelope ({ success, message,
 * data }) rather than the promo itself, so callers have to peel one layer —
 * except when the promo is already unwrapped. Mirrors the local helpers in the
 * promo detail loaders.
 */
export function unwrapPromo(raw: unknown): PromoCode | null {
  if (!raw || typeof raw !== "object") return null;
  const obj = raw as Record<string, unknown>;
  if (
    "data" in obj &&
    obj.data &&
    typeof obj.data === "object" &&
    !Array.isArray(obj.data) &&
    !("name" in obj || "code" in obj || "rewards" in obj)
  ) {
    return obj.data as PromoCode;
  }
  return obj as PromoCode;
}

export async function getPromoLogs(
  promoId: string | null,
  page: number,
  pageSize: number,
) {
  const search = promoId
    ? `admin-console/promo-codes/${promoId}`
    : "admin-console/promo-codes";
  return getAdminActivityLogs(
    {
      search,
      method: ["POST", "PUT", "PATCH", "DELETE"],
      page,
      pageSize,
    },
    new Request(
      typeof window !== "undefined" ? window.location.href : "http://localhost",
    ),
  );
}

export async function listServiceCenters(
  headers?: HeadersInit,
): Promise<CoreResponse<any[]>> {
  return await coreClient<any[]>("/v1/admin/service-centers", {
    method: "GET",
    headers,
  });
}
