import { revalidateTag } from "next/cache";
import type { NextRequest } from "next/server";

const SECRET = process.env.REVALIDATION_SECRET || "";
const RATE_LIMIT_WINDOW = 60_000;
const RATE_LIMIT_MAX = 10;
const TIMESTAMP_TTL = 5 * 60_000;

const rateMap = new Map<string, { count: number; resetAt: number }>();
const seenTimestamps = new Set<number>();

setInterval(() => {
  const now = Date.now();
  for (const [key, val] of rateMap) {
    if (val.resetAt < now) rateMap.delete(key);
  }
}, RATE_LIMIT_WINDOW);

function checkRateLimit(ip: string): boolean {
  const now = Date.now();
  const entry = rateMap.get(ip);
  if (!entry || entry.resetAt < now) {
    rateMap.set(ip, { count: 1, resetAt: now + RATE_LIMIT_WINDOW });
    return true;
  }
  entry.count++;
  return entry.count <= RATE_LIMIT_MAX;
}

interface RevalidateBody {
  secret?: string;
  timestamp?: number;
  type?: string;
  slug?: string;
  uri?: string;
}

const TAG_MAP: Record<string, (body: RevalidateBody) => string[]> = {
  home: () => ["home"],
  menu: () => ["menu"],
  posts: () => ["posts"],
  pages: () => ["pages"],
  products: () => ["products"],
  post: (b) => [`post:${b.slug || ""}`],
  page: (b) => [`page:${b.uri || b.slug || ""}`],
  product: (b) => [`product:${b.slug || ""}`],
};

export async function POST(request: NextRequest) {
  try {
    const body: RevalidateBody = await request.json();

    if (!body.secret || body.secret !== SECRET) {
      console.error("[revalidate] 401 — invalid secret");
      return Response.json({ revalidated: false, error: "unauthorized" }, { status: 401 });
    }

    const ts = body.timestamp;
    if (!ts || Date.now() - ts > TIMESTAMP_TTL) {
      console.error("[revalidate] 401 — stale or missing timestamp");
      return Response.json({ revalidated: false, error: "timestamp expired or missing" }, { status: 401 });
    }

    if (seenTimestamps.has(ts)) {
      console.error("[revalidate] 401 — replay detected");
      return Response.json({ revalidated: false, error: "replay detected" }, { status: 401 });
    }
    seenTimestamps.add(ts);
    setTimeout(() => seenTimestamps.delete(ts), TIMESTAMP_TTL);

    const ip = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "unknown";
    if (!checkRateLimit(ip)) {
      console.error(`[revalidate] 429 — rate limited ip=${ip}`);
      return Response.json({ revalidated: false, error: "rate limited" }, { status: 429 });
    }

    const { type } = body;
    if (!type || !(type in TAG_MAP)) {
      return Response.json({ revalidated: false, error: `unknown type: ${type}` }, { status: 400 });
    }

    const tags = TAG_MAP[type](body);
    for (const tag of tags) {
      revalidateTag(tag, "max");
      console.log(`[revalidate] revalidated tag=${tag}`);
    }

    return Response.json({ revalidated: true, tags, now: Date.now() });
  } catch (err) {
    console.error("[revalidate] error:", err);
    return Response.json({ revalidated: false, error: "internal error" }, { status: 500 });
  }
}
