import { z } from "zod"

import { discriminatedUnionArray } from "@/lib/discriminatedUnion"

import {
  accordionRefsSchema,
  accordionSchema,
} from "../schemas/blocks/accordion"
import {
  cardGridRefsSchema,
  cardsGridSchema,
} from "../schemas/blocks/cardsGrid"
import {
  contentRefsSchema as blockContentRefsSchema,
  contentSchema as blockContentSchema,
} from "../schemas/blocks/content"
import {
  dynamicContentRefsSchema,
  dynamicContentSchema as blockDynamicContentSchema,
} from "../schemas/blocks/dynamicContent"
import { hotelListingSchema } from "../schemas/blocks/hotelListing"
import {
  shortcutsRefsSchema,
  shortcutsSchema,
} from "../schemas/blocks/shortcuts"
import { tableSchema } from "../schemas/blocks/table"
import { textColsRefsSchema, textColsSchema } from "../schemas/blocks/textCols"
import { uspGridRefsSchema, uspGridSchema } from "../schemas/blocks/uspGrid"
import {
  dynamicContentRefsSchema as headerDynamicContentRefsSchema,
  dynamicContentSchema as headerDynamicContentSchema,
} from "../schemas/headers/dynamicContent"
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
import {
  linkAndTitleSchema,
  linkConnectionRefs,
} from "../schemas/linkConnection"
import {
  contentRefsSchema as sidebarContentRefsSchema,
  contentSchema as sidebarContentSchema,
} from "../schemas/sidebar/content"
import { dynamicContentSchema as sidebarDynamicContentSchema } from "../schemas/sidebar/dynamicContent"
import {
  joinLoyaltyContactRefsSchema,
  joinLoyaltyContactSchema,
} from "../schemas/sidebar/joinLoyaltyContact"
import {
  quickLinksRefschema,
  quickLinksSchema,
} from "../schemas/sidebar/quickLinks"
import {
  scriptedCardRefschema,
  scriptedCardsSchema,
} from "../schemas/sidebar/scriptedCard"
import {
  teaserCardRefschema,
  teaserCardsSchema,
} from "../schemas/sidebar/teaserCard"
import { systemSchema } from "../schemas/system"

import { ContentPageEnum } from "@/types/enums/contentPage"

// Block schemas
export const contentPageCards = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.CardsGrid),
  })
  .merge(cardsGridSchema)

export const contentPageContent = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Content),
  })
  .merge(blockContentSchema)

export const contentPageDynamicContent = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.DynamicContent),
  })
  .merge(blockDynamicContentSchema)

export const contentPageShortcuts = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Shortcuts),
  })
  .merge(shortcutsSchema)

export const contentPageTextCols = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.TextCols),
  })
  .merge(textColsSchema)

export const contentPageUspGrid = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.UspGrid),
  })
  .merge(uspGridSchema)

export const contentPageTable = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Table),
  })
  .merge(tableSchema)

export const contentPageAccordion = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Accordion),
  })
  .merge(accordionSchema)

export const contentPageHotelListing = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.HotelListing),
  })
  .merge(hotelListingSchema)

export const blocksSchema = z.discriminatedUnion("__typename", [
  contentPageAccordion,
  contentPageCards,
  contentPageContent,
  contentPageDynamicContent,
  contentPageShortcuts,
  contentPageTable,
  contentPageTextCols,
  contentPageUspGrid,
  contentPageHotelListing,
])

export const contentPageSidebarContent = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.Content),
  })
  .merge(sidebarContentSchema)

export const contentPageSidebarDynamicContent = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.DynamicContent),
  })
  .merge(sidebarDynamicContentSchema)

export const contentPageJoinLoyaltyContact = z
  .object({
    __typename: z.literal(
      ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact
    ),
  })
  .merge(joinLoyaltyContactSchema)

export const contentPageSidebarScriptedCard = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.ScriptedCard),
  })
  .merge(scriptedCardsSchema)

export const contentPageSidebarTeaserCard = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.TeaserCard),
  })
  .merge(teaserCardsSchema)

export const contentPageSidebarQuicklinks = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.QuickLinks),
  })
  .merge(quickLinksSchema)

