/*
 * 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 { safeParse } from "../../lib/schemas.js";
import { Result as SafeParseResult } from "../../types/fp.js";
import { smartUnion } from "../../types/smartUnion.js";
import { SDKValidationError } from "../errors/sdkvalidationerror.js";
import {
  Address,
  Address$inboundSchema,
  Address$Outbound,
  Address$outboundSchema,
} from "./address.js";
import {
  DiscountFixedOnceForeverDurationBase,
  DiscountFixedOnceForeverDurationBase$inboundSchema,
  DiscountFixedOnceForeverDurationBase$Outbound,
  DiscountFixedOnceForeverDurationBase$outboundSchema,
} from "./discountfixedonceforeverdurationbase.js";
import {
  DiscountFixedRepeatDurationBase,
  DiscountFixedRepeatDurationBase$inboundSchema,
  DiscountFixedRepeatDurationBase$Outbound,
  DiscountFixedRepeatDurationBase$outboundSchema,
} from "./discountfixedrepeatdurationbase.js";
import {
  DiscountPercentageOnceForeverDurationBase,
  DiscountPercentageOnceForeverDurationBase$inboundSchema,
  DiscountPercentageOnceForeverDurationBase$Outbound,
  DiscountPercentageOnceForeverDurationBase$outboundSchema,
} from "./discountpercentageonceforeverdurationbase.js";
import {
  DiscountPercentageRepeatDurationBase,
  DiscountPercentageRepeatDurationBase$inboundSchema,
  DiscountPercentageRepeatDurationBase$Outbound,
  DiscountPercentageRepeatDurationBase$outboundSchema,
} from "./discountpercentagerepeatdurationbase.js";
import {
  MetadataOutputType,
  MetadataOutputType$inboundSchema,
  MetadataOutputType$Outbound,
  MetadataOutputType$outboundSchema,
} from "./metadataoutputtype.js";
import {
  OrderBillingReason,
  OrderBillingReason$inboundSchema,
  OrderBillingReason$outboundSchema,
} from "./orderbillingreason.js";
import {
  OrderCustomer,
  OrderCustomer$inboundSchema,
  OrderCustomer$Outbound,
  OrderCustomer$outboundSchema,
} from "./ordercustomer.js";
import {
  OrderItemSchema,
  OrderItemSchema$inboundSchema,
  OrderItemSchema$Outbound,
  OrderItemSchema$outboundSchema,
} from "./orderitemschema.js";
import {
  OrderProduct,
  OrderProduct$inboundSchema,
  OrderProduct$Outbound,
  OrderProduct$outboundSchema,
} from "./orderproduct.js";
import {
  OrderStatus,
  OrderStatus$inboundSchema,
  OrderStatus$outboundSchema,
} from "./orderstatus.js";
import {
  OrderSubscription,
  OrderSubscription$inboundSchema,
  OrderSubscription$Outbound,
  OrderSubscription$outboundSchema,
} from "./ordersubscription.js";

export type OrderCustomFieldData = string | number | boolean | Date;

export type OrderDiscount =
  | DiscountFixedRepeatDurationBase
  | DiscountFixedOnceForeverDurationBase
  | DiscountPercentageRepeatDurationBase
  | DiscountPercentageOnceForeverDurationBase;

export type Order = {
  /**
   * The ID of the object.
   */
  id: string;
  /**
   * Creation timestamp of the object.
   */
  createdAt: Date;
  /**
   * Last modification timestamp of the object.
   */
  modifiedAt: Date | null;
  status: OrderStatus;
  /**
   * Whether the order has been paid for.
   */
  paid: boolean;
  /**
   * Amount in cents, before discounts and taxes.
   */
  subtotalAmount: number;
  /**
   * Discount amount in cents.
   */
  discountAmount: number;
  /**
   * Amount in cents, after discounts but before taxes.
   */
  netAmount: number;
  /**
   * Sales tax amount in cents.
   */
  taxAmount: number;
  /**
   * Amount in cents, after discounts and taxes.
   */
  totalAmount: number;
  /**
   * Customer's balance amount applied to this invoice. Can increase the total amount paid, if the customer has a negative balance,  or decrease it, if the customer has a positive balance.Amount in cents.
   */
  appliedBalanceAmount: number;
  /**
   * Amount in cents that is due for this order.
   */
  dueAmount: number;
  /**
   * Amount refunded in cents.
   */
  refundedAmount: number;
  /**
   * Sales tax refunded in cents.
   */
  refundedTaxAmount: number;
  currency: string;
  billingReason: OrderBillingReason;
  /**
   * The name of the customer that should appear on the invoice.
   */
  billingName: string | null;
  billingAddress: Address | null;
  /**
   * The invoice number associated with this order. `null` while the order is in `draft` status; assigned at finalize.
   */
  invoiceNumber: string | null;
  /**
   * Whether an invoice has been generated for this order.
   */
  isInvoiceGenerated: boolean;
  /**
   * The receipt number for this order. Set once the order is paid for organizations with receipts enabled. When set, a downloadable receipt PDF can be obtained via the receipt endpoint.
   */
  receiptNumber: string | null;
  /**
   * Number of seats purchased (for seat-based one-time orders).
   */
  seats?: number | null | undefined;
  customerId: string;
  productId: string | null;
  discountId: string | null;
  subscriptionId: string | null;
  checkoutId: string | null;
  /**
   * When the next automatic payment retry is scheduled. `null` if the order is not in dunning or all retries have been exhausted.
   */
  nextPaymentAttemptAt?: Date | null | undefined;
  metadata: { [k: string]: MetadataOutputType };
  /**
   * Key-value object storing custom field values.
   */
  customFieldData?:
    | { [k: string]: string | number | boolean | Date | null }
    | undefined;
  /**
   * Platform fee amount in cents.
   */
  platformFeeAmount: number;
  /**
   * Currency of the platform fee.
   */
  platformFeeCurrency: string | null;
  customer: OrderCustomer;
  product: OrderProduct | null;
  discount:
    | DiscountFixedRepeatDurationBase
    | DiscountFixedOnceForeverDurationBase
    | DiscountPercentageRepeatDurationBase
    | DiscountPercentageOnceForeverDurationBase
    | null;
  subscription: OrderSubscription | null;
  /**
   * Line items composing the order.
   */
  items: Array<OrderItemSchema>;
  /**
   * A summary description of the order.
   */
  description: string;
  /**
   * Amount in cents that can still be refunded (net, before taxes). Accounts for any applied customer balance and previous refunds.
   */
  refundableAmount: number;
  /**
   * Sales tax in cents that would be refunded if the full refundable amount is refunded.
   */
  refundableTaxAmount: number;
};

