import { z } from "zod"

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

import {
  cardGridRefsSchema,
  cardsGridSchema,
} from "../schemas/blocks/cardsGrid"
import {
  dynamicContentRefsSchema,
  dynamicContentSchema as blockDynamicContentSchema,
} from "../schemas/blocks/dynamicContent"
import {
  shortcutsRefsSchema,
  shortcutsSchema,
} from "../schemas/blocks/shortcuts"
import { uspGridRefsSchema, uspGridSchema } from "../schemas/blocks/uspGrid"
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
import {
  linkAndTitleSchema,
  linkConnectionRefs,
} from "../schemas/linkConnection"
import { systemSchema } from "../schemas/system"

import { CollectionPageEnum } from "@/types/enums/collectionPage"

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

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

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

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

export const blocksSchema = z.discriminatedUnion("__typename", [
  collectionPageCards,
  collectionPageDynamicContent,
  collectionPageShortcuts,
  collectionPageUspGrid,
])

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 collectionPageSchema = z.object({
  collection_page: z.object({
    hero_image: tempImageVaultAssetSchema,
    blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
    title: z.string(),
    header: z.object({
      heading: z.string(),
      preamble: z.string(),
      top_primary_button: topPrimaryButtonSchema,
      navigation_links: navigationLinksSchema,
    }),
    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 collectionPageCardsRefs = z
  .object({
    __typename: z.literal(CollectionPageEnum.ContentStack.blocks.CardsGrid),
  })
  .merge(cardGridRefsSchema)

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

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

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

const collectionPageBlockRefsItem = z.discriminatedUnion("__typename", [
  collectionPageShortcutsRefs,
  contentPageDynamicContentRefs,
  collectionPageCardsRefs,
  collectionPageUspGridRefs,
])

const collectionPageHeaderRefs = z.object({
  navigation_links: z.array(linkConnectionRefs),
  top_primary_button: linkConnectionRefs.nullable(),
})

export const collectionPageRefsSchema = z.object({
  collection_page: z.object({
    header: collectionPageHeaderRefs,
    blocks: discriminatedUnionArray(
      collectionPageBlockRefsItem.options
    ).nullable(),
    system: systemSchema,
  }),
})
