/**
 * Generated by orval v7.6.0 🍺
 * Do not edit manually.
 * Coinbase Developer Platform APIs
 * The Coinbase Developer Platform APIs - leading the world's transition onchain.
 * OpenAPI spec version: 2.0.0
 */
import { faker } from "@faker-js/faker";

import { HttpResponse, delay, http } from "msw";

import { PaymentRailAction } from "../coinbaseDeveloperPlatformAPIs.schemas.js";
import type {
  CreatePaymentTransferQuote201,
  CryptoRail,
  CryptoRailAddress,
  PaymentMethod,
  PaymentMethodRequest,
  Transfer,
} from "../coinbaseDeveloperPlatformAPIs.schemas.js";

export const getGetPaymentMethodsResponseMock = (): PaymentMethod[] =>
  Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({
    id: faker.helpers.fromRegExp(
      "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
    ),
    type: faker.helpers.arrayElement(["card", "fiat_account"] as const),
    currency: faker.string.alpha(20),
    actions: faker.helpers.arrayElements(Object.values(PaymentRailAction)),
    limits: faker.helpers.arrayElement([
      {
        sourceLimit: faker.helpers.arrayElement([
          {
            amount: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
            currency: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
          },
          undefined,
        ]),
        targetLimit: faker.helpers.arrayElement([
          {
            amount: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
            currency: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
          },
          undefined,
        ]),
      },
      undefined,
    ]),
  }));

export const getGetCryptoRailsResponseMock = (): CryptoRail[] =>
  Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({
    currency: faker.string.alpha(20),
    name: faker.string.alpha(20),
    networks: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(
      () => ({
        name: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
        chainId: faker.helpers.arrayElement([
          faker.number.int({ min: undefined, max: undefined }),
          undefined,
        ]),
        contractAddress: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
      }),
    ),
    actions: faker.helpers.arrayElements(Object.values(PaymentRailAction)),
  }));

export const getCreatePaymentTransferQuoteResponsePaymentMethodRequestMock = (
  overrideResponse: Partial<PaymentMethodRequest> = {},
): PaymentMethodRequest => ({
  ...{
    id: faker.helpers.fromRegExp(
      "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
    ),
  },
  ...overrideResponse,
});

export const getCreatePaymentTransferQuoteResponseCryptoRailAddressMock = (
  overrideResponse: Partial<CryptoRailAddress> = {},
): CryptoRailAddress => ({
  ...{
    currency: faker.string.alpha(20),
    network: faker.string.alpha(20),
    address: faker.string.alpha(20),
  },
  ...overrideResponse,
});

export const getCreatePaymentTransferQuoteResponseMock = (
  overrideResponse: Partial<CreatePaymentTransferQuote201> = {},
): CreatePaymentTransferQuote201 => ({
  transfer: {
    id: faker.helpers.fromRegExp(
      "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
    ),
    sourceType: faker.helpers.arrayElement(["payment_method"] as const),
    source: faker.helpers.arrayElement([
      { ...getCreatePaymentTransferQuoteResponsePaymentMethodRequestMock() },
    ]),
    targetType: faker.helpers.arrayElement(["crypto_rail"] as const),
    target: faker.helpers.arrayElement([
      { ...getCreatePaymentTransferQuoteResponseCryptoRailAddressMock() },
    ]),
    sourceAmount: faker.string.alpha(20),
    sourceCurrency: faker.string.alpha(20),
    targetAmount: faker.string.alpha(20),
    targetCurrency: faker.string.alpha(20),
    userAmount: faker.string.alpha(20),
    userCurrency: faker.string.alpha(20),
    fees: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(
      () => ({
        type: faker.helpers.arrayElement(["exchange_fee", "network_fee"] as const),
        amount: faker.string.alpha(20),
        currency: faker.string.alpha(20),
        description: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
      }),
    ),
    status: faker.helpers.arrayElement([
      "created",
      "pending",
      "started",
      "completed",
      "failed",
    ] as const),
    createdAt: faker.string.alpha(20),
    updatedAt: faker.string.alpha(20),
    transactionHash: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
  },
  ...overrideResponse,
});

