import {
  GetLoyaltyPage,
  GetLoyaltyPageRefs,
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { contentstackExtendedProcedureUID, router } from "@/server/trpc"

import {
  generateRefsResponseTag,
  generateTag,
  generateTags,
} from "@/utils/generateTag"
import { removeMultipleSlashes } from "@/utils/url"

import { removeEmptyObjects } from "../../utils"
import {
  LoyaltyPage,
  type LoyaltyPageRefsDataRaw,
  validateLoyaltyPageRefsSchema,
  validateLoyaltyPageSchema,
} from "./output"
import { getConnections } from "./utils"

import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"

function makeButtonObject(button: any) {
  return {
    openInNewTab: button.open_in_new_tab,
    title:
      button.cta_text ||
      (button.is_contentstack_link && button.linkConnection.edges.length
        ? button.linkConnection.edges[0].node.title
        : button.external_link.title),
    href:
      button.is_contentstack_link && button.linkConnection.edges.length
        ? button.linkConnection.edges[0].node.web?.original_url ||
        removeMultipleSlashes(
          `/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}`
        )
        : button.external_link.href,
    isExternal: !button.is_contentstack_link,
  }
}

export const loyaltyPageQueryRouter = router({
  get: contentstackExtendedProcedureUID.query(async ({ ctx }) => {
    const { lang, uid } = ctx

    const refsResponse = await request<LoyaltyPageRefsDataRaw>(
      GetLoyaltyPageRefs,
      {
        locale: lang,
        uid,
      },
      {
        tags: [generateRefsResponseTag(lang, uid)],
      }
    )

    if (!refsResponse.data) {
      throw notFound(refsResponse)
    }

    const cleanedData = removeEmptyObjects(refsResponse.data)

    const validatedLoyaltyPageRefs =
      validateLoyaltyPageRefsSchema.safeParse(cleanedData)
    if (!validatedLoyaltyPageRefs.success) {
      console.info(
        `Failed to validate Loyaltypage Refs - (lang: ${lang}, uid: ${uid})`
      )
      console.error(validatedLoyaltyPageRefs.error)
      return null
    }

    const connections = getConnections(validatedLoyaltyPageRefs.data)

    const tags = [
      generateTags(lang, connections),
      generateTag(lang, validatedLoyaltyPageRefs.data.loyalty_page.system.uid),
    ].flat()

    const response = await request<any>(
      GetLoyaltyPage,
      {
        locale: lang,
        uid,
      },
      { tags }
    )

    if (!response.data) {
      throw notFound(response)
    }

    const blocks = response.data.loyalty_page.blocks
      ? response.data.loyalty_page.blocks.map((block: any) => {
        switch (block.__typename) {
          case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
            return {
              ...block,
              dynamic_content: {
                ...block.dynamic_content,
                link: block.dynamic_content.link.pageConnection.edges.length
                  ? {
                    text: block.dynamic_content.link.text,
                    href: removeMultipleSlashes(
                      `/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}`
                    ),
                    title:
                      block.dynamic_content.link.pageConnection.edges[0]
                        .node.title,
                  }
                  : undefined,
              },
            }
          case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
            return {
              ...block,
              shortcuts: {
                ...block.shortcuts,
                shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({
                  text: shortcut.text,
                  openInNewTab: shortcut.open_in_new_tab,
                  ...shortcut.linkConnection.edges[0].node,
                  url:
                    shortcut.linkConnection.edges[0].node.web?.original_url ||
                    removeMultipleSlashes(
                      `/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}`
                    ),
                })),
              },
            }
          case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
            return {
              ...block,
              cards_grid: {
                ...block.cards_grid,
                cards: block.cards_grid.cardConnection.edges.map(
                  ({ node: card }: { node: any }) => {
                    return {
                      ...card,
                      primaryButton: card.has_primary_button
                        ? makeButtonObject(card.primary_button)
                        : undefined,
                      secondaryButton: card.has_secondary_button
                        ? makeButtonObject(card.secondary_button)
                        : undefined,
                    }
                  }
                ),
              },
            }
          default:
            return block
        }
      })
      : null

    const loyaltyPage = {
      heading: response.data.loyalty_page.heading,
      system: response.data.loyalty_page.system,
      blocks,
      sidebar: response.data.loyalty_page.sidebar,
    }

    const validatedLoyaltyPage =
      validateLoyaltyPageSchema.safeParse(loyaltyPage)

    if (!validatedLoyaltyPage.success) {
      console.info(
        `Failed to validate Loyaltypage Data - (lang: ${lang}, uid: ${uid})`
      )
      console.error(validatedLoyaltyPage.error)
      return null
    }

    // Assert LoyaltyPage type to get correct typings for RTE fields
    return validatedLoyaltyPage.data as LoyaltyPage
  }),
})
