import { Region, Stack } from "contentstack"

import { env } from "@/env/server"
import { createCounter } from "@/server/telemetry"

import type { SyncResponse } from "@/types/sitemap"

const environment = env.CMS_ENVIRONMENT
const stack = Stack({
  api_key: env.CMS_API_KEY,
  delivery_token: env.CMS_ACCESS_TOKEN,
  branch: env.CMS_BRANCH,
  environment,
  region: Region.EU,
})

export async function contentstackSync(syncToken: string | null) {
  const entries = []
  const syncOptions = syncToken ? { sync_token: syncToken } : { init: true }

  const entriesSyncCounter = createCounter("sitemap", "entries.sync")
  const metricsEntriesSync = entriesSyncCounter.init({
    environment,
    ...syncOptions,
  })

  metricsEntriesSync.start()

  try {
    let syncResponse: SyncResponse = await stack.sync(syncOptions)

    entries.push(...syncResponse.items)

    const entriesSyncPaginationCounter = createCounter(
      "sitemap",
      "entries.sync.pagination"
    )
    const metricsEntriesSyncPagination = entriesSyncPaginationCounter.init({
      environment,
      ...syncOptions,
    })
    // Check if there is a pagination token, and fetch more data if needed
    while (syncResponse.pagination_token && !syncResponse.sync_token) {
      metricsEntriesSyncPagination.start({
        paginationToken: syncResponse.pagination_token,
      })

      syncResponse = await stack.sync({
        pagination_token: syncResponse.pagination_token,
      })

      entries.push(...syncResponse.items)

      metricsEntriesSyncPagination.success({
        paginationToken: syncResponse.pagination_token,
      })
    }

    if (syncResponse.sync_token) {
      metricsEntriesSync.success({
        newSyncToken: syncResponse.sync_token,
        entriesCount: entries.length,
      })

      return {
        syncToken: syncResponse.sync_token,
        entries,
      }
    } else {
      throw new Error("No sync token received, something went wrong")
    }
  } catch (error) {
    metricsEntriesSync.fail(error)

    throw new Error("Failed to sync entries")
  }
}
