import { NextResponse } from "next/server";
import { hasSanityWriteAccess, sanityWriteClient } from "@/lib/sanity/write-client";
import { consumeMetricRateLimit, getClientKeyFromHeaders, recordMetricAllowed, recordMetricBlocked } from "@/lib/api-metrics";

const MAX_NAME_LENGTH = 80;
const MAX_TITLE_LENGTH = 120;
const MAX_BODY_LENGTH = 2000;

function isNonEmptyString(value: unknown, maxLength: number): value is string {
  return typeof value === "string" && value.trim().length > 0 && value.trim().length <= maxLength;
}

export async function POST(request: Request) {
  if (!hasSanityWriteAccess || !sanityWriteClient) {
    return NextResponse.json({ error: "reviews_disabled" }, { status: 503 });
  }

  const clientKey = getClientKeyFromHeaders({
    forwardedFor: request.headers.get("x-forwarded-for"),
    realIp: request.headers.get("x-real-ip"),
  });
  const rateLimit = consumeMetricRateLimit("reviewSubmit", clientKey);

  if (!rateLimit.allowed) {
    recordMetricBlocked("reviewSubmit", clientKey);
    return NextResponse.json({ error: "rate_limited" }, { status: 429 });
  }

  let body: unknown;
  try {
    body = await request.json();
  } catch {
    return NextResponse.json({ error: "invalid_body" }, { status: 400 });
  }

  const payload = body as {
    productId?: unknown;
    rating?: unknown;
    authorName?: unknown;
    authorEmail?: unknown;
    title?: unknown;
    body?: unknown;
  };

  const rating = Number(payload.rating);
  const productId = typeof payload.productId === "string" ? payload.productId.trim() : "";

  if (!productId || !Number.isInteger(rating) || rating < 1 || rating > 5) {
    return NextResponse.json({ error: "invalid_rating_or_product" }, { status: 400 });
  }

  if (!isNonEmptyString(payload.authorName, MAX_NAME_LENGTH)) {
    return NextResponse.json({ error: "invalid_author_name" }, { status: 400 });
  }

  if (!isNonEmptyString(payload.body, MAX_BODY_LENGTH)) {
    return NextResponse.json({ error: "invalid_body_text" }, { status: 400 });
  }

  const title = typeof payload.title === "string" ? payload.title.trim().slice(0, MAX_TITLE_LENGTH) : "";
  const authorEmail = typeof payload.authorEmail === "string" ? payload.authorEmail.trim().slice(0, 200) : "";

  try {
    await sanityWriteClient.create({
      _type: "productReview",
      product: { _type: "reference", _ref: productId },
      rating,
      authorName: (payload.authorName as string).trim(),
      authorEmail: authorEmail || undefined,
      title: title || undefined,
      body: (payload.body as string).trim(),
      status: "pending",
      createdAt: new Date().toISOString(),
    });
  } catch {
    return NextResponse.json({ error: "create_failed" }, { status: 500 });
  }

  recordMetricAllowed("reviewSubmit", clientKey);
  return NextResponse.json({ ok: true });
}
