/*
 * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
 */

import * as z from "zod";
import { safeParse } from "../../lib/schemas.js";
import { ClosedEnum } from "../../types/enums.js";
import { Result as SafeParseResult } from "../../types/fp.js";
import { SDKValidationError } from "../errors/sdkvalidationerror.js";

export type GetCustomersRequest = {
  /**
   * A case-sensitive filter on the list based on the customer's `email` field. The value must be a string.
   */
  email?: string | undefined;
  /**
   * A case-sensitive filter on the list based on the customer's `externalId` field. The value must be a string.
   */
  externalId?: string | undefined;
  /**
   * Whether to include expanded fields on the customer (`link`, `partner`, `discount`).
   */
  includeExpandedFields?: boolean | undefined;
};

export type Link = {
  /**
   * The unique ID of the short link.
   */
  id: string;
  /**
   * The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains).
   */
  domain: string;
  /**
   * The short link slug. If not provided, a random 7-character slug will be generated.
   */
  key: string;
  /**
   * The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`).
   */
  shortLink: string;
  /**
   * The ID of the program the short link is associated with.
   */
  programId: string | null;
};

export type Partner = {
  id: string;
  name: string;
  email: string;
  image?: string | null | undefined;
};

export const Type = {
  Percentage: "percentage",
  Flat: "flat",
} as const;
export type Type = ClosedEnum<typeof Type>;

export const GetCustomersInterval = {
  Month: "month",
  Year: "year",
} as const;
export type GetCustomersInterval = ClosedEnum<typeof GetCustomersInterval>;

export type Discount = {
  id: string;
  couponId: string | null;
  couponTestId: string | null;
  amount: number;
  type: Type;
  duration: number | null;
  interval: GetCustomersInterval | null;
};

export type GetCustomersResponseBody = {
  /**
   * The unique identifier of the customer in Dub.
   */
  id: string;
  /**
   * Unique identifier for the customer in the client's app.
   */
  externalId: string;
  /**
   * Name of the customer.
   */
  name: string;
  /**
   * Email of the customer.
   */
  email?: string | null | undefined;
  /**
   * Avatar URL of the customer.
   */
  avatar?: string | null | undefined;
  /**
   * Country of the customer.
   */
  country?: string | null | undefined;
  /**
   * The date the customer was created.
   */
  createdAt: string;
  link?: Link | null | undefined;
  partner?: Partner | null | undefined;
  discount?: Discount | null | undefined;
};

/** @internal */
export const GetCustomersRequest$inboundSchema: z.ZodType<
  GetCustomersRequest,
  z.ZodTypeDef,
  unknown
> = z.object({
  email: z.string().optional(),
  externalId: z.string().optional(),
  includeExpandedFields: z.boolean().optional(),
});

/** @internal */
export type GetCustomersRequest$Outbound = {
  email?: string | undefined;
  externalId?: string | undefined;
  includeExpandedFields?: boolean | undefined;
};

/** @internal */
export const GetCustomersRequest$outboundSchema: z.ZodType<
  GetCustomersRequest$Outbound,
  z.ZodTypeDef,
  GetCustomersRequest
> = z.object({
  email: z.string().optional(),
  externalId: z.string().optional(),
  includeExpandedFields: z.boolean().optional(),
});

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace GetCustomersRequest$ {
  /** @deprecated use `GetCustomersRequest$inboundSchema` instead. */
  export const inboundSchema = GetCustomersRequest$inboundSchema;
  /** @deprecated use `GetCustomersRequest$outboundSchema` instead. */
  export const outboundSchema = GetCustomersRequest$outboundSchema;
  /** @deprecated use `GetCustomersRequest$Outbound` instead. */
  export type Outbound = GetCustomersRequest$Outbound;
}

export function getCustomersRequestToJSON(
  getCustomersRequest: GetCustomersRequest,
): string {
  return JSON.stringify(
    GetCustomersRequest$outboundSchema.parse(getCustomersRequest),
  );
}

