import { z } from "zod"

import { removeMultipleSlashes } from "@/utils/url"

import { systemSchema } from "./system"

import { ContentEnum } from "@/types/enums/content"

export const pageLinkSchema = z.object({
  system: systemSchema,
  title: z.string().optional().default(""),
  url: z.string().optional().default(""),
})

export const accountPageSchema = z
  .object({
    __typename: z.literal(ContentEnum.blocks.AccountPage),
  })
  .merge(pageLinkSchema)

export const accountPageRefSchema = z.object({
  __typename: z.literal(ContentEnum.blocks.AccountPage),
  system: systemSchema,
})

export const extendedPageLinkSchema = pageLinkSchema.merge(
  z.object({
    web: z.object({
      original_url: z.string().optional().default(""),
    }),
  })
)
export const collectionPageSchema = z
  .object({
    __typename: z.literal(ContentEnum.blocks.CollectionPage),
  })
  .merge(extendedPageLinkSchema)

export const collectionPageRefSchema = z.object({
  __typename: z.literal(ContentEnum.blocks.CollectionPage),
  system: systemSchema,
})

export const contentPageSchema = z
  .object({
    __typename: z.literal(ContentEnum.blocks.ContentPage),
  })
  .merge(extendedPageLinkSchema)

export const contentPageRefSchema = z.object({
  __typename: z.literal(ContentEnum.blocks.ContentPage),
  system: systemSchema,
})

export const hotelPageSchema = z
  .object({
    __typename: z.literal(ContentEnum.blocks.HotelPage),
  })
  .merge(pageLinkSchema)

export const hotelPageRefSchema = z.object({
  __typename: z.literal(ContentEnum.blocks.HotelPage),
  system: systemSchema,
})

export const loyaltyPageSchema = z
  .object({
    __typename: z.literal(ContentEnum.blocks.LoyaltyPage),
  })
  .merge(extendedPageLinkSchema)

export const loyaltyPageRefSchema = z.object({
  __typename: z.literal(ContentEnum.blocks.LoyaltyPage),
  system: systemSchema,
})

type Data =
  | z.output<typeof accountPageSchema>
  | z.output<typeof contentPageSchema>
  | z.output<typeof collectionPageSchema>
  | z.output<typeof hotelPageSchema>
  | z.output<typeof loyaltyPageSchema>
  | Object

export function transform(data: Data) {
  if (data && "__typename" in data) {
    switch (data.__typename) {
      case ContentEnum.blocks.AccountPage:
      case ContentEnum.blocks.HotelPage:
        return {
          __typename: data.__typename,
          system: data.system,
          title: data.title,
          url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`),
        }
      case ContentEnum.blocks.ContentPage:
      case ContentEnum.blocks.CollectionPage:
      case ContentEnum.blocks.LoyaltyPage:
        // TODO: Once all links use this transform
        // `web` can be removed and not to be worried
        // about throughout the application
        return {
          __typename: data.__typename,
          system: data.system,
          title: data.title,
          url: data.web.original_url
            ? data.web.original_url
            : removeMultipleSlashes(`/${data.system.locale}/${data.url}`),
          web: data.web,
        }
    }
  }
}

type RefData =
  | z.output<typeof accountPageRefSchema>
  | z.output<typeof collectionPageRefSchema>
  | z.output<typeof contentPageRefSchema>
  | z.output<typeof hotelPageRefSchema>
  | z.output<typeof loyaltyPageRefSchema>
  | Object

export function transformRef(data: RefData) {
  if (data && "__typename" in data) {
    switch (data.__typename) {
      case ContentEnum.blocks.AccountPage:
      case ContentEnum.blocks.ContentPage:
      case ContentEnum.blocks.CollectionPage:
      case ContentEnum.blocks.HotelPage:
      case ContentEnum.blocks.LoyaltyPage:
        return data.system
    }
  }
}
