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

import * as z from "zod/v4-mini";
import { remap as remap$ } from "../../lib/primitives.js";
import { smartUnion } from "../../types/smartUnion.js";
import {
  AttachedCustomFieldCreate,
  AttachedCustomFieldCreate$Outbound,
  AttachedCustomFieldCreate$outboundSchema,
} from "./attachedcustomfieldcreate.js";
import {
  ExistingProductPrice,
  ExistingProductPrice$Outbound,
  ExistingProductPrice$outboundSchema,
} from "./existingproductprice.js";
import {
  ProductPriceCustomCreate,
  ProductPriceCustomCreate$Outbound,
  ProductPriceCustomCreate$outboundSchema,
} from "./productpricecustomcreate.js";
import {
  ProductPriceFixedCreate,
  ProductPriceFixedCreate$Outbound,
  ProductPriceFixedCreate$outboundSchema,
} from "./productpricefixedcreate.js";
import {
  ProductPriceMeteredUnitCreate,
  ProductPriceMeteredUnitCreate$Outbound,
  ProductPriceMeteredUnitCreate$outboundSchema,
} from "./productpricemeteredunitcreate.js";
import {
  ProductPriceSeatBasedCreate,
  ProductPriceSeatBasedCreate$Outbound,
  ProductPriceSeatBasedCreate$outboundSchema,
} from "./productpriceseatbasedcreate.js";
import {
  ProductVisibility,
  ProductVisibility$outboundSchema,
} from "./productvisibility.js";
import {
  RecurringInterval,
  RecurringInterval$outboundSchema,
} from "./recurringinterval.js";
import {
  TrialInterval,
  TrialInterval$outboundSchema,
} from "./trialinterval.js";

export type ProductUpdateMetadata = string | number | number | boolean;

export type Two =
  | ProductPriceCustomCreate
  | ProductPriceFixedCreate
  | ProductPriceMeteredUnitCreate
  | ProductPriceSeatBasedCreate;

export type ProductUpdatePrices =
  | ExistingProductPrice
  | ProductPriceCustomCreate
  | ProductPriceFixedCreate
  | ProductPriceMeteredUnitCreate
  | ProductPriceSeatBasedCreate;

/**
 * Schema to update a product.
 */
export type ProductUpdate = {
  /**
   * Key-value object allowing you to store additional information.
   *
   * @remarks
   *
   * The key must be a string with a maximum length of **40 characters**.
   * The value must be either:
   *
   * * A string with a maximum length of **500 characters**
   * * An integer
   * * A floating-point number
   * * A boolean
   *
   * You can store up to **50 key-value pairs**.
   */
  metadata?: { [k: string]: string | number | number | boolean } | undefined;
  /**
   * The interval unit for the trial period.
   */
  trialInterval?: TrialInterval | null | undefined;
  /**
   * The number of interval units for the trial period.
   */
  trialIntervalCount?: number | null | undefined;
  name?: string | null | undefined;
  /**
   * The description of the product.
   */
  description?: string | null | undefined;
  /**
   * The recurring interval of the product. If `None`, the product is a one-time purchase. **Can only be set on legacy recurring products. Once set, it can't be changed.**
   */
  recurringInterval?: RecurringInterval | null | undefined;
  /**
   * Number of interval units of the subscription. If this is set to 1 the charge will happen every interval (e.g. every month), if set to 2 it will be every other month, and so on. Once set, it can't be changed.**
   */
  recurringIntervalCount?: number | null | undefined;
  /**
   * Whether the product is archived. If `true`, the product won't be available for purchase anymore. Existing customers will still have access to their benefits, and subscriptions will continue normally.
   */
  isArchived?: boolean | null | undefined;
  /**
   * The visibility of the product.
   */
  visibility?: ProductVisibility | null | undefined;
  /**
   * List of available prices for this product. If you want to keep existing prices, include them in the list as an `ExistingProductPrice` object.
   */
  prices?:
    | Array<
      | ExistingProductPrice
      | ProductPriceCustomCreate
      | ProductPriceFixedCreate
      | ProductPriceMeteredUnitCreate
      | ProductPriceSeatBasedCreate
    >
    | null
    | undefined;
  /**
   * List of file IDs. Each one must be on the same organization as the product, of type `product_media` and correctly uploaded.
   */
  medias?: Array<string> | null | undefined;
  attachedCustomFields?: Array<AttachedCustomFieldCreate> | null | undefined;
};

/** @internal */
export type ProductUpdateMetadata$Outbound = string | number | number | boolean;

/** @internal */
export const ProductUpdateMetadata$outboundSchema: z.ZodMiniType<
  ProductUpdateMetadata$Outbound,
  ProductUpdateMetadata
> = smartUnion([z.string(), z.int(), z.number(), z.boolean()]);

export function productUpdateMetadataToJSON(
  productUpdateMetadata: ProductUpdateMetadata,
): string {
  return JSON.stringify(
    ProductUpdateMetadata$outboundSchema.parse(productUpdateMetadata),
  );
}

