import { NextResponse } from "next/server";
import { searchSanityProductSuggestions } from "@/lib/sanity/queries";
import { consumeMetricRateLimit, getApiMetricsSnapshot, getClientKeyFromHeaders, recordMetricAllowed, recordMetricBlocked } from "@/lib/api-metrics";

const SEARCH_MIN_QUERY_LENGTH = 4;
const CACHE_CONTROL_HEADER = "public, max-age=300, s-maxage=3600, stale-while-revalidate=86400";

function withRateLimitHeaders(init: ResponseInit, limit: number, remaining: number, resetAt: number): ResponseInit {
  const resetInSeconds = Math.max(0, Math.ceil((resetAt - Date.now()) / 1000));

  return {
    ...init,
    headers: {
      ...init.headers,
      "Cache-Control": CACHE_CONTROL_HEADER,
      "X-RateLimit-Limit": String(limit),
      "X-RateLimit-Remaining": String(Math.max(0, remaining)),
      "X-RateLimit-Reset": String(resetInSeconds),
    },
  };
}

function logSearchSuggestionMetrics(message: string, details: Record<string, unknown>) {
  console.info("[search-suggestions]", message, details);
}

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const query = (searchParams.get("q") || "").trim();
  const clientKey = getClientKeyFromHeaders({
    forwardedFor: request.headers.get("x-forwarded-for"),
    realIp: request.headers.get("x-real-ip"),
  });
  const rateLimit = consumeMetricRateLimit("searchSuggestions", clientKey);

  if (!rateLimit.allowed) {
    const blocked = recordMetricBlocked("searchSuggestions", query);
    logSearchSuggestionMetrics("rate_limited", {
      blocked,
      ip: clientKey,
      queryLength: query.length,
    });

    return NextResponse.json(
      { suggestions: [], error: "rate_limited" },
      withRateLimitHeaders({ status: 429 }, rateLimit.limit, rateLimit.remaining, rateLimit.resetAt),
    );
  }

  if (query.length < SEARCH_MIN_QUERY_LENGTH) {
    return NextResponse.json(
      { suggestions: [] },
      withRateLimitHeaders({}, rateLimit.limit, rateLimit.remaining, rateLimit.resetAt),
    );
  }

  const suggestions = await searchSanityProductSuggestions(query, 6);
  const allowed = recordMetricAllowed("searchSuggestions", query);

  if (allowed % 25 === 0) {
    const snapshot = getApiMetricsSnapshot();
    logSearchSuggestionMetrics("traffic_snapshot", {
      allowed,
      blocked: snapshot.metrics.searchSuggestions.blocked,
      query,
      suggestionCount: suggestions.length,
    });
  }

  return NextResponse.json(
    { suggestions },
    withRateLimitHeaders({}, rateLimit.limit, rateLimit.remaining, rateLimit.resetAt),
  );
}