/** @internal */
export const OrderCustomFieldData$inboundSchema: z.ZodMiniType<
  OrderCustomFieldData,
  unknown
> = smartUnion([
  z.string(),
  z.int(),
  z.boolean(),
  z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
]);
/** @internal */
export type OrderCustomFieldData$Outbound = string | number | boolean | string;

/** @internal */
export const OrderCustomFieldData$outboundSchema: z.ZodMiniType<
  OrderCustomFieldData$Outbound,
  OrderCustomFieldData
> = smartUnion([
  z.string(),
  z.int(),
  z.boolean(),
  z.pipe(z.date(), z.transform(v => v.toISOString())),
]);

export function orderCustomFieldDataToJSON(
  orderCustomFieldData: OrderCustomFieldData,
): string {
  return JSON.stringify(
    OrderCustomFieldData$outboundSchema.parse(orderCustomFieldData),
  );
}
export function orderCustomFieldDataFromJSON(
  jsonString: string,
): SafeParseResult<OrderCustomFieldData, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => OrderCustomFieldData$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'OrderCustomFieldData' from JSON`,
  );
}

/** @internal */
export const OrderDiscount$inboundSchema: z.ZodMiniType<
  OrderDiscount,
  unknown
> = smartUnion([
  DiscountFixedRepeatDurationBase$inboundSchema,
  DiscountFixedOnceForeverDurationBase$inboundSchema,
  DiscountPercentageRepeatDurationBase$inboundSchema,
  DiscountPercentageOnceForeverDurationBase$inboundSchema,
]);
/** @internal */
export type OrderDiscount$Outbound =
  | DiscountFixedRepeatDurationBase$Outbound
  | DiscountFixedOnceForeverDurationBase$Outbound
  | DiscountPercentageRepeatDurationBase$Outbound
  | DiscountPercentageOnceForeverDurationBase$Outbound;

/** @internal */
export const OrderDiscount$outboundSchema: z.ZodMiniType<
  OrderDiscount$Outbound,
  OrderDiscount
> = smartUnion([
  DiscountFixedRepeatDurationBase$outboundSchema,
  DiscountFixedOnceForeverDurationBase$outboundSchema,
  DiscountPercentageRepeatDurationBase$outboundSchema,
  DiscountPercentageOnceForeverDurationBase$outboundSchema,
]);

export function orderDiscountToJSON(orderDiscount: OrderDiscount): string {
  return JSON.stringify(OrderDiscount$outboundSchema.parse(orderDiscount));
}
export function orderDiscountFromJSON(
  jsonString: string,
): SafeParseResult<OrderDiscount, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => OrderDiscount$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'OrderDiscount' from JSON`,
  );
}

