import { NextRequest, NextResponse } from "next/server";
import { cookies } from "next/headers";
import type { ScoringOverrideRequest } from "@/lib/admin-types";
import { decodeAdminToken, ADMIN_COOKIE, officerHasPermission } from "@/lib/admin-auth";
import { adminApiUsesMock, overrideAdminScoring } from "@/lib/admin-mock";
import { apiErrorResponse } from "@/lib/api-errors";
import { getOrCreateCorrelationId, withCorrelationId } from "@/lib/correlation-id";
import { fetchUpstream } from "@/lib/proxy-upstream";

type RouteContext = { params: Promise<{ id: string }> };

export async function POST(req: NextRequest, context: RouteContext) {
  const correlationId = getOrCreateCorrelationId(req);
  const { id } = await context.params;
  const jar = await cookies();
  const officer = decodeAdminToken(jar.get(ADMIN_COOKIE)?.value);

  if (!officer) {
    return apiErrorResponse(401, "UNAUTHORIZED", "Officer authentication required", correlationId);
  }

  const body = (await req.json().catch(() => null)) as ScoringOverrideRequest | null;
  if (!body || typeof body.score !== "number") {
    return apiErrorResponse(400, "BAD_REQUEST", "score is required", correlationId);
  }

  if (!officerHasPermission(officer, "scoring:override")) {
    return apiErrorResponse(403, "FORBIDDEN", "Scoring override not permitted for your role", correlationId);
  }

  if (adminApiUsesMock()) {
    const updated = overrideAdminScoring(id, body, officer.id);
    if (!updated) {
      return apiErrorResponse(404, "NOT_FOUND", "Case not found", correlationId);
    }
    return withCorrelationId(NextResponse.json({ case: updated }), correlationId);
  }

  const upstream = await fetchUpstream(`/admin/cases/${id}/scoring`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${jar.get(ADMIN_COOKIE)?.value}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(body),
    correlationId,
  });

  if (!upstream?.ok) {
    const fallback = overrideAdminScoring(id, body, officer.id);
    if (fallback) {
      return withCorrelationId(NextResponse.json({ case: fallback }), correlationId);
    }
    return apiErrorResponse(
      upstream?.status ?? 503,
      "UPSTREAM_ERROR",
      "Scoring override failed",
      correlationId,
    );
  }

  const data = await upstream.json();
  return withCorrelationId(NextResponse.json(data), correlationId);
}
