import { createCoreAPIClient } from "@/lib/features/coreClient";
import type { CoreResponse } from "@/lib/features/types";
import type {
  HoldingBalancesResponse,
  Manager,
  PointTransaction,
  TransferPayload,
  TransferResponse,
  PointsEntitlement,
  ViewPointAccount,
} from "./types";

const coreClient = createCoreAPIClient();

export async function getHoldingBalances(
  headers?: HeadersInit,
): Promise<CoreResponse<HoldingBalancesResponse>> {
  return coreClient<HoldingBalancesResponse>(
    "/v1/admin-console/points-transfer/holding-accounts/balances",
    {
      method: "GET",
      headers,
    },
  );
}

export type SyncHoldingBalancesResult = {
  started: boolean;
  alreadyRunning: boolean;
  /** True if the server stopped waiting — the sync is still running, poll for it. */
  timedOut: boolean;
  /** Balances as of the moment the sync settled. */
  balances: HoldingBalancesResponse;
};

// Long-running by design: the response is held until the sync settles (~105s)
// so the caller gets the final balances in one round trip.
export async function syncHoldingBalances(
  headers?: HeadersInit,
): Promise<CoreResponse<SyncHoldingBalancesResult>> {
  return coreClient<SyncHoldingBalancesResult>(
    "/v1/admin-console/points-transfer/holding-accounts/balances/sync",
    {
      method: "POST",
      headers,
    },
  );
}

export async function getManagers(
  headers?: HeadersInit,
): Promise<CoreResponse<Manager[]>> {
  return coreClient<Manager[]>("/v1/admin-console/points-transfer/managers", {
    method: "GET",
    headers,
  });
}

export async function getTransactions(
  limit: number = 3,
  offset: number = 0,
  search?: string,
  headers?: HeadersInit,
): Promise<CoreResponse<{ transactions: PointTransaction[]; total: number }>> {
  const qs = new URLSearchParams();
  qs.set("limit", String(limit));
  qs.set("offset", String(offset));
  if (search) {
    qs.set("search", search);
  }
  return coreClient<{ transactions: PointTransaction[]; total: number }>(
    `/v1/admin-console/points-transfer/transactions?${qs.toString()}`,
    {
      method: "GET",
      headers,
    },
  );
}

export async function transferPoints(
  payload: TransferPayload,
  headers?: HeadersInit,
): Promise<CoreResponse<TransferResponse>> {
  return coreClient<TransferResponse>(
    "/v1/admin-console/points-transfer/transactions/transfer",
    {
      method: "POST",
      headers,
      body: JSON.stringify(payload),
    },
  );
}

// --- PHASE 2 QUERIES ---

export async function searchViewPointByEmail(
  queryVal: string,
  headers?: HeadersInit,
): Promise<CoreResponse<ViewPointAccount[]>> {
  const qs = new URLSearchParams();
  if (queryVal.includes("@")) {
    qs.set("email", queryVal);
  } else {
    qs.set("memberNo", queryVal);
  }
  return coreClient<ViewPointAccount[]>(
    `/v1/admin-console/points-transfer/viewpoint-search?${qs.toString()}`,
    {
      method: "GET",
      headers,
    },
  );
}

export async function mapManagerToViewPoint(
  managerId: string,
  payload: {
    accountId: string;
    contactId: string;
    club: string;
    isActive: boolean;
  },
  headers?: HeadersInit,
): Promise<CoreResponse<{ success: boolean }>> {
  return coreClient<{ success: boolean }>(
    `/v1/admin-console/points-transfer/managers/${managerId}/map`,
    {
      method: "POST",
      headers,
      body: JSON.stringify(payload),
    },
  );
}

export async function getMyBalances(
  headers?: HeadersInit,
): Promise<CoreResponse<{ balance: number; account: string }>> {
  return coreClient<{ balance: number; account: string }>(
    "/v1/admin-console/points-transfer/my-balances",
    {
      method: "GET",
      headers,
    },
  );
}

export async function getMyTransactions(
  limit = 5,
  offset = 0,
  search?: string,
  headers?: HeadersInit,
): Promise<
  CoreResponse<{
    transactions: PointTransaction[];
    total: number;
    totalPoints: number;
    totalUsers: number;
  }>
> {
  const qs = new URLSearchParams();
  qs.set("limit", String(limit));
  qs.set("offset", String(offset));
  if (search) {
    qs.set("search", search);
  }
  return coreClient<{
    transactions: PointTransaction[];
    total: number;
    totalPoints: number;
    totalUsers: number;
  }>(`/v1/admin-console/points-transfer/my-transactions?${qs.toString()}`, {
    method: "GET",
    headers,
  });
}

export async function getMyEntitlements(
  headers?: HeadersInit,
): Promise<CoreResponse<PointsEntitlement[]>> {
  return coreClient<PointsEntitlement[]>(
    "/v1/admin-console/points-transfer/my-entitlements",
    {
      method: "GET",
      headers,
    },
  );
}

export async function transferToMember(
  payload: {
    targetAccountId: string;
    targetContactId: string;
    targetFirstName?: string;
    targetLastName?: string;
    targetEmail?: string;
    points: number;
    notes?: string;
  },
  headers?: HeadersInit,
): Promise<CoreResponse<{ success: boolean; vpRefId: string }>> {
  return coreClient<{ success: boolean; vpRefId: string }>(
    "/v1/admin-console/points-transfer/transfer-to-member",
    {
      method: "POST",
      headers,
      body: JSON.stringify(payload),
    },
  );
}

export async function updateManager(
  managerId: string,
  payload: {
    first_name: string;
    last_name: string;
    email: string;
    service_center: string;
    viewpoint_account_id: string | null;
    viewpoint_contact_id: string | null;
    viewpoint_club: string | null;
    viewpoint_is_active: boolean | null;
  },
  headers?: HeadersInit,
): Promise<CoreResponse<{ success: boolean }>> {
  return coreClient<{ success: boolean }>(
    `/v1/admin-console/points-transfer/managers/${managerId}`,
    {
      method: "PUT",
      headers,
      body: JSON.stringify(payload),
    },
  );
}

export async function deleteManager(
  managerId: string,
  headers?: HeadersInit,
): Promise<CoreResponse<{ success: boolean }>> {
  return coreClient<{ success: boolean }>(
    `/v1/admin-console/points-transfer/managers/${managerId}`,
    {
      method: "DELETE",
      headers,
    },
  );
}

export async function restoreManager(
  managerId: string,
  headers?: HeadersInit,
): Promise<CoreResponse<{ success: boolean }>> {
  return coreClient<{ success: boolean }>(
    `/v1/admin-console/points-transfer/managers/${managerId}/restore`,
    {
      method: "POST",
      headers,
    },
  );
}

export async function getManagerHistory(
  managerId: string,
  headers?: HeadersInit,
): Promise<CoreResponse<{ received: any[]; sent: any[] }>> {
  return coreClient<{ received: any[]; sent: any[] }>(
    `/v1/admin-console/points-transfer/managers/${managerId}/history`,
    {
      method: "GET",
      headers,
    },
  );
}