/** @internal */
export const Order$inboundSchema: z.ZodMiniType<Order, unknown> = z.pipe(
  z.object({
    id: z.string(),
    created_at: z.pipe(
      z.iso.datetime({ offset: true }),
      z.transform(v => new Date(v)),
    ),
    modified_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    status: OrderStatus$inboundSchema,
    paid: z.boolean(),
    subtotal_amount: z.int(),
    discount_amount: z.int(),
    net_amount: z.int(),
    tax_amount: z.int(),
    total_amount: z.int(),
    applied_balance_amount: z.int(),
    due_amount: z.int(),
    refunded_amount: z.int(),
    refunded_tax_amount: z.int(),
    currency: z.string(),
    billing_reason: OrderBillingReason$inboundSchema,
    billing_name: z.nullable(z.string()),
    billing_address: z.nullable(Address$inboundSchema),
    invoice_number: z.nullable(z.string()),
    is_invoice_generated: z.boolean(),
    receipt_number: z.nullable(z.string()),
    seats: z.optional(z.nullable(z.int())),
    customer_id: z.string(),
    product_id: z.nullable(z.string()),
    discount_id: z.nullable(z.string()),
    subscription_id: z.nullable(z.string()),
    checkout_id: z.nullable(z.string()),
    next_payment_attempt_at: z.optional(
      z.nullable(z.pipe(
        z.iso.datetime({ offset: true }),
        z.transform(v => new Date(v)),
      )),
    ),
    metadata: z.record(z.string(), MetadataOutputType$inboundSchema),
    custom_field_data: z.optional(
      z.record(
        z.string(),
        z.nullable(
          smartUnion([
            z.string(),
            z.int(),
            z.boolean(),
            z.pipe(
              z.iso.datetime({ offset: true }),
              z.transform(v => new Date(v)),
            ),
          ]),
        ),
      ),
    ),
    platform_fee_amount: z.int(),
    platform_fee_currency: z.nullable(z.string()),
    customer: OrderCustomer$inboundSchema,
    product: z.nullable(OrderProduct$inboundSchema),
    discount: z.nullable(
      smartUnion([
        DiscountFixedRepeatDurationBase$inboundSchema,
        DiscountFixedOnceForeverDurationBase$inboundSchema,
        DiscountPercentageRepeatDurationBase$inboundSchema,
        DiscountPercentageOnceForeverDurationBase$inboundSchema,
      ]),
    ),
    subscription: z.nullable(OrderSubscription$inboundSchema),
    items: z.array(OrderItemSchema$inboundSchema),
    description: z.string(),
    refundable_amount: z.int(),
    refundable_tax_amount: z.int(),
  }),
  z.transform((v) => {
    return remap$(v, {
      "created_at": "createdAt",
      "modified_at": "modifiedAt",
      "subtotal_amount": "subtotalAmount",
      "discount_amount": "discountAmount",
      "net_amount": "netAmount",
      "tax_amount": "taxAmount",
      "total_amount": "totalAmount",
      "applied_balance_amount": "appliedBalanceAmount",
      "due_amount": "dueAmount",
      "refunded_amount": "refundedAmount",
      "refunded_tax_amount": "refundedTaxAmount",
      "billing_reason": "billingReason",
      "billing_name": "billingName",
      "billing_address": "billingAddress",
      "invoice_number": "invoiceNumber",
      "is_invoice_generated": "isInvoiceGenerated",
      "receipt_number": "receiptNumber",
      "customer_id": "customerId",
      "product_id": "productId",
      "discount_id": "discountId",
      "subscription_id": "subscriptionId",
      "checkout_id": "checkoutId",
      "next_payment_attempt_at": "nextPaymentAttemptAt",
      "custom_field_data": "customFieldData",
      "platform_fee_amount": "platformFeeAmount",
      "platform_fee_currency": "platformFeeCurrency",
      "refundable_amount": "refundableAmount",
      "refundable_tax_amount": "refundableTaxAmount",
    });
  }),
);
/** @internal */
export type Order$Outbound = {
  id: string;
  created_at: string;
  modified_at: string | null;
  status: string;
  paid: boolean;
  subtotal_amount: number;
  discount_amount: number;
  net_amount: number;
  tax_amount: number;
  total_amount: number;
  applied_balance_amount: number;
  due_amount: number;
  refunded_amount: number;
  refunded_tax_amount: number;
  currency: string;
  billing_reason: string;
  billing_name: string | null;
  billing_address: Address$Outbound | null;
  invoice_number: string | null;
  is_invoice_generated: boolean;
  receipt_number: string | null;
  seats?: number | null | undefined;
  customer_id: string;
  product_id: string | null;
  discount_id: string | null;
  subscription_id: string | null;
  checkout_id: string | null;
  next_payment_attempt_at?: string | null | undefined;
  metadata: { [k: string]: MetadataOutputType$Outbound };
  custom_field_data?:
    | { [k: string]: string | number | boolean | string | null }
    | undefined;
  platform_fee_amount: number;
  platform_fee_currency: string | null;
  customer: OrderCustomer$Outbound;
  product: OrderProduct$Outbound | null;
  discount:
    | DiscountFixedRepeatDurationBase$Outbound
    | DiscountFixedOnceForeverDurationBase$Outbound
    | DiscountPercentageRepeatDurationBase$Outbound
    | DiscountPercentageOnceForeverDurationBase$Outbound
    | null;
  subscription: OrderSubscription$Outbound | null;
  items: Array<OrderItemSchema$Outbound>;
  description: string;
  refundable_amount: number;
  refundable_tax_amount: number;
};