export function getCustomersRequestFromJSON(
  jsonString: string,
): SafeParseResult<GetCustomersRequest, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => GetCustomersRequest$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'GetCustomersRequest' from JSON`,
  );
}

/** @internal */
export const Link$inboundSchema: z.ZodType<Link, z.ZodTypeDef, unknown> = z
  .object({
    id: z.string(),
    domain: z.string(),
    key: z.string(),
    shortLink: z.string(),
    programId: z.nullable(z.string()),
  });

/** @internal */
export type Link$Outbound = {
  id: string;
  domain: string;
  key: string;
  shortLink: string;
  programId: string | null;
};

/** @internal */
export const Link$outboundSchema: z.ZodType<Link$Outbound, z.ZodTypeDef, Link> =
  z.object({
    id: z.string(),
    domain: z.string(),
    key: z.string(),
    shortLink: z.string(),
    programId: z.nullable(z.string()),
  });

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace Link$ {
  /** @deprecated use `Link$inboundSchema` instead. */
  export const inboundSchema = Link$inboundSchema;
  /** @deprecated use `Link$outboundSchema` instead. */
  export const outboundSchema = Link$outboundSchema;
  /** @deprecated use `Link$Outbound` instead. */
  export type Outbound = Link$Outbound;
}

export function linkToJSON(link: Link): string {
  return JSON.stringify(Link$outboundSchema.parse(link));
}

export function linkFromJSON(
  jsonString: string,
): SafeParseResult<Link, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => Link$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'Link' from JSON`,
  );
}

/** @internal */
export const Partner$inboundSchema: z.ZodType<Partner, z.ZodTypeDef, unknown> =
  z.object({
    id: z.string(),
    name: z.string(),
    email: z.string(),
    image: z.nullable(z.string()).optional(),
  });

/** @internal */
export type Partner$Outbound = {
  id: string;
  name: string;
  email: string;
  image?: string | null | undefined;
};

/** @internal */
export const Partner$outboundSchema: z.ZodType<
  Partner$Outbound,
  z.ZodTypeDef,
  Partner
> = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string(),
  image: z.nullable(z.string()).optional(),
});

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace Partner$ {
  /** @deprecated use `Partner$inboundSchema` instead. */
  export const inboundSchema = Partner$inboundSchema;
  /** @deprecated use `Partner$outboundSchema` instead. */
  export const outboundSchema = Partner$outboundSchema;
  /** @deprecated use `Partner$Outbound` instead. */
  export type Outbound = Partner$Outbound;
}

export function partnerToJSON(partner: Partner): string {
  return JSON.stringify(Partner$outboundSchema.parse(partner));
}

export function partnerFromJSON(
  jsonString: string,
): SafeParseResult<Partner, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => Partner$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'Partner' from JSON`,
  );
}

/** @internal */
export const Type$inboundSchema: z.ZodNativeEnum<typeof Type> = z.nativeEnum(
  Type,
);

/** @internal */
export const Type$outboundSchema: z.ZodNativeEnum<typeof Type> =
  Type$inboundSchema;

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace Type$ {
  /** @deprecated use `Type$inboundSchema` instead. */
  export const inboundSchema = Type$inboundSchema;
  /** @deprecated use `Type$outboundSchema` instead. */
  export const outboundSchema = Type$outboundSchema;
}

/** @internal */
export const GetCustomersInterval$inboundSchema: z.ZodNativeEnum<
  typeof GetCustomersInterval
> = z.nativeEnum(GetCustomersInterval);

/** @internal */
export const GetCustomersInterval$outboundSchema: z.ZodNativeEnum<
  typeof GetCustomersInterval
> = GetCustomersInterval$inboundSchema;

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace GetCustomersInterval$ {
  /** @deprecated use `GetCustomersInterval$inboundSchema` instead. */
  export const inboundSchema = GetCustomersInterval$inboundSchema;
  /** @deprecated use `GetCustomersInterval$outboundSchema` instead. */
  export const outboundSchema = GetCustomersInterval$outboundSchema;
}

/** @internal */
export const Discount$inboundSchema: z.ZodType<
  Discount,
  z.ZodTypeDef,
  unknown
> = z.object({
  id: z.string(),
  couponId: z.nullable(z.string()),
  couponTestId: z.nullable(z.string()),
  amount: z.number(),
  type: Type$inboundSchema,
  duration: z.nullable(z.number()),
  interval: z.nullable(GetCustomersInterval$inboundSchema),
});

/** @internal */
export type Discount$Outbound = {
  id: string;
  couponId: string | null;
  couponTestId: string | null;
  amount: number;
  type: string;
  duration: number | null;
  interval: string | null;
};

/** @internal */
export const Discount$outboundSchema: z.ZodType<
  Discount$Outbound,
  z.ZodTypeDef,
  Discount
> = z.object({
  id: z.string(),
  couponId: z.nullable(z.string()),
  couponTestId: z.nullable(z.string()),
  amount: z.number(),
  type: Type$outboundSchema,
  duration: z.nullable(z.number()),
  interval: z.nullable(GetCustomersInterval$outboundSchema),
});

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace Discount$ {
  /** @deprecated use `Discount$inboundSchema` instead. */
  export const inboundSchema = Discount$inboundSchema;
  /** @deprecated use `Discount$outboundSchema` instead. */
  export const outboundSchema = Discount$outboundSchema;
  /** @deprecated use `Discount$Outbound` instead. */
  export type Outbound = Discount$Outbound;
}

export function discountToJSON(discount: Discount): string {
  return JSON.stringify(Discount$outboundSchema.parse(discount));
}

export function discountFromJSON(
  jsonString: string,
): SafeParseResult<Discount, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => Discount$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'Discount' from JSON`,
  );
}