export const getExecutePaymentTransferQuoteResponsePaymentMethodRequestMock = (
  overrideResponse: Partial<PaymentMethodRequest> = {},
): PaymentMethodRequest => ({
  ...{
    id: faker.helpers.fromRegExp(
      "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
    ),
  },
  ...overrideResponse,
});

export const getExecutePaymentTransferQuoteResponseCryptoRailAddressMock = (
  overrideResponse: Partial<CryptoRailAddress> = {},
): CryptoRailAddress => ({
  ...{
    currency: faker.string.alpha(20),
    network: faker.string.alpha(20),
    address: faker.string.alpha(20),
  },
  ...overrideResponse,
});

export const getExecutePaymentTransferQuoteResponseMock = (
  overrideResponse: Partial<Transfer> = {},
): Transfer => ({
  id: faker.helpers.fromRegExp(
    "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
  ),
  sourceType: faker.helpers.arrayElement(["payment_method"] as const),
  source: faker.helpers.arrayElement([
    { ...getExecutePaymentTransferQuoteResponsePaymentMethodRequestMock() },
  ]),
  targetType: faker.helpers.arrayElement(["crypto_rail"] as const),
  target: faker.helpers.arrayElement([
    { ...getExecutePaymentTransferQuoteResponseCryptoRailAddressMock() },
  ]),
  sourceAmount: faker.string.alpha(20),
  sourceCurrency: faker.string.alpha(20),
  targetAmount: faker.string.alpha(20),
  targetCurrency: faker.string.alpha(20),
  userAmount: faker.string.alpha(20),
  userCurrency: faker.string.alpha(20),
  fees: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({
    type: faker.helpers.arrayElement(["exchange_fee", "network_fee"] as const),
    amount: faker.string.alpha(20),
    currency: faker.string.alpha(20),
    description: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
  })),
  status: faker.helpers.arrayElement([
    "created",
    "pending",
    "started",
    "completed",
    "failed",
  ] as const),
  createdAt: faker.string.alpha(20),
  updatedAt: faker.string.alpha(20),
  transactionHash: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
  ...overrideResponse,
});

export const getGetPaymentTransferResponsePaymentMethodRequestMock = (
  overrideResponse: Partial<PaymentMethodRequest> = {},
): PaymentMethodRequest => ({
  ...{
    id: faker.helpers.fromRegExp(
      "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
    ),
  },
  ...overrideResponse,
});

export const getGetPaymentTransferResponseCryptoRailAddressMock = (
  overrideResponse: Partial<CryptoRailAddress> = {},
): CryptoRailAddress => ({
  ...{
    currency: faker.string.alpha(20),
    network: faker.string.alpha(20),
    address: faker.string.alpha(20),
  },
  ...overrideResponse,
});

export const getGetPaymentTransferResponseMock = (
  overrideResponse: Partial<Transfer> = {},
): Transfer => ({
  id: faker.helpers.fromRegExp(
    "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
  ),
  sourceType: faker.helpers.arrayElement(["payment_method"] as const),
  source: faker.helpers.arrayElement([
    { ...getGetPaymentTransferResponsePaymentMethodRequestMock() },
  ]),
  targetType: faker.helpers.arrayElement(["crypto_rail"] as const),
  target: faker.helpers.arrayElement([{ ...getGetPaymentTransferResponseCryptoRailAddressMock() }]),
  sourceAmount: faker.string.alpha(20),
  sourceCurrency: faker.string.alpha(20),
  targetAmount: faker.string.alpha(20),
  targetCurrency: faker.string.alpha(20),
  userAmount: faker.string.alpha(20),
  userCurrency: faker.string.alpha(20),
  fees: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({
    type: faker.helpers.arrayElement(["exchange_fee", "network_fee"] as const),
    amount: faker.string.alpha(20),
    currency: faker.string.alpha(20),
    description: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
  })),
  status: faker.helpers.arrayElement([
    "created",
    "pending",
    "started",
    "completed",
    "failed",
  ] as const),
  createdAt: faker.string.alpha(20),
  updatedAt: faker.string.alpha(20),
  transactionHash: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
  ...overrideResponse,
});

