import { z } from "zod"

import {
  contentCardRefSchema,
  contentCardSchema,
  transformContentCard,
} from "./cards/contentCard"
import { buttonSchema } from "./utils/buttonLinkSchema"
import { linkConnectionRefsSchema } from "./utils/linkConnection"

import { BlocksEnums } from "@/types/enums/blocks"

export const cardGallerySchema = z.object({
  typename: z
    .literal(BlocksEnums.block.CardGallery)
    .optional()
    .default(BlocksEnums.block.CardGallery),
  card_gallery: z
    .object({
      heading: z.string().optional(),
      link: buttonSchema.optional(),
      card_groups: z
        .array(
          z
            .object({
              filter_identifier: z.string().nullish(),
              filter_label: z.string().nullish(),
              cardsConnection: z.object({
                edges: z.array(z.object({ node: contentCardSchema })),
              }),
            })
            .transform((group) => {
              if (!group.filter_label || !group.cardsConnection.edges.length) {
                return null
              }

              const iconIdentifier = group.filter_identifier ?? "favorite"
              const identifier = `${group.filter_label.toLowerCase()}-${iconIdentifier}`
              const cards = group.cardsConnection.edges
                .map((edge) => transformContentCard(edge.node))
                .filter(
                  (card): card is NonNullable<typeof card> => card !== null
                )
                .map((card) => ({
                  ...card,
                  filterId: identifier,
                }))
              return {
                label: group.filter_label,
                iconIdentifier,
                identifier,
                cards,
              }
            })
        )
        .transform((groups) =>
          groups.filter(
            (group): group is NonNullable<typeof group> => group !== null
          )
        ),
    })
    .transform((data) => {
      const filterCategories = data.card_groups.map((group) => ({
        identifier: group.identifier,
        iconIdentifier: group.iconIdentifier,
        label: group.label,
      }))

      return {
        heading: data.heading,
        filterCategories,
        cards: data.card_groups.map((group) => group.cards).flat(),
        defaultFilter: filterCategories[0]?.identifier,
        link:
          data.link?.href && data.link.title
            ? { href: data.link.href, text: data.link.title }
            : undefined,
      }
    }),
})

export const cardGalleryRefsSchema = z.object({
  typename: z
    .literal(BlocksEnums.block.CardGallery)
    .optional()
    .default(BlocksEnums.block.CardGallery),
  card_gallery: z.object({
    card_groups: z.array(
      z.object({
        cardsConnection: z.object({
          edges: z.array(
            z.object({
              node: contentCardRefSchema,
            })
          ),
        }),
      })
    ),
    link: linkConnectionRefsSchema.optional(),
  }),
})
