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 { badRequest, internalServerError, notFound } from "@/server/errors/next"

import { generateLoyaltyConfigTag } from "@/utils/generateTag"

enum LoyaltyConfigContentTypes {
  loyalty_level = "loyalty_level",
  reward = "reward",
}

const validateJsonBody = z.object({
  data: z.object({
    content_type: z.object({
      uid: z.nativeEnum(LoyaltyConfigContentTypes),
    }),
    entry: z.object({
      reward_id: z.string().optional(),
      level_id: z.string().optional(),
      locale: z.nativeEnum(Lang),
    }),
  }),
})

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 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 loyaltyConfig revalidation"
      )
      console.error(validatedData.error)
      return internalServerError({ revalidated: false, now: Date.now() })
    }

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

    let tag = ""
    if (
      content_type.uid === LoyaltyConfigContentTypes.loyalty_level &&
      entry.level_id
    ) {
      tag = generateLoyaltyConfigTag(
        entry.locale,
        content_type.uid,
        entry.level_id
      )
    } else if (
      content_type.uid === LoyaltyConfigContentTypes.reward &&
      entry.reward_id
    ) {
      tag = generateLoyaltyConfigTag(
        entry.locale,
        content_type.uid,
        entry.reward_id
      )
    } else {
      console.error("Invalid content_type")
      return notFound({ revalidated: false, now: Date.now() })
    }

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

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