export const sidebarSchema = z.discriminatedUnion("__typename", [
  contentPageSidebarContent,
  contentPageSidebarDynamicContent,
  contentPageJoinLoyaltyContact,
  contentPageSidebarScriptedCard,
  contentPageSidebarTeaserCard,
  contentPageSidebarQuicklinks,
])

const navigationLinksSchema = z
  .array(linkAndTitleSchema)
  .nullable()
  .transform((data) => {
    if (!data) {
      return null
    }

    return data
      .filter((item) => !!item.link)
      .map((item) => ({
        url: item.link!.url,
        title: item.title || item.link!.title,
      }))
  })

const topPrimaryButtonSchema = linkAndTitleSchema
  .nullable()
  .transform((data) => {
    if (!data?.link) {
      return null
    }
    return {
      url: data.link.url,
      title: data.title || data.link.title || null,
    }
  })

// Content Page Schema and types
export const contentPageSchema = z.object({
  content_page: z.object({
    hero_image: tempImageVaultAssetSchema,
    blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
    sidebar: discriminatedUnionArray(sidebarSchema.options).nullable(),
    title: z.string(),
    header: z.object({
      heading: z.string(),
      preamble: z.string(),
      top_primary_button: topPrimaryButtonSchema,
      navigation_links: navigationLinksSchema,
      dynamic_content: headerDynamicContentSchema.nullish(),
    }),
    meeting_package: z
      .object({
        show_widget: z.boolean(),
        location: z.string(),
      })
      .nullable(),
    system: systemSchema.merge(
      z.object({
        created_at: z.string(),
        updated_at: z.string(),
      })
    ),
  }),
  trackingProps: z.object({
    url: z.string(),
  }),
})

/** REFS */
const contentPageCardsRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.CardsGrid),
  })
  .merge(cardGridRefsSchema)

const contentPageBlockContentRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Content),
  })
  .merge(blockContentRefsSchema)

const contentPageDynamicContentRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.DynamicContent),
  })
  .merge(dynamicContentRefsSchema)

const contentPageShortcutsRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Shortcuts),
  })
  .merge(shortcutsRefsSchema)

const contentPageTextColsRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.TextCols),
  })
  .merge(textColsRefsSchema)

const contentPageUspGridRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.UspGrid),
  })
  .merge(uspGridRefsSchema)

const contentPageAccordionRefs = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.blocks.Accordion),
  })
  .merge(accordionRefsSchema)

const contentPageBlockRefsItem = z.discriminatedUnion("__typename", [
  contentPageAccordionRefs,
  contentPageBlockContentRefs,
  contentPageShortcutsRefs,
  contentPageCardsRefs,
  contentPageDynamicContentRefs,
  contentPageTextColsRefs,
  contentPageUspGridRefs,
])

const contentPageSidebarContentRef = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.Content),
  })
  .merge(sidebarContentRefsSchema)

const contentPageSidebarJoinLoyaltyContactRef = z
  .object({
    __typename: z.literal(
      ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact
    ),
  })
  .merge(joinLoyaltyContactRefsSchema)

const contentPageSidebarScriptedCardRef = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.ScriptedCard),
  })
  .merge(scriptedCardRefschema)

const contentPageSidebarTeaserCardRef = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.TeaserCard),
  })
  .merge(teaserCardRefschema)

const contentPageSidebarQuickLinksRef = z
  .object({
    __typename: z.literal(ContentPageEnum.ContentStack.sidebar.QuickLinks),
  })
  .merge(quickLinksRefschema)

const contentPageSidebarRefsItem = z.discriminatedUnion("__typename", [
  contentPageSidebarContentRef,
  contentPageSidebarJoinLoyaltyContactRef,
  contentPageSidebarScriptedCardRef,
  contentPageSidebarTeaserCardRef,
  contentPageSidebarQuickLinksRef,
])

const contentPageHeaderRefs = z.object({
  navigation_links: z.array(linkConnectionRefs),
  top_primary_button: linkConnectionRefs.nullable(),
  dynamic_content: headerDynamicContentRefsSchema.nullish(),
})

export const contentPageRefsSchema = z.object({
  content_page: z.object({
    header: contentPageHeaderRefs,
    blocks: discriminatedUnionArray(
      contentPageBlockRefsItem.options
    ).nullable(),
    sidebar: discriminatedUnionArray(
      contentPageSidebarRefsItem.options
    ).nullable(),
    system: systemSchema,
  }),
})
