/*
 * 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 {
  CustomerCancellationReason,
  CustomerCancellationReason$inboundSchema,
} from "./customercancellationreason.js";
import {
  RecurringInterval,
  RecurringInterval$inboundSchema,
} from "./recurringinterval.js";
import {
  SubscriptionStatus,
  SubscriptionStatus$inboundSchema,
} from "./subscriptionstatus.js";

export type CustomerOrderSubscription = {
  /**
   * Creation timestamp of the object.
   */
  createdAt: Date;
  /**
   * Last modification timestamp of the object.
   */
  modifiedAt: Date | null;
  /**
   * The ID of the object.
   */
  id: string;
  /**
   * The amount of the subscription.
   */
  amount: number;
  /**
   * The currency of the subscription.
   */
  currency: string;
  recurringInterval: RecurringInterval;
  /**
   * 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.
   */
  recurringIntervalCount: number;
  status: SubscriptionStatus;
  /**
   * The start timestamp of the current billing period.
   */
  currentPeriodStart: Date;
  /**
   * The end timestamp of the current billing period.
   */
  currentPeriodEnd: Date;
  /**
   * The start timestamp of the current meter period, if the product has a meter cycle set. Metered credits are granted and overage is settled on this cadence.
   */
  currentMeterPeriodStart: Date | null;
  /**
   * The end timestamp of the current meter period, if the product has a meter cycle set. This is when credits next renew.
   */
  currentMeterPeriodEnd: Date | null;
  /**
   * The start timestamp of the trial period, if any.
   */
  trialStart: Date | null;
  /**
   * The end timestamp of the trial period, if any.
   */
  trialEnd: Date | null;
  /**
   * Whether the subscription will be canceled at the end of the current period.
   */
  cancelAtPeriodEnd: boolean;
  /**
   * The timestamp when the subscription was canceled. The subscription might still be active if `cancel_at_period_end` is `true`.
   */
  canceledAt: Date | null;
  /**
   * The timestamp when the subscription started.
   */
  startedAt: Date | null;
  /**
   * The timestamp when the subscription will end.
   */
  endsAt: Date | null;
  /**
   * The timestamp when the subscription ended.
   */
  endedAt: Date | null;
  /**
   * The timestamp when the subscription entered `past_due` status.
   */
  pastDueAt?: Date | null | undefined;
  /**
   * Whether the subscription will be paused at the end of the current period.
   */
  pauseAtPeriodEnd: boolean;
  /**
   * The timestamp when the subscription was paused.
   */
  pausedAt: Date | null;
  /**
   * The timestamp when a paused subscription is scheduled to automatically resume, if set.
   */
  resumesAt: Date | null;
  /**
   * The ID of the subscribed customer.
   */
  customerId: string;
  /**
   * The ID of the subscribed product.
   */
  productId: string;
  /**
   * The ID of the applied discount, if any.
   */
  discountId: string | null;
  checkoutId: string | null;
  /**
   * The number of seats for seat-based subscriptions. None for non-seat subscriptions.
   */
  seats?: number | null | undefined;
  customerCancellationReason: CustomerCancellationReason | null;
  customerCancellationComment: string | null;
};

/** @internal */
export const CustomerOrderSubscription$inboundSchema: z.ZodMiniType<
  CustomerOrderSubscription,
  unknown
> = z.pipe(
  z.object({
    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))),
    ),
    id: z.string(),
    amount: z.int(),
    currency: z.string(),
    recurring_interval: RecurringInterval$inboundSchema,
    recurring_interval_count: z.int(),
    status: SubscriptionStatus$inboundSchema,
    current_period_start: z.pipe(
      z.iso.datetime({ offset: true }),
      z.transform(v => new Date(v)),
    ),
    current_period_end: z.pipe(
      z.iso.datetime({ offset: true }),
      z.transform(v => new Date(v)),
    ),
    current_meter_period_start: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    current_meter_period_end: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    trial_start: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    trial_end: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    cancel_at_period_end: z.boolean(),
    canceled_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    started_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    ends_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    ended_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    past_due_at: z.optional(
      z.nullable(z.pipe(
        z.iso.datetime({ offset: true }),
        z.transform(v => new Date(v)),
      )),
    ),
    pause_at_period_end: z.boolean(),
    paused_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    resumes_at: z.nullable(
      z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))),
    ),
    customer_id: z.string(),
    product_id: z.string(),
    discount_id: z.nullable(z.string()),
    checkout_id: z.nullable(z.string()),
    seats: z.optional(z.nullable(z.int())),
    customer_cancellation_reason: z.nullable(
      CustomerCancellationReason$inboundSchema,
    ),
    customer_cancellation_comment: z.nullable(z.string()),
  }),
  z.transform((v) => {
    return remap$(v, {
      "created_at": "createdAt",
      "modified_at": "modifiedAt",
      "recurring_interval": "recurringInterval",
      "recurring_interval_count": "recurringIntervalCount",
      "current_period_start": "currentPeriodStart",
      "current_period_end": "currentPeriodEnd",
      "current_meter_period_start": "currentMeterPeriodStart",
      "current_meter_period_end": "currentMeterPeriodEnd",
      "trial_start": "trialStart",
      "trial_end": "trialEnd",
      "cancel_at_period_end": "cancelAtPeriodEnd",
      "canceled_at": "canceledAt",
      "started_at": "startedAt",
      "ends_at": "endsAt",
      "ended_at": "endedAt",
      "past_due_at": "pastDueAt",
      "pause_at_period_end": "pauseAtPeriodEnd",
      "paused_at": "pausedAt",
      "resumes_at": "resumesAt",
      "customer_id": "customerId",
      "product_id": "productId",
      "discount_id": "discountId",
      "checkout_id": "checkoutId",
      "customer_cancellation_reason": "customerCancellationReason",
      "customer_cancellation_comment": "customerCancellationComment",
    });
  }),
);

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