/** @internal */
export type Two$Outbound =
  | ProductPriceCustomCreate$Outbound
  | ProductPriceFixedCreate$Outbound
  | ProductPriceMeteredUnitCreate$Outbound
  | ProductPriceSeatBasedCreate$Outbound;

/** @internal */
export const Two$outboundSchema: z.ZodMiniType<Two$Outbound, Two> = z.union([
  ProductPriceCustomCreate$outboundSchema,
  ProductPriceFixedCreate$outboundSchema,
  ProductPriceMeteredUnitCreate$outboundSchema,
  ProductPriceSeatBasedCreate$outboundSchema,
]);

export function twoToJSON(two: Two): string {
  return JSON.stringify(Two$outboundSchema.parse(two));
}

/** @internal */
export type ProductUpdatePrices$Outbound =
  | ExistingProductPrice$Outbound
  | ProductPriceCustomCreate$Outbound
  | ProductPriceFixedCreate$Outbound
  | ProductPriceMeteredUnitCreate$Outbound
  | ProductPriceSeatBasedCreate$Outbound;

/** @internal */
export const ProductUpdatePrices$outboundSchema: z.ZodMiniType<
  ProductUpdatePrices$Outbound,
  ProductUpdatePrices
> = smartUnion([
  ExistingProductPrice$outboundSchema,
  z.union([
    ProductPriceCustomCreate$outboundSchema,
    ProductPriceFixedCreate$outboundSchema,
    ProductPriceMeteredUnitCreate$outboundSchema,
    ProductPriceSeatBasedCreate$outboundSchema,
  ]),
]);

export function productUpdatePricesToJSON(
  productUpdatePrices: ProductUpdatePrices,
): string {
  return JSON.stringify(
    ProductUpdatePrices$outboundSchema.parse(productUpdatePrices),
  );
}

/** @internal */
export type ProductUpdate$Outbound = {
  metadata?: { [k: string]: string | number | number | boolean } | undefined;
  trial_interval?: string | null | undefined;
  trial_interval_count?: number | null | undefined;
  name?: string | null | undefined;
  description?: string | null | undefined;
  recurring_interval?: string | null | undefined;
  recurring_interval_count?: number | null | undefined;
  is_archived?: boolean | null | undefined;
  visibility?: string | null | undefined;
  prices?:
    | Array<
      | ExistingProductPrice$Outbound
      | ProductPriceCustomCreate$Outbound
      | ProductPriceFixedCreate$Outbound
      | ProductPriceMeteredUnitCreate$Outbound
      | ProductPriceSeatBasedCreate$Outbound
    >
    | null
    | undefined;
  medias?: Array<string> | null | undefined;
  attached_custom_fields?:
    | Array<AttachedCustomFieldCreate$Outbound>
    | null
    | undefined;
};

/** @internal */
export const ProductUpdate$outboundSchema: z.ZodMiniType<
  ProductUpdate$Outbound,
  ProductUpdate
> = z.pipe(
  z.object({
    metadata: z.optional(
      z.record(
        z.string(),
        smartUnion([z.string(), z.int(), z.number(), z.boolean()]),
      ),
    ),
    trialInterval: z.optional(z.nullable(TrialInterval$outboundSchema)),
    trialIntervalCount: z.optional(z.nullable(z.int())),
    name: z.optional(z.nullable(z.string())),
    description: z.optional(z.nullable(z.string())),
    recurringInterval: z.optional(z.nullable(RecurringInterval$outboundSchema)),
    recurringIntervalCount: z.optional(z.nullable(z.int())),
    isArchived: z.optional(z.nullable(z.boolean())),
    visibility: z.optional(z.nullable(ProductVisibility$outboundSchema)),
    prices: z.optional(
      z.nullable(
        z.array(
          smartUnion([
            ExistingProductPrice$outboundSchema,
            z.union([
              ProductPriceCustomCreate$outboundSchema,
              ProductPriceFixedCreate$outboundSchema,
              ProductPriceMeteredUnitCreate$outboundSchema,
              ProductPriceSeatBasedCreate$outboundSchema,
            ]),
          ]),
        ),
      ),
    ),
    medias: z.optional(z.nullable(z.array(z.string()))),
    attachedCustomFields: z.optional(
      z.nullable(z.array(AttachedCustomFieldCreate$outboundSchema)),
    ),
  }),
  z.transform((v) => {
    return remap$(v, {
      trialInterval: "trial_interval",
      trialIntervalCount: "trial_interval_count",
      recurringInterval: "recurring_interval",
      recurringIntervalCount: "recurring_interval_count",
      isArchived: "is_archived",
      attachedCustomFields: "attached_custom_fields",
    });
  }),
);

export function productUpdateToJSON(productUpdate: ProductUpdate): string {
  return JSON.stringify(ProductUpdate$outboundSchema.parse(productUpdate));
}