/** @internal */
export const GetCustomersResponseBody$inboundSchema: z.ZodType<
  GetCustomersResponseBody,
  z.ZodTypeDef,
  unknown
> = z.object({
  id: z.string(),
  externalId: z.string(),
  name: z.string(),
  email: z.nullable(z.string()).optional(),
  avatar: z.nullable(z.string()).optional(),
  country: z.nullable(z.string()).optional(),
  createdAt: z.string(),
  link: z.nullable(z.lazy(() => Link$inboundSchema)).optional(),
  partner: z.nullable(z.lazy(() => Partner$inboundSchema)).optional(),
  discount: z.nullable(z.lazy(() => Discount$inboundSchema)).optional(),
});

/** @internal */
export type GetCustomersResponseBody$Outbound = {
  id: string;
  externalId: string;
  name: string;
  email?: string | null | undefined;
  avatar?: string | null | undefined;
  country?: string | null | undefined;
  createdAt: string;
  link?: Link$Outbound | null | undefined;
  partner?: Partner$Outbound | null | undefined;
  discount?: Discount$Outbound | null | undefined;
};

/** @internal */
export const GetCustomersResponseBody$outboundSchema: z.ZodType<
  GetCustomersResponseBody$Outbound,
  z.ZodTypeDef,
  GetCustomersResponseBody
> = z.object({
  id: z.string(),
  externalId: z.string(),
  name: z.string(),
  email: z.nullable(z.string()).optional(),
  avatar: z.nullable(z.string()).optional(),
  country: z.nullable(z.string()).optional(),
  createdAt: z.string(),
  link: z.nullable(z.lazy(() => Link$outboundSchema)).optional(),
  partner: z.nullable(z.lazy(() => Partner$outboundSchema)).optional(),
  discount: z.nullable(z.lazy(() => Discount$outboundSchema)).optional(),
});

/**
 * @internal
 * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module.
 */
export namespace GetCustomersResponseBody$ {
  /** @deprecated use `GetCustomersResponseBody$inboundSchema` instead. */
  export const inboundSchema = GetCustomersResponseBody$inboundSchema;
  /** @deprecated use `GetCustomersResponseBody$outboundSchema` instead. */
  export const outboundSchema = GetCustomersResponseBody$outboundSchema;
  /** @deprecated use `GetCustomersResponseBody$Outbound` instead. */
  export type Outbound = GetCustomersResponseBody$Outbound;
}

export function getCustomersResponseBodyToJSON(
  getCustomersResponseBody: GetCustomersResponseBody,
): string {
  return JSON.stringify(
    GetCustomersResponseBody$outboundSchema.parse(getCustomersResponseBody),
  );
}

export function getCustomersResponseBodyFromJSON(
  jsonString: string,
): SafeParseResult<GetCustomersResponseBody, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => GetCustomersResponseBody$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'GetCustomersResponseBody' from JSON`,
  );
}