/** @internal */
export const Order$outboundSchema: z.ZodMiniType<Order$Outbound, Order> = z
  .pipe(
    z.object({
      id: z.string(),
      createdAt: z.pipe(z.date(), z.transform(v => v.toISOString())),
      modifiedAt: z.nullable(
        z.pipe(z.date(), z.transform(v => v.toISOString())),
      ),
      status: OrderStatus$outboundSchema,
      paid: z.boolean(),
      subtotalAmount: z.int(),
      discountAmount: z.int(),
      netAmount: z.int(),
      taxAmount: z.int(),
      totalAmount: z.int(),
      appliedBalanceAmount: z.int(),
      dueAmount: z.int(),
      refundedAmount: z.int(),
      refundedTaxAmount: z.int(),
      currency: z.string(),
      billingReason: OrderBillingReason$outboundSchema,
      billingName: z.nullable(z.string()),
      billingAddress: z.nullable(Address$outboundSchema),
      invoiceNumber: z.nullable(z.string()),
      isInvoiceGenerated: z.boolean(),
      receiptNumber: z.nullable(z.string()),
      seats: z.optional(z.nullable(z.int())),
      customerId: z.string(),
      productId: z.nullable(z.string()),
      discountId: z.nullable(z.string()),
      subscriptionId: z.nullable(z.string()),
      checkoutId: z.nullable(z.string()),
      nextPaymentAttemptAt: z.optional(
        z.nullable(z.pipe(z.date(), z.transform(v => v.toISOString()))),
      ),
      metadata: z.record(z.string(), MetadataOutputType$outboundSchema),
      customFieldData: z.optional(
        z.record(
          z.string(),
          z.nullable(
            smartUnion([
              z.string(),
              z.int(),
              z.boolean(),
              z.pipe(z.date(), z.transform(v => v.toISOString())),
            ]),
          ),
        ),
      ),
      platformFeeAmount: z.int(),
      platformFeeCurrency: z.nullable(z.string()),
      customer: OrderCustomer$outboundSchema,
      product: z.nullable(OrderProduct$outboundSchema),
      discount: z.nullable(
        smartUnion([
          DiscountFixedRepeatDurationBase$outboundSchema,
          DiscountFixedOnceForeverDurationBase$outboundSchema,
          DiscountPercentageRepeatDurationBase$outboundSchema,
          DiscountPercentageOnceForeverDurationBase$outboundSchema,
        ]),
      ),
      subscription: z.nullable(OrderSubscription$outboundSchema),
      items: z.array(OrderItemSchema$outboundSchema),
      description: z.string(),
      refundableAmount: z.int(),
      refundableTaxAmount: z.int(),
    }),
    z.transform((v) => {
      return remap$(v, {
        createdAt: "created_at",
        modifiedAt: "modified_at",
        subtotalAmount: "subtotal_amount",
        discountAmount: "discount_amount",
        netAmount: "net_amount",
        taxAmount: "tax_amount",
        totalAmount: "total_amount",
        appliedBalanceAmount: "applied_balance_amount",
        dueAmount: "due_amount",
        refundedAmount: "refunded_amount",
        refundedTaxAmount: "refunded_tax_amount",
        billingReason: "billing_reason",
        billingName: "billing_name",
        billingAddress: "billing_address",
        invoiceNumber: "invoice_number",
        isInvoiceGenerated: "is_invoice_generated",
        receiptNumber: "receipt_number",
        customerId: "customer_id",
        productId: "product_id",
        discountId: "discount_id",
        subscriptionId: "subscription_id",
        checkoutId: "checkout_id",
        nextPaymentAttemptAt: "next_payment_attempt_at",
        customFieldData: "custom_field_data",
        platformFeeAmount: "platform_fee_amount",
        platformFeeCurrency: "platform_fee_currency",
        refundableAmount: "refundable_amount",
        refundableTaxAmount: "refundable_tax_amount",
      });
    }),
  );

export function orderToJSON(order: Order): string {
  return JSON.stringify(Order$outboundSchema.parse(order));
}
export function orderFromJSON(
  jsonString: string,
): SafeParseResult<Order, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => Order$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'Order' from JSON`,
  );
}
