import { z } from "zod"

import { MembershipLevelEnum } from "@/constants/membershipLevels"

const Coupon = z.object({
  code: z.string().optional(),
  status: z.string().optional(),
  createdAt: z.string().datetime({ offset: true }).optional(),
  customer: z.object({
    id: z.string().optional(),
  }),
  name: z.string().optional(),
  claimedAt: z.string().datetime({ offset: true }).optional(),
  redeemedAt: z
    .date({ coerce: true })
    .optional()
    .transform((value) => {
      if (value?.getFullYear() === 1) {
        return null
      }
      return value
    }),
  type: z.string().optional(),
  value: z.number().optional(),
  pool: z.string().optional(),
  cfUnwrapped: z.boolean().default(false),
})

const SurpriseReward = z.object({
  title: z.string().optional(),
  id: z.string().optional(),
  type: z.literal("coupon"),
  status: z.string().optional(),
  rewardId: z.string().optional(),
  redeemLocation: z.string().optional(),
  autoApplyReward: z.boolean().default(false),
  rewardType: z.string().optional(),
  endsAt: z.string().datetime({ offset: true }).optional(),
  coupons: z.array(Coupon).optional(),
})

export const validateApiRewardSchema = z
  .object({
    data: z.array(
      z.discriminatedUnion("type", [
        z.object({
          title: z.string().optional(),
          id: z.string().optional(),
          type: z.literal("custom"),
          status: z.string().optional(),
          rewardId: z.string().optional(),
          redeemLocation: z.string().optional(),
          autoApplyReward: z.boolean().default(false),
          rewardType: z.string().optional(),
          rewardTierLevel: z.string().optional(),
        }),
        SurpriseReward,
      ])
    ),
  })
  .transform((data) => data.data)

enum TierKey {
  tier1 = MembershipLevelEnum.L1,
  tier2 = MembershipLevelEnum.L2,
  tier3 = MembershipLevelEnum.L3,
  tier4 = MembershipLevelEnum.L4,
  tier5 = MembershipLevelEnum.L5,
  tier6 = MembershipLevelEnum.L6,
  tier7 = MembershipLevelEnum.L7,
}

type Key = keyof typeof TierKey

export const validateApiTierRewardsSchema = z.record(
  z.nativeEnum(TierKey).transform((data) => {
    return TierKey[data as unknown as Key]
  }),
  z.array(
    z.object({
      title: z.string().optional(),
      id: z.string().optional(),
      type: z.string().optional(),
      status: z.string().optional(),
      rewardId: z.string().optional(),
      redeemLocation: z.string().optional(),
      autoApplyReward: z.boolean().default(false),
      rewardType: z.string().optional(),
      rewardTierLevel: z.string().optional(),
    })
  )
)

export const validateCmsRewardsSchema = z
  .object({
    data: z.object({
      all_reward: z.object({
        items: z.array(
          z.object({
            taxonomies: z.array(
              z.object({
                term_uid: z.string().optional(),
              })
            ),
            label: z.string().optional(),
            reward_id: z.string(),
            grouped_label: z.string().optional(),
            description: z.string().optional(),
            grouped_description: z.string().optional(),
            value: z.string().optional(),
          })
        ),
      }),
    }),
  })
  .transform((data) => data.data.all_reward.items)

export type ApiReward = z.output<typeof validateApiRewardSchema>[0]

export type SurpriseReward = z.output<typeof SurpriseReward>

export type CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>

export type Reward = z.output<typeof validateCmsRewardsSchema>[0]

// New endpoint related types and schemas.

const BenefitReward = z.object({
  title: z.string().optional(),
  id: z.string().optional(),
  status: z.string().optional(),
  rewardId: z.string().optional(),
  rewardType: z.string().optional(),
  rewardTierLevel: z.string().optional(),
})

const CouponState = z.enum(["claimed", "redeemed", "viewed"])
const CouponData = z.object({
  couponCode: z.string().optional(),
  unwrapped: z.boolean().default(false),
  state: CouponState,
  expiresAt: z.string().datetime({ offset: true }).optional(),
})

const CouponReward = z.object({
  title: z.string().optional(),
  id: z.string().optional(),
  rewardId: z.string().optional(),
  rewardType: z.string().optional(),
  status: z.string().optional(),
  coupon: z.array(CouponData).optional(),
})

/**
 * Schema for the new /profile/v1/Reward endpoint.
 *
 * TODO: Once we fully migrate to the new endpoint:
 * 1. Remove the data transform and use the categorized structure directly.
 * 2. Simplify surprise filtering in the query.
 */
export const validateCategorizedRewardsSchema = z
  .object({
    benefits: z.array(BenefitReward),
    coupons: z.array(CouponReward),
  })
  .transform((data) => [
    ...data.benefits.map((benefit) => ({
      ...benefit,
      type: "custom" as const, // Added for legacy compatibility.
    })),
    ...data.coupons.map((coupon) => ({
      ...coupon,
      type: "coupon" as const, // Added for legacy compatibility.
    })),
  ])

export const validateApiAllTiersSchema = z.record(
  z.nativeEnum(TierKey).transform((data) => {
    return TierKey[data as unknown as Key]
  }),
  z.array(BenefitReward)
)
