import { z } from "zod"

import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks"

import { tempImageVaultAssetSchema } from "../imageVault"
import { systemSchema } from "../system"
import { buttonSchema } from "./utils/buttonLinkSchema"
import { linkConnectionRefsSchema } from "./utils/linkConnection"
import { imageSchema } from "./image"
import { imageContainerSchema } from "./imageContainer"

import { BlocksEnums } from "@/types/enums/blocks"
import { CardsGridEnum, CardsGridLayoutEnum } from "@/types/enums/cardsGrid"
import { scriptedCardThemeEnum } from "@/types/enums/scriptedCard"

export const cardBlockSchema = z.object({
  __typename: z.literal(CardsGridEnum.cards.Card),
  // JSON - ImageVault Image
  background_image: tempImageVaultAssetSchema,
  body_text: z.string().optional().default(""),
  has_primary_button: z.boolean().default(false),
  has_secondary_button: z.boolean().default(false),
  heading: z.string().optional().default(""),
  primary_button: buttonSchema,
  scripted_top_title: z.string().optional(),
  secondary_button: buttonSchema,
  system: systemSchema,
  title: z.string().optional(),
})

export function transformCardBlock(card: typeof cardBlockSchema._type) {
  return {
    __typename: card.__typename,
    backgroundImage: card.background_image,
    body_text: card.body_text,
    heading: card.heading,
    primaryButton: card.has_primary_button ? card.primary_button : undefined,
    scripted_top_title: card.scripted_top_title,
    secondaryButton: card.has_secondary_button
      ? card.secondary_button
      : undefined,
    system: card.system,
    title: card.title,
  }
}

export const teaserCardBlockSchema = z.object({
  __typename: z.literal(CardsGridEnum.cards.TeaserCard),
  heading: z.string().default(""),
  body_text: z.string().default(""),
  image: tempImageVaultAssetSchema,
  primary_button: buttonSchema,
  secondary_button: buttonSchema,
  has_primary_button: z.boolean().default(false),
  has_secondary_button: z.boolean().default(false),
  has_sidepeek_button: z.boolean().default(false),
  sidepeek_button: z
    .object({
      call_to_action_text: z.string().optional().default(""),
    })
    .optional(),
  sidepeek_content: z
    .object({
      heading: z.string(),
      content: z.object({
        json: z.any(),
        embedded_itemsConnection: z.object({
          edges: z.array(
            z.object({
              node: z
                .discriminatedUnion("__typename", [
                  imageContainerSchema,
                  imageSchema,
                  pageLinks.accountPageSchema,
                  pageLinks.contentPageSchema,
                  pageLinks.hotelPageSchema,
                  pageLinks.loyaltyPageSchema,
                ])
                .transform((data) => {
                  const link = pageLinks.transform(data)
                  if (link) {
                    return link
                  }
                  return data
                }),
            })
          ),
        }),
      }),
      has_primary_button: z.boolean().default(false),
      primary_button: buttonSchema,
      has_secondary_button: z.boolean().default(false),
      secondary_button: buttonSchema,
    })
    .optional()
    .transform((data) => {
      if (!data) {
        return undefined
      }

      return {
        ...data,
        primary_button: data.has_primary_button
          ? data.primary_button
          : undefined,
        secondary_button: data.has_secondary_button
          ? data.secondary_button
          : undefined,
      }
    }),
  system: systemSchema,
})

export function transformTeaserCardBlock(
  card: typeof teaserCardBlockSchema._type
) {
  return {
    __typename: card.__typename,
    body_text: card.body_text,
    heading: card.heading,
    primaryButton: card.has_primary_button ? card.primary_button : undefined,
    secondaryButton: card.has_secondary_button
      ? card.secondary_button
      : undefined,
    sidePeekButton: card.has_sidepeek_button ? card.sidepeek_button : undefined,
    sidePeekContent: card.has_sidepeek_button
      ? card.sidepeek_content
      : undefined,
    image: card.image,
    system: card.system,
  }
}

const loyaltyCardBlockSchema = z.object({
  __typename: z.literal(CardsGridEnum.cards.LoyaltyCard),
  body_text: z.string().optional(),
  heading: z.string().optional().default(""),
  // JSON - ImageVault Image
  image: tempImageVaultAssetSchema,
  link: buttonSchema,
  system: systemSchema,
  title: z.string().optional(),
})

export const cardsGridSchema = z.object({
  typename: z
    .literal(BlocksEnums.block.CardsGrid)
    .optional()
    .default(BlocksEnums.block.CardsGrid),
  cards_grid: z
    .object({
      cardConnection: z.object({
        edges: z.array(
          z.object({
            node: z.discriminatedUnion("__typename", [
              cardBlockSchema,
              loyaltyCardBlockSchema,
              teaserCardBlockSchema,
            ]),
          })
        ),
      }),
      layout: z.nativeEnum(CardsGridLayoutEnum),
      preamble: z.string().optional().default(""),
      theme: z.nativeEnum(scriptedCardThemeEnum).nullable(),
      title: z.string().optional().default(""),
    })
    .transform((data) => {
      return {
        layout: data.layout,
        preamble: data.preamble,
        theme: data.theme,
        title: data.title,
        cards: data.cardConnection.edges.map((card) => {
          if (card.node.__typename === CardsGridEnum.cards.Card) {
            return transformCardBlock(card.node)
          } else if (card.node.__typename === CardsGridEnum.cards.TeaserCard) {
            return transformTeaserCardBlock(card.node)
          } else {
            return {
              __typename: card.node.__typename,
              body_text: card.node.body_text,
              heading: card.node.heading,
              image: card.node.image,
              link: card.node.link,
              system: card.node.system,
              title: card.node.title,
            }
          }
        }),
      }
    }),
})

export const cardBlockRefsSchema = z.object({
  __typename: z.literal(CardsGridEnum.cards.Card),
  primary_button: linkConnectionRefsSchema,
  secondary_button: linkConnectionRefsSchema,
  system: systemSchema,
})

export function transformCardBlockRefs(
  card:
    | typeof cardBlockRefsSchema._type
    | typeof teaserCardBlockRefsSchema._type
) {
  const cards = [card.system]
  if (card.primary_button) {
    cards.push(card.primary_button)
  }
  if (card.secondary_button) {
    cards.push(card.secondary_button)
  }
  return cards
}

const loyaltyCardBlockRefsSchema = z.object({
  __typename: z.literal(CardsGridEnum.cards.LoyaltyCard),
  link: linkConnectionRefsSchema,
  system: systemSchema,
})

export const teaserCardBlockRefsSchema = z.object({
  __typename: z.literal(CardsGridEnum.cards.TeaserCard),
  primary_button: linkConnectionRefsSchema,
  secondary_button: linkConnectionRefsSchema,
  system: systemSchema,
})

export const cardGridRefsSchema = z.object({
  cards_grid: z
    .object({
      cardConnection: z.object({
        edges: z.array(
          z.object({
            node: z.discriminatedUnion("__typename", [
              cardBlockRefsSchema,
              loyaltyCardBlockRefsSchema,
              teaserCardBlockRefsSchema,
            ]),
          })
        ),
      }),
    })
    .transform((data) => {
      return data.cardConnection.edges
        .map(({ node }) => {
          if (
            node.__typename === CardsGridEnum.cards.Card ||
            node.__typename === CardsGridEnum.cards.TeaserCard
          ) {
            return transformCardBlockRefs(node)
          } else {
            const loyaltyCards = [node.system]
            if (node.link) {
              loyaltyCards.push(node.link)
            }
            return loyaltyCards
          }
        })
        .flat()
    }),
})
