import { GetCollectionPageRefs } from "@/lib/graphql/Query/CollectionPage/CollectionPage.graphql"
import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { createCounter } from "@/server/telemetry"

import {
  generateRefsResponseTag,
  generateTag,
  generateTagsFromSystem,
} from "@/utils/generateTag"

import { collectionPageRefsSchema } from "./output"

import { CollectionPageEnum } from "@/types/enums/collectionPage"
import type { System } from "@/types/requests/system"
import type {
  CollectionPageRefs,
  GetCollectionPageRefsSchema,
} from "@/types/trpc/routers/contentstack/collectionPage"
import type { Lang } from "@/constants/languages"

export async function fetchCollectionPageRefs(lang: Lang, uid: string) {
  const getCollectionPageRefsCounter = createCounter(
    "trpc.contentstack",
    "collectionPage.get.refs"
  )
  const metricsGetCollectionPageRefs = getCollectionPageRefsCounter.init({
    lang,
    uid,
  })

  metricsGetCollectionPageRefs.start()

  const cacheKey = generateRefsResponseTag(lang, uid)

  const refsResponse = await request<GetCollectionPageRefsSchema>(
    GetCollectionPageRefs,
    {
      locale: lang,
      uid,
    },
    {
      key: cacheKey,
      ttl: "max",
    }
  )

  if (!refsResponse.data) {
    const notFoundError = notFound(refsResponse)
    metricsGetCollectionPageRefs.noDataError()
    throw notFoundError
  }

  return refsResponse.data
}

export function validateCollectionPageRefs(
  data: GetCollectionPageRefsSchema,
  lang: Lang,
  uid: string
) {
  const getCollectionPageRefsCounter = createCounter(
    "trpc.contentstack",
    "collectionPage.get.refs"
  )
  const metricsGetCollectionPageRefs = getCollectionPageRefsCounter.init({
    lang,
    uid,
  })

  const validatedData = collectionPageRefsSchema.safeParse(data)
  if (!validatedData.success) {
    metricsGetCollectionPageRefs.validationError(validatedData.error)
    return null
  }

  metricsGetCollectionPageRefs.success()

  return validatedData.data
}

export function generatePageTags(
  validatedData: CollectionPageRefs,
  lang: Lang
): string[] {
  const connections = getConnections(validatedData)
  return [
    generateTagsFromSystem(lang, connections),
    generateTag(lang, validatedData.collection_page.system.uid),
  ].flat()
}

export function getConnections({ collection_page }: CollectionPageRefs) {
  const connections: System["system"][] = [collection_page.system]
  if (collection_page.blocks) {
    collection_page.blocks.forEach((block) => {
      switch (block.__typename) {
        case CollectionPageEnum.ContentStack.blocks.Shortcuts: {
          if (block.shortcuts.shortcuts.length) {
            connections.push(...block.shortcuts.shortcuts)
          }
          break
        }
        case CollectionPageEnum.ContentStack.blocks.CardsGrid: {
          if (block.cards_grid.length) {
            connections.push(...block.cards_grid)
          }
          break
        }
        case CollectionPageEnum.ContentStack.blocks.UspGrid: {
          if (block.usp_grid.length) {
            connections.push(...block.usp_grid)
          }
        }
      }
    })
  }

  return connections
}