export const getGetPaymentMethodsMockHandler = (
  overrideResponse?:
    | PaymentMethod[]
    | ((
        info: Parameters<Parameters<typeof http.get>[1]>[0],
      ) => Promise<PaymentMethod[]> | PaymentMethod[]),
) => {
  return http.get("*/v2/payments/rails/payment-methods", async info => {
    await delay(0);

    return new HttpResponse(
      JSON.stringify(
        overrideResponse !== undefined
          ? typeof overrideResponse === "function"
            ? await overrideResponse(info)
            : overrideResponse
          : getGetPaymentMethodsResponseMock(),
      ),
      { status: 200, headers: { "Content-Type": "application/json" } },
    );
  });
};

export const getGetCryptoRailsMockHandler = (
  overrideResponse?:
    | CryptoRail[]
    | ((
        info: Parameters<Parameters<typeof http.get>[1]>[0],
      ) => Promise<CryptoRail[]> | CryptoRail[]),
) => {
  return http.get("*/v2/payments/rails/crypto", async info => {
    await delay(0);

    return new HttpResponse(
      JSON.stringify(
        overrideResponse !== undefined
          ? typeof overrideResponse === "function"
            ? await overrideResponse(info)
            : overrideResponse
          : getGetCryptoRailsResponseMock(),
      ),
      { status: 200, headers: { "Content-Type": "application/json" } },
    );
  });
};

export const getCreatePaymentTransferQuoteMockHandler = (
  overrideResponse?:
    | CreatePaymentTransferQuote201
    | ((
        info: Parameters<Parameters<typeof http.post>[1]>[0],
      ) => Promise<CreatePaymentTransferQuote201> | CreatePaymentTransferQuote201),
) => {
  return http.post("*/v2/payments/transfers", async info => {
    await delay(0);

    return new HttpResponse(
      JSON.stringify(
        overrideResponse !== undefined
          ? typeof overrideResponse === "function"
            ? await overrideResponse(info)
            : overrideResponse
          : getCreatePaymentTransferQuoteResponseMock(),
      ),
      { status: 201, headers: { "Content-Type": "application/json" } },
    );
  });
};

export const getExecutePaymentTransferQuoteMockHandler = (
  overrideResponse?:
    | Transfer
    | ((info: Parameters<Parameters<typeof http.post>[1]>[0]) => Promise<Transfer> | Transfer),
) => {
  return http.post("*/v2/payments/transfers/:transferId/execute", async info => {
    await delay(0);

    return new HttpResponse(
      JSON.stringify(
        overrideResponse !== undefined
          ? typeof overrideResponse === "function"
            ? await overrideResponse(info)
            : overrideResponse
          : getExecutePaymentTransferQuoteResponseMock(),
      ),
      { status: 200, headers: { "Content-Type": "application/json" } },
    );
  });
};

export const getGetPaymentTransferMockHandler = (
  overrideResponse?:
    | Transfer
    | ((info: Parameters<Parameters<typeof http.get>[1]>[0]) => Promise<Transfer> | Transfer),
) => {
  return http.get("*/v2/payments/transfers/:transferId", async info => {
    await delay(0);

    return new HttpResponse(
      JSON.stringify(
        overrideResponse !== undefined
          ? typeof overrideResponse === "function"
            ? await overrideResponse(info)
            : overrideResponse
          : getGetPaymentTransferResponseMock(),
      ),
      { status: 200, headers: { "Content-Type": "application/json" } },
    );
  });
};
export const getPaymentsAlphaMock = () => [
  getGetPaymentMethodsMockHandler(),
  getGetCryptoRailsMockHandler(),
  getCreatePaymentTransferQuoteMockHandler(),
  getExecutePaymentTransferQuoteMockHandler(),
  getGetPaymentTransferMockHandler(),
];
