/*
 * 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 { SDKValidationError } from "../errors/sdkvalidationerror.js";
import { Address, Address$inboundSchema } from "./address.js";
import {
  CustomerOrderProduct,
  CustomerOrderProduct$inboundSchema,
} from "./customerorderproduct.js";
import {
  CustomerOrderSubscription,
  CustomerOrderSubscription$inboundSchema,
} from "./customerordersubscription.js";
import {
  OrderBillingReason,
  OrderBillingReason$inboundSchema,
} from "./orderbillingreason.js";
import {
  OrderItemSchema,
  OrderItemSchema$inboundSchema,
} from "./orderitemschema.js";
import { OrderStatus, OrderStatus$inboundSchema } from "./orderstatus.js";

export type CustomerOrder = {
  /**
   * 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;
  product: CustomerOrderProduct | null;
  subscription: CustomerOrderSubscription | 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 CustomerOrder$inboundSchema: z.ZodMiniType<
  CustomerOrder,
  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)),
      )),
    ),
    product: z.nullable(CustomerOrderProduct$inboundSchema),
    subscription: z.nullable(CustomerOrderSubscription$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",
      "refundable_amount": "refundableAmount",
      "refundable_tax_amount": "refundableTaxAmount",
    });
  }),
);

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