/*
 * 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 MeterCreateMetadata = string | number | number | boolean;

/**
 * The aggregation to apply on the filtered events to calculate the meter.
 */
export type MeterCreateAggregation =
  | (PropertyAggregation & { func: "avg" })
  | CountAggregation
  | (PropertyAggregation & { func: "max" })
  | (PropertyAggregation & { func: "min" })
  | (PropertyAggregation & { func: "sum" })
  | UniqueAggregation;

export type MeterCreate = {
  /**
   * 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;
  unit?: MeterUnit | undefined;
  /**
   * The label for the custom unit, e.g. 'request'. Required when unit is 'custom'.
   */
  customLabel?: string | null | undefined;
  /**
   * The multiplier to convert from the base unit to display scale, e.g. 1000 to display per 1000 units. Defaults to 1 when not provided.
   */
  customMultiplier?: number | null | undefined;
  filter: Filter;
  /**
   * 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;
  /**
   * The ID of the organization owning the meter. **Required unless you use an organization token.**
   */
  organizationId?: string | null | undefined;
};

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

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

export function meterCreateMetadataToJSON(
  meterCreateMetadata: MeterCreateMetadata,
): string {
  return JSON.stringify(
    MeterCreateMetadata$outboundSchema.parse(meterCreateMetadata),
  );
}

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

/** @internal */
export const MeterCreateAggregation$outboundSchema: z.ZodMiniType<
  MeterCreateAggregation$Outbound,
  MeterCreateAggregation
> = 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 meterCreateAggregationToJSON(
  meterCreateAggregation: MeterCreateAggregation,
): string {
  return JSON.stringify(
    MeterCreateAggregation$outboundSchema.parse(meterCreateAggregation),
  );
}

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

/** @internal */
export const MeterCreate$outboundSchema: z.ZodMiniType<
  MeterCreate$Outbound,
  MeterCreate
> = z.pipe(
  z.object({
    metadata: z.optional(
      z.record(
        z.string(),
        smartUnion([z.string(), z.int(), z.number(), z.boolean()]),
      ),
    ),
    name: z.string(),
    unit: z.optional(MeterUnit$outboundSchema),
    customLabel: z.optional(z.nullable(z.string())),
    customMultiplier: z.optional(z.nullable(z.int())),
    filter: Filter$outboundSchema,
    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,
    ]),
    organizationId: z.optional(z.nullable(z.string())),
  }),
  z.transform((v) => {
    return remap$(v, {
      customLabel: "custom_label",
      customMultiplier: "custom_multiplier",
      organizationId: "organization_id",
    });
  }),
);

export function meterCreateToJSON(meterCreate: MeterCreate): string {
  return JSON.stringify(MeterCreate$outboundSchema.parse(meterCreate));
}
