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

import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import { internalServerError } from "@/server/errors/next"
import { affix as breadcrumbsAffix } from "@/server/routers/contentstack/breadcrumbs/utils"

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

const validateJsonBody = z.object({
  data: z.object({
    content_type: z.object({
      uid: z.string(),
    }),
    entry: z.object({
      breadcrumbs: z
        .object({
          title: z.string(),
        })
        .optional(),
      locale: z.nativeEnum(Lang),
      uid: z.string(),
      url: z.string().optional(),
    }),
  }),
})

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

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

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

    const {
      data: {
        data: { content_type, entry },
      },
    } = validatedData
    const refsTag = generateRefsResponseTag(entry.locale, entry.uid)
    const refTag = generateRefTag(entry.locale, content_type.uid, entry.uid)
    const tag = generateTag(entry.locale, entry.uid)

    console.info(`Revalidating refsTag: ${refsTag}`)
    revalidateTag(refsTag)

    console.info(`Revalidating refTag: ${refTag}`)
    revalidateTag(refTag)

    console.info(`Revalidating tag: ${tag}`)
    revalidateTag(tag)

    if (entry.breadcrumbs) {
      const breadcrumbsRefsTag = generateRefsResponseTag(
        entry.locale,
        entry.uid,
        breadcrumbsAffix
      )
      const breadcrumbsTag = generateTag(
        entry.locale,
        entry.uid,
        breadcrumbsAffix
      )

      console.info(`Revalidating breadcrumbsRefsTag: ${breadcrumbsRefsTag}`)
      revalidateTag(breadcrumbsRefsTag)

      console.info(`Revalidating breadcrumbsTag: ${breadcrumbsTag}`)
      revalidateTag(breadcrumbsTag)
    }

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