import { z } from "zod"

import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks"

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

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: z
              .discriminatedUnion("__typename", [
                pageLinks.accountPageSchema,
                pageLinks.contentPageSchema,
                pageLinks.hotelPageSchema,
                pageLinks.loyaltyPageSchema,
              ])
              .transform((data) => {
                const link = pageLinks.transform(data)
                if (link) {
                  return link
                }
                return data
              }),
          })
        ),
      }),
    }),
  })
)

export type Accordion = z.infer<typeof accordionSchema>

enum AccordionEnum {
  ContentPageBlocksAccordionBlockAccordionsGlobalAccordion = "ContentPageBlocksAccordionBlockAccordionsGlobalAccordion",
  ContentPageBlocksAccordionBlockAccordionsSpecificAccordion = "ContentPageBlocksAccordionBlockAccordionsSpecificAccordion",
}

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.enum([
            AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion,
            AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion,
          ]),
          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:
              return (
                acc.global_accordion?.global_accordionConnection.edges.flatMap(
                  ({ node: accordionConnection }) => {
                    return accordionConnection.questions
                  }
                ) || []
              )
            case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion:
              return acc.specific_accordion?.questions || []
          }
        }),
      }
    }),
})

const actualRefs = z.discriminatedUnion("__typename", [
  pageLinks.accountPageRefSchema,
  pageLinks.contentPageRefSchema,
  pageLinks.hotelPageRefSchema,
  pageLinks.loyaltyPageRefSchema,
])

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: actualRefs,
                  })
                ),
              }),
            }),
          })
        ),
      }),
    })
  ),
})

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

export const accordionRefsSchema = z.object({
  accordion: z
    .object({
      accordions: z.array(
        z.object({
          __typename: z.enum([
            AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion,
            AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion,
          ]),
          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:
            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:
            return (
              accordion.specific_accordion?.questions.flatMap((question) =>
                question.answer.embedded_itemsConnection.edges.flatMap(
                  ({ node }) => node.system
                )
              ) || []
            )
        }
      })
    }),
})
