import { z } from "zod"

import { tempImageVaultAssetSchema } from "../imageVault"
import { systemSchema } from "../system"
import {
  infoCardBlockRefsSchema,
  infoCardBlockSchema,
  transformInfoCardBlock,
} from "./cards/infoCard"
import {
  loyaltyCardBlockRefsSchema,
  loyaltyCardBlockSchema,
} from "./cards/loyaltyCard"
import {
  teaserCardBlockRefsSchema,
  teaserCardBlockSchema,
  transformTeaserCardBlock,
} from "./cards/teaserCard"
import { buttonSchema } from "./utils/buttonLinkSchema"
import { linkConnectionRefsSchema } from "./utils/linkConnection"

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 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,
              infoCardBlockSchema,
            ]),
          })
        ),
      }),
      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 if (card.node.__typename === CardsGridEnum.cards.InfoCard) {
            return transformInfoCardBlock(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
    | typeof infoCardBlockRefsSchema._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
}

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