import { timingSafeEqual } from 'node:crypto';
import { revalidatePath } from 'next/cache';
import { NextResponse, type NextRequest } from 'next/server';

const SUPPORTED_PATHS = [
  /^\/productos\/[a-z0-9]+(?:-[a-z0-9]+)*$/,
  /^\/categoria\/[a-z0-9]+(?:-[a-z0-9]+)*$/,
  /^\/marca\/[a-z0-9]+(?:-[a-z0-9]+)*$/,
  /^\/products\/search$/,
];

function isSupportedCatalogPath(path: unknown): path is string {
  return typeof path === 'string' && SUPPORTED_PATHS.some((pattern) => pattern.test(path));
}

function secretsMatch(actual: string | null, expected: string): boolean {
  if (actual === null) return false;
  const actualBuffer = Buffer.from(actual);
  const expectedBuffer = Buffer.from(expected);
  return (
    actualBuffer.length === expectedBuffer.length && timingSafeEqual(actualBuffer, expectedBuffer)
  );
}

export async function POST(request: NextRequest) {
  const secret = process.env.REVALIDATE_SECRET;
  if (!secret) {
    return NextResponse.json(
      { revalidated: false, error: 'Revalidation is not configured' },
      { status: 503 },
    );
  }
  if (!secretsMatch(request.headers.get('x-revalidate-secret'), secret)) {
    return NextResponse.json({ revalidated: false, error: 'Unauthorized' }, { status: 401 });
  }

  let body: unknown;
  try {
    body = await request.json();
  } catch {
    return NextResponse.json({ revalidated: false, error: 'Invalid JSON body' }, { status: 400 });
  }

  const path = typeof body === 'object' && body !== null && 'path' in body ? body.path : undefined;
  if (!isSupportedCatalogPath(path)) {
    return NextResponse.json(
      { revalidated: false, error: 'Unsupported revalidation path' },
      { status: 400 },
    );
  }

  revalidatePath(path);
  return NextResponse.json({ revalidated: true, path });
}
