import { Lang } from "@/constants/languages"
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
  GetDaDeEnUrlsAccountPage,
  GetFiNoSvUrlsAccountPage,
} from "@/lib/graphql/Query/AccountPage/AccountPage.graphql"
import {
  GetDaDeEnUrlsCollectionPage,
  GetFiNoSvUrlsCollectionPage,
} from "@/lib/graphql/Query/CollectionPage/CollectionPage.graphql"
import {
  GetDaDeEnUrlsContentPage,
  GetFiNoSvUrlsContentPage,
} from "@/lib/graphql/Query/ContentPage/ContentPage.graphql"
import {
  GetDaDeEnUrlsCurrentBlocksPage,
  GetFiNoSvUrlsCurrentBlocksPage,
} from "@/lib/graphql/Query/Current/LanguageSwitcher.graphql"
import {
  GetDaDeEnUrlsDestinationCityPage,
  GetFiNoSvUrlsDestinationCityPage,
} from "@/lib/graphql/Query/DestinationCityPage/DestinationCityPage.graphql"
import {
  GetDaDeEnUrlsDestinationCountryPage,
  GetFiNoSvUrlsDestinationCountryPage,
} from "@/lib/graphql/Query/DestinationCountryPage/DestinationCountryPage.graphql"
import {
  GetDaDeEnUrlsDestinationOverviewPage,
  GetFiNoSvUrlsDestinationOverviewPage,
} from "@/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql"
import {
  GetDaDeEnUrlsHotelPage,
  GetFiNoSvUrlsHotelPage,
} from "@/lib/graphql/Query/HotelPage/HotelPage.graphql"
import {
  GetDaDeEnUrlsLoyaltyPage,
  GetFiNoSvUrlsLoyaltyPage,
} from "@/lib/graphql/Query/LoyaltyPage/LoyaltyPage.graphql"
import {
  GetDaDeEnUrlsStartPage,
  GetFiNoSvUrlsStartPage,
} from "@/lib/graphql/Query/StartPage/StartPage.graphql"
import { internalServerError } from "@/server/errors/trpc"
import { createCounter } from "@/server/telemetry"

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

import { validateLanguageSwitcherData } from "./output"

import { PageContentTypeEnum } from "@/types/requests/contentType"
import type {
  LanguageSwitcherData,
  LanguageSwitcherQueryDataRaw,
} from "@/types/requests/languageSwitcher"

export const languageSwitcherAffix = "languageSwitcher"

export async function getUrlsOfAllLanguages(
  lang: Lang,
  uid: string,
  contentType: string
) {
  const getLanguageSwitcherCounter = createCounter(
    "trpc.contentstack",
    "languageSwitcher.get"
  )
  const metricsGetLanguageSwitcher = getLanguageSwitcherCounter.init({
    lang,
    uid,
    contentType,
  })

  metricsGetLanguageSwitcher.start()

  const variables = { uid }
  const tagsDaDeEn = [
    generateTag(Lang.da, uid, languageSwitcherAffix),
    generateTag(Lang.de, uid, languageSwitcherAffix),
    generateTag(Lang.en, uid, languageSwitcherAffix),
  ]
  const tagsFiNoSv = [
    generateTag(Lang.fi, uid, languageSwitcherAffix),
    generateTag(Lang.no, uid, languageSwitcherAffix),
    generateTag(Lang.sv, uid, languageSwitcherAffix),
  ]
  let daDeEnDocument = null
  let fiNoSvDocument = null
  switch (contentType) {
    case PageContentTypeEnum.accountPage:
      daDeEnDocument = GetDaDeEnUrlsAccountPage
      fiNoSvDocument = GetFiNoSvUrlsAccountPage
      break
    case PageContentTypeEnum.currentBlocksPage:
      daDeEnDocument = GetDaDeEnUrlsCurrentBlocksPage
      fiNoSvDocument = GetFiNoSvUrlsCurrentBlocksPage
      break
    case PageContentTypeEnum.loyaltyPage:
      daDeEnDocument = GetDaDeEnUrlsLoyaltyPage
      fiNoSvDocument = GetFiNoSvUrlsLoyaltyPage
      break
    case PageContentTypeEnum.hotelPage:
      daDeEnDocument = GetDaDeEnUrlsHotelPage
      fiNoSvDocument = GetFiNoSvUrlsHotelPage
      break
    case PageContentTypeEnum.contentPage:
      daDeEnDocument = GetDaDeEnUrlsContentPage
      fiNoSvDocument = GetFiNoSvUrlsContentPage
      break
    case PageContentTypeEnum.collectionPage:
      daDeEnDocument = GetDaDeEnUrlsCollectionPage
      fiNoSvDocument = GetFiNoSvUrlsCollectionPage
      break
    case PageContentTypeEnum.destinationOverviewPage:
      daDeEnDocument = GetDaDeEnUrlsDestinationOverviewPage
      fiNoSvDocument = GetFiNoSvUrlsDestinationOverviewPage
      break
    case PageContentTypeEnum.destinationCountryPage:
      daDeEnDocument = GetDaDeEnUrlsDestinationCountryPage
      fiNoSvDocument = GetFiNoSvUrlsDestinationCountryPage
      break
    case PageContentTypeEnum.destinationCityPage:
      daDeEnDocument = GetDaDeEnUrlsDestinationCityPage
      fiNoSvDocument = GetFiNoSvUrlsDestinationCityPage
      break
    case PageContentTypeEnum.startPage:
      daDeEnDocument = GetDaDeEnUrlsStartPage
      fiNoSvDocument = GetFiNoSvUrlsStartPage
      break
    default:
      console.error(`type: [${contentType}]`)
      console.error(`Trying to get a content type that is not supported`)
      throw internalServerError()
  }

  if (!daDeEnDocument || !fiNoSvDocument) {
    throw internalServerError()
  }

  const response = await batchRequest<LanguageSwitcherQueryDataRaw>([
    {
      document: daDeEnDocument,
      variables,
      cacheOptions: {
        ttl: "max",
        key: tagsDaDeEn,
      },
    },
    {
      document: fiNoSvDocument,
      variables,
      cacheOptions: {
        ttl: "max",
        key: tagsFiNoSv,
      },
    },
  ])

  const urls = Object.keys(response.data).reduce<LanguageSwitcherData>(
    (acc, key) => {
      const item = response.data[key as Lang]

      const url = item
        ? item.web?.original_url || removeTrailingSlash(`/${key}${item.url}`)
        : undefined

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

  const validatedLanguageSwitcherData =
    validateLanguageSwitcherData.safeParse(urls)

  if (!validatedLanguageSwitcherData.success) {
    metricsGetLanguageSwitcher.validationError(
      validatedLanguageSwitcherData.error
    )
    return null
  }

  metricsGetLanguageSwitcher.success()

  return urls
}
