/**
 * 用户权益快照
 */
import { z } from "zod";

import {
  booleanOrFalse,
  numberOrZero,
  schemaOr,
  stringOrEmpty,
  stringOrNull,
} from "../nullable-defaults";

const POLICY_DEFAULTS = {
  membershipState: "",
  nonVipEntitlementsShared: false,
  guestSameAsLoggedInNonVip: false,
  refreshAfterPayment: "",
} as const;

const COSTS_DEFAULTS = {
  normal_message: 0,
  private_message: 0,
  voice_message: 0,
  photo: 0,
  voice_call_minute: 0,
  private_album_10: 0,
  private_album_20: 0,
} as const;

const QUOTAS_DEFAULTS = {
  normalChatFreeDaily: 0,
  privateUnlockFreeDaily: 0,
  voiceMessageFreeDaily: 0,
  photoFreeDaily: 0,
} as const;

const HISTORY_UNLOCK_COSTS_DEFAULTS = {
  private_message: 0,
  voice_message: 0,
  photo: 0,
} as const;

const HISTORY_UNLOCK_DEFAULTS = {
  enabled: false,
  order: "",
  chargeMode: "",
  insufficientBalanceBehavior: "",
  costs: HISTORY_UNLOCK_COSTS_DEFAULTS,
} as const;

const VOICE_CALL_BILLING_DEFAULTS = {
  enabled: false,
  protocolVersion: 2,
  chargeMode: "per_turn",
  sharesNormalChatFreeDaily: true,
  freeTurnsDaily: 0,
  costPerPaidTurn: 0,
  usageType: "voice_call_turn",
  legacyMinuteCostUsed: false,
} as const;

export const UserEntitlementsPolicySchema = z
  .object({
    membershipState: stringOrEmpty,
    nonVipEntitlementsShared: booleanOrFalse,
    guestSameAsLoggedInNonVip: booleanOrFalse,
    refreshAfterPayment: stringOrEmpty,
  })
  .passthrough()
  .readonly();

export const UserEntitlementsCostsSchema = z
  .object({
    normal_message: numberOrZero,
    private_message: numberOrZero,
    voice_message: numberOrZero,
    photo: numberOrZero,
    voice_call_minute: numberOrZero,
    private_album_10: numberOrZero,
    private_album_20: numberOrZero,
  })
  .passthrough()
  .readonly();

export const UserEntitlementsQuotasSchema = z
  .object({
    normalChatFreeDaily: numberOrZero,
    privateUnlockFreeDaily: numberOrZero,
    voiceMessageFreeDaily: numberOrZero,
    photoFreeDaily: numberOrZero,
  })
  .passthrough()
  .readonly();

export const UserEntitlementsHistoryUnlockCostsSchema = z
  .object({
    private_message: numberOrZero,
    voice_message: numberOrZero,
    photo: numberOrZero,
  })
  .passthrough()
  .readonly();

export const UserEntitlementsHistoryUnlockSchema = z
  .object({
    enabled: booleanOrFalse,
    order: stringOrEmpty,
    chargeMode: stringOrEmpty,
    insufficientBalanceBehavior: stringOrEmpty,
    costs: schemaOr(
      UserEntitlementsHistoryUnlockCostsSchema,
      HISTORY_UNLOCK_COSTS_DEFAULTS,
    ),
  })
  .passthrough()
  .readonly();

export const VoiceCallBillingSchema = z
  .object({
    enabled: booleanOrFalse,
    protocolVersion: numberOrZero,
    chargeMode: stringOrEmpty,
    sharesNormalChatFreeDaily: booleanOrFalse,
    freeTurnsDaily: numberOrZero,
    costPerPaidTurn: numberOrZero,
    usageType: stringOrEmpty,
    legacyMinuteCostUsed: booleanOrFalse,
  })
  .passthrough()
  .readonly();

export const UserEntitlementsSchema = z
  .object({
    userId: stringOrEmpty,
    isGuest: booleanOrFalse,
    isVip: booleanOrFalse,
    vipExpiresAt: stringOrNull,
    creditBalance: numberOrZero,
    dolBalance: numberOrZero,
    policy: schemaOr(UserEntitlementsPolicySchema, POLICY_DEFAULTS),
    costs: schemaOr(UserEntitlementsCostsSchema, COSTS_DEFAULTS),
    quotas: schemaOr(UserEntitlementsQuotasSchema, QUOTAS_DEFAULTS),
    historyUnlock: schemaOr(
      UserEntitlementsHistoryUnlockSchema,
      HISTORY_UNLOCK_DEFAULTS,
    ),
    voiceCallBilling: schemaOr(
      VoiceCallBillingSchema,
      VOICE_CALL_BILLING_DEFAULTS,
    ),
  })
  .readonly();

export type UserEntitlementsInput = z.input<typeof UserEntitlementsSchema>;
export type UserEntitlementsData = z.output<typeof UserEntitlementsSchema>;

export type UserEntitlements = UserEntitlementsData;
