import { Lang } from "@/constants/languages"
import { baseUrls } from "@/constants/routes/baseUrls"
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
  GetDaDeEnUrlsAccountPage,
  GetFiNoSvUrlsAccountPage,
} from "@/lib/graphql/Query/AccountPage.graphql"
import {
  GetDaDeEnUrlsCurrentBlocksPage,
  GetFiNoSvUrlsCurrentBlocksPage,
} from "@/lib/graphql/Query/LanguageSwitcherCurrent.graphql"
import {
  GetDaDeEnUrlsLoyaltyPage,
  GetFiNoSvUrlsLoyaltyPage,
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
import { internalServerError } from "@/server/errors/trpc"
import { publicProcedure, router } from "@/server/trpc"

import { generateTag } from "@/utils/generateTag"

import { validateLanguageSwitcherData } from "./output"
import { languageSwitcherAffix } from "./utils"

import type {
  LanguageSwitcherData,
  LanguageSwitcherQueryDataRaw,
} from "@/types/requests/languageSwitcher"
import { PageTypeEnum } from "@/types/requests/pageType"

interface LanguageSwitcherVariables {
  contentType: string
  uid: string
}

async function getLanguageSwitcher(options: LanguageSwitcherVariables) {
  const variables = { uid: options.uid }
  const tagsDaDeEn = [
    generateTag(Lang.da, options.uid, languageSwitcherAffix),
    generateTag(Lang.de, options.uid, languageSwitcherAffix),
    generateTag(Lang.en, options.uid, languageSwitcherAffix),
  ]
  const tagsFiNoSv = [
    generateTag(Lang.fi, options.uid, languageSwitcherAffix),
    generateTag(Lang.no, options.uid, languageSwitcherAffix),
    generateTag(Lang.sv, options.uid, languageSwitcherAffix),
  ]
  switch (options.contentType) {
    case PageTypeEnum.accountPage:
      return await batchRequest<LanguageSwitcherQueryDataRaw>([
        {
          document: GetDaDeEnUrlsAccountPage,
          variables,
          tags: tagsDaDeEn,
        },
        {
          document: GetFiNoSvUrlsAccountPage,
          variables,
          tags: tagsFiNoSv,
        },
      ])
    case PageTypeEnum.currentBlocksPage:
      return await batchRequest<LanguageSwitcherQueryDataRaw>([
        {
          document: GetDaDeEnUrlsCurrentBlocksPage,
          variables,
          tags: tagsDaDeEn,
        },
        {
          document: GetFiNoSvUrlsCurrentBlocksPage,
          variables,
          tags: tagsFiNoSv,
        },
      ])
    case PageTypeEnum.loyaltyPage:
      return await batchRequest<LanguageSwitcherQueryDataRaw>([
        {
          document: GetDaDeEnUrlsLoyaltyPage,
          variables,
          tags: tagsDaDeEn,
        },
        {
          document: GetFiNoSvUrlsLoyaltyPage,
          variables,
          tags: tagsFiNoSv,
        },
      ])
    default:
      console.info(`type: [${options.contentType}]`)
      console.error(`Trying to get a content type that is not supported`)
      throw internalServerError()
  }
}

export const languageSwitcherQueryRouter = router({
  get: publicProcedure.query(async ({ ctx }) => {
    if (!ctx.uid || !ctx.lang) {
      return { lang: ctx.lang, urls: baseUrls }
    }
    const res = await getLanguageSwitcher({
      contentType: ctx.contentType!,
      uid: ctx.uid,
    })
    const urls = Object.keys(res.data).reduce<LanguageSwitcherData>(
      (acc, key) => {
        const item = res.data[key as Lang]?.items[0]
        const url = item
          ? item.web?.original_url || `/${key}${item.url}`
          : undefined

        return {
          ...acc,
          [key]: { url, isExternal: !!item?.web?.original_url },
        }
      },
      {} as LanguageSwitcherData
    )

    const validatedLanguageSwitcherData =
      validateLanguageSwitcherData.safeParse(urls)

    if (!validatedLanguageSwitcherData.success) {
      console.info(
        `Failed to validate Language Switcher Data - (contentType: ${ctx.contentType}, lang: ${ctx.lang}, uid: ${ctx.uid})`
      )
      console.error(validatedLanguageSwitcherData.error)
      return null
    }

    return {
      lang: ctx.lang,
      urls,
    }
  }),
})
