/*
 * 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 {
  CountAggregation,
  CountAggregation$Outbound,
  CountAggregation$outboundSchema,
} from "./countaggregation.js";
import { Filter, Filter$Outbound, Filter$outboundSchema } from "./filter.js";
import { MeterUnit, MeterUnit$outboundSchema } from "./meterunit.js";
import {
  PropertyAggregation,
  PropertyAggregation$Outbound,
  PropertyAggregation$outboundSchema,
} from "./propertyaggregation.js";
import {
  UniqueAggregation,
  UniqueAggregation$Outbound,
  UniqueAggregation$outboundSchema,
} from "./uniqueaggregation.js";

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

export type Aggregation =
  | (PropertyAggregation & { func: "avg" })
  | CountAggregation
  | (PropertyAggregation & { func: "max" })
  | (PropertyAggregation & { func: "min" })
  | (PropertyAggregation & { func: "sum" })
  | UniqueAggregation;

export type MeterUpdate = {
  /**
   * 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 name of the meter. Will be shown on customer's invoices and usage.
   */
  name?: string | null | undefined;
  /**
   * The unit of the meter.
   */
  unit?: MeterUnit | null | undefined;
  /**
   * The label for the custom unit. Required when unit is 'custom'.
   */
  customLabel?: string | null | undefined;
  /**
   * The multiplier to convert from base unit to display scale. Required when unit is 'custom'.
   */
  customMultiplier?: number | null | undefined;
  /**
   * The filter to apply on events that'll be used to calculate the meter.
   */
  filter?: Filter | null | undefined;
  /**
   * The aggregation to apply on the filtered events to calculate the meter.
   */
  aggregation?:
    | (PropertyAggregation & { func: "avg" })
    | CountAggregation
    | (PropertyAggregation & { func: "max" })
    | (PropertyAggregation & { func: "min" })
    | (PropertyAggregation & { func: "sum" })
    | UniqueAggregation
    | null
    | undefined;
  /**
   * Whether the meter is archived. Archived meters are no longer used for billing.
   */
  isArchived?: boolean | null | undefined;
};

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

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

export function meterUpdateMetadataToJSON(
  meterUpdateMetadata: MeterUpdateMetadata,
): string {
  return JSON.stringify(
    MeterUpdateMetadata$outboundSchema.parse(meterUpdateMetadata),
  );
}

/** @internal */
export type Aggregation$Outbound =
  | (PropertyAggregation$Outbound & { func: "avg" })
  | CountAggregation$Outbound
  | (PropertyAggregation$Outbound & { func: "max" })
  | (PropertyAggregation$Outbound & { func: "min" })
  | (PropertyAggregation$Outbound & { func: "sum" })
  | UniqueAggregation$Outbound;

/** @internal */
export const Aggregation$outboundSchema: z.ZodMiniType<
  Aggregation$Outbound,
  Aggregation
> = z.union([
  z.intersection(
    PropertyAggregation$outboundSchema,
    z.object({ func: z.literal("avg") }),
  ),
  CountAggregation$outboundSchema,
  z.intersection(
    PropertyAggregation$outboundSchema,
    z.object({ func: z.literal("max") }),
  ),
  z.intersection(
    PropertyAggregation$outboundSchema,
    z.object({ func: z.literal("min") }),
  ),
  z.intersection(
    PropertyAggregation$outboundSchema,
    z.object({ func: z.literal("sum") }),
  ),
  UniqueAggregation$outboundSchema,
]);

export function aggregationToJSON(aggregation: Aggregation): string {
  return JSON.stringify(Aggregation$outboundSchema.parse(aggregation));
}

/** @internal */
export type MeterUpdate$Outbound = {
  metadata?: { [k: string]: string | number | number | boolean } | undefined;
  name?: string | null | undefined;
  unit?: string | null | undefined;
  custom_label?: string | null | undefined;
  custom_multiplier?: number | null | undefined;
  filter?: Filter$Outbound | null | undefined;
  aggregation?:
    | (PropertyAggregation$Outbound & { func: "avg" })
    | CountAggregation$Outbound
    | (PropertyAggregation$Outbound & { func: "max" })
    | (PropertyAggregation$Outbound & { func: "min" })
    | (PropertyAggregation$Outbound & { func: "sum" })
    | UniqueAggregation$Outbound
    | null
    | undefined;
  is_archived?: boolean | null | undefined;
};

/** @internal */
export const MeterUpdate$outboundSchema: z.ZodMiniType<
  MeterUpdate$Outbound,
  MeterUpdate
> = z.pipe(
  z.object({
    metadata: z.optional(
      z.record(
        z.string(),
        smartUnion([z.string(), z.int(), z.number(), z.boolean()]),
      ),
    ),
    name: z.optional(z.nullable(z.string())),
    unit: z.optional(z.nullable(MeterUnit$outboundSchema)),
    customLabel: z.optional(z.nullable(z.string())),
    customMultiplier: z.optional(z.nullable(z.int())),
    filter: z.optional(z.nullable(Filter$outboundSchema)),
    aggregation: z.optional(
      z.nullable(
        z.union([
          z.intersection(
            PropertyAggregation$outboundSchema,
            z.object({ func: z.literal("avg") }),
          ),
          CountAggregation$outboundSchema,
          z.intersection(
            PropertyAggregation$outboundSchema,
            z.object({ func: z.literal("max") }),
          ),
          z.intersection(
            PropertyAggregation$outboundSchema,
            z.object({ func: z.literal("min") }),
          ),
          z.intersection(
            PropertyAggregation$outboundSchema,
            z.object({ func: z.literal("sum") }),
          ),
          UniqueAggregation$outboundSchema,
        ]),
      ),
    ),
    isArchived: z.optional(z.nullable(z.boolean())),
  }),
  z.transform((v) => {
    return remap$(v, {
      customLabel: "custom_label",
      customMultiplier: "custom_multiplier",
      isArchived: "is_archived",
    });
  }),
);

export function meterUpdateToJSON(meterUpdate: MeterUpdate): string {
  return JSON.stringify(MeterUpdate$outboundSchema.parse(meterUpdate));
}
