import { z } from "zod"

import {
  linkRefsUnionSchema,
  linkUnionSchema,
  transformPageLink,
} from "../pageLinks"
import { imageSchema } from "./image"

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

export const embeddedContentSchema = z.union([linkUnionSchema, imageSchema])

export const accordionItemsSchema = z.array(
  z.object({
    question: z.string(),
    answer: z.object({
      json: z.any(), // JSON
      embedded_itemsConnection: z.object({
        edges: z.array(
          z.object({
            node: embeddedContentSchema.transform((data) => {
              const link = transformPageLink(data)
              if (link) {
                return link
              }
              return data
            }),
          })
        ),
      }),
    }),
  })
)

export type Accordion = z.infer<typeof accordionSchema>

enum AccordionEnum {
  ContentPageBlocksAccordionBlockAccordionsGlobalAccordion = "ContentPageBlocksAccordionBlockAccordionsGlobalAccordion",
  ContentPageBlocksAccordionBlockAccordionsSpecificAccordion = "ContentPageBlocksAccordionBlockAccordionsSpecificAccordion",
  DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion = "DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion",
  DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion = "DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion",
  DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion = "DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion",
  DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion = "DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion",
}

export const accordionSchema = z.object({
  typename: z
    .literal(BlocksEnums.block.Accordion)
    .optional()
    .default(BlocksEnums.block.Accordion),
  accordion: z
    .object({
      title: z.string().optional().default(""),
      accordions: z.array(
        z.object({
          __typename: z.nativeEnum(AccordionEnum),
          global_accordion: z
            .object({
              global_accordionConnection: z.object({
                edges: z.array(
                  z.object({
                    node: z.object({
                      questions: accordionItemsSchema,
                    }),
                  })
                ),
              }),
            })
            .optional(),
          specific_accordion: z
            .object({
              questions: accordionItemsSchema,
            })
            .optional(),
        })
      ),
    })
    .transform((data) => {
      return {
        ...data,
        accordions: data.accordions.flatMap((acc) => {
          switch (acc.__typename) {
            case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion:
            case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion:
            case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion:
              return (
                acc.global_accordion?.global_accordionConnection.edges.flatMap(
                  ({ node: accordionConnection }) => {
                    return accordionConnection.questions
                  }
                ) || []
              )
            case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion:
            case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion:
            case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion:
              return acc.specific_accordion?.questions || []
          }
        }),
      }
    }),
})

export const globalAccordionConnectionRefs = z.object({
  edges: z.array(
    z.object({
      node: z.object({
        questions: z.array(
          z.object({
            answer: z.object({
              embedded_itemsConnection: z.object({
                edges: z.array(
                  z.object({
                    node: linkRefsUnionSchema,
                  })
                ),
              }),
            }),
          })
        ),
      }),
    })
  ),
})

export const specificAccordionConnectionRefs = z.object({
  questions: z.array(
    z.object({
      answer: z.object({
        embedded_itemsConnection: z.object({
          edges: z.array(
            z.object({
              node: linkRefsUnionSchema,
            })
          ),
        }),
      }),
    })
  ),
})

export const accordionRefsSchema = z.object({
  accordion: z
    .object({
      accordions: z.array(
        z.object({
          __typename: z.nativeEnum(AccordionEnum),
          global_accordion: z
            .object({
              global_accordionConnection: globalAccordionConnectionRefs,
            })
            .optional(),
          specific_accordion: specificAccordionConnectionRefs.optional(),
        })
      ),
    })
    .transform((data) => {
      return data.accordions.flatMap((accordion) => {
        switch (accordion.__typename) {
          case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion:
          case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion:
          case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion:
            return (
              accordion.global_accordion?.global_accordionConnection.edges.flatMap(
                ({ node: accordionConnection }) => {
                  return accordionConnection.questions.flatMap((question) =>
                    question.answer.embedded_itemsConnection.edges.flatMap(
                      ({ node }) => node.system
                    )
                  )
                }
              ) || []
            )
          case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion:
          case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion:
          case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion:
            return (
              accordion.specific_accordion?.questions.flatMap((question) =>
                question.answer.embedded_itemsConnection.edges.flatMap(
                  ({ node }) => node.system
                )
              ) || []
            )
        }
      })
    }),
})
