import { revalidateTag } from "next/cache"
import { headers } from "next/headers"
import { z } from "zod"

import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import { badRequest, internalServerError, notFound } from "@/server/errors/next"

import { getCacheClient } from "@/services/dataCache"
import { generateHotelUrlTag } from "@/utils/generateTag"

import type { NextRequest } from "next/server"

const validateJsonBody = z.object({
  data: z.object({
    content_type: z.object({
      uid: z.literal("hotel_page"),
    }),
    entry: z.object({
      hotel_page_id: z.string(),
      locale: z.nativeEnum(Lang),
      publish_details: z.object({ locale: z.nativeEnum(Lang) }).optional(),
    }),
  }),
})

export async function POST(request: NextRequest) {
  try {
    const headersList = await headers()
    const secret = headersList.get("x-revalidate-secret")

    if (secret !== env.REVALIDATE_SECRET) {
      console.error(`Invalid Secret`)
      console.error({ secret })
      return badRequest({ revalidated: false, now: Date.now() })
    }

    const data = await request.json()
    const validatedData = validateJsonBody.safeParse(data)
    if (!validatedData.success) {
      console.error("Bad validation for `validatedData` in hotel revalidation")
      console.error(validatedData.error)
      return internalServerError({ revalidated: false, now: Date.now() })
    }

    const {
      data: {
        data: { content_type, entry },
      },
    } = validatedData

    // The publish_details.locale is the locale that the entry is published in, regardless if it is "localized" or not
    const locale = entry.publish_details?.locale ?? entry.locale

    let tag = ""
    if (content_type.uid === "hotel_page") {
      tag = generateHotelUrlTag(locale, entry.hotel_page_id)
    } else {
      console.error(
        `Invalid content_type, received ${content_type.uid}, expected "hotel_page"`
      )
      return notFound({ revalidated: false, now: Date.now() })
    }

    console.info(`Revalidating hotel url tag: ${tag}`)
    revalidateTag(tag)
    const cacheClient = await getCacheClient()
    await cacheClient.deleteKey(tag, { fuzzy: true })

    return Response.json({ revalidated: true, now: Date.now() })
  } catch (error) {
    console.error("Failed to revalidate tag(s) for hotel")
    console.error(error)
    return internalServerError({ revalidated: false, now: Date.now() })
  }
}
