import { createCounter } from "@/server/telemetry"
import { publicProcedure, router } from "@/server/trpc"

import { getCacheClient } from "@/services/dataCache"

import { jobylonFeedSchema } from "./output"

export const TWENTYFOUR_HOURS = 60 * 60 * 24

// The URL for the Jobylon feed including the hash for the specific feed.
// The URL and hash are generated by Jobylon. Documentation: https://developer.jobylon.com/feed-api
const feedUrl =
  "https://feed.jobylon.com/feeds/cc04ba19-f0bd-4412-8b9b-d1d1fcbf0800"

export const jobylonQueryRouter = router({
  feed: router({
    get: publicProcedure.query(async function () {
      const jobylonFeedGetCounter = createCounter("trpc.jobylon.feed", "get")
      const metricsJobylonFeedGet = jobylonFeedGetCounter.init()

      metricsJobylonFeedGet.start()

      const url = new URL(feedUrl)
      url.search = new URLSearchParams({
        format: "json",
      }).toString()

      const cacheClient = await getCacheClient()

      const result = cacheClient.cacheOrGet(
        "jobylon:feed",
        async () => {
          const response = await fetch(url, {
            cache: "no-cache",
          })

          if (!response.ok) {
            await metricsJobylonFeedGet.httpError(response)
            const text = await response.text()
            throw new Error(
              `Failed to fetch Jobylon feed: ${JSON.stringify({
                status: response.status,
                statusText: response.statusText,
                text,
              })}`
            )
          }

          const responseJson = await response.json()
          const validatedResponse = jobylonFeedSchema.safeParse(responseJson)

          if (!validatedResponse.success) {
            metricsJobylonFeedGet.validationError(validatedResponse.error)
            throw new Error(
              `Failed to parse Jobylon feed: ${JSON.stringify(validatedResponse.error)}`
            )
          }

          return validatedResponse.data
        },
        "1d"
      )

      metricsJobylonFeedGet.success()

      return result
    }),
  }),
})
