import 'server-only';
import { NextRequest, NextResponse } from 'next/server';
import { isCrossOriginRequest } from './sameOrigin';
import { BACKEND_TOKEN_COOKIE_NAME, SESSION_COOKIE_NAME, parseSessionToken } from './session';
import { canManageUsers, isRecord, isUserId } from './users';
import { BVAS_GEOGRAPHY_FILTERS, canFilterBvas, validateBvasQuery } from './bvasInfo';
import { isBvasReport3, isBvasReport3Page } from './bvasReport3';

function json(data: unknown, status = 200) {
  return NextResponse.json(data, { status, headers: { 'Cache-Control': 'private, no-store' } });
}

export async function proxyBvasReport3(request: NextRequest, id?: string) {
  try {
    const token = request.cookies.get(BACKEND_TOKEN_COOKIE_NAME)?.value;
    const user = await parseSessionToken(request.cookies.get(SESSION_COOKIE_NAME)?.value, token);
    if (!user || !token) {
      const result = json({ error: 'Sign in to access BVAS Report 3.' }, 401);
      for (const name of [SESSION_COOKIE_NAME, BACKEND_TOKEN_COOKIE_NAME]) result.cookies.set(name, '', { httpOnly: true, path: '/', sameSite: 'lax', maxAge: 0 });
      return result;
    }
    if (request.method !== 'GET' && request.method !== 'DELETE') return json({ error: 'BVAS Report 3 supports reading and deletion only.' }, 405);
    if (request.method === 'DELETE') {
      if (!canManageUsers(user)) return json({ error: 'Only super admins can delete BVAS Report 3.' }, 403);
      if (isCrossOriginRequest(request)) return json({ error: 'Cross-origin requests are not allowed.' }, 403);
      if (id === undefined) return json({ error: 'A report UUID is required for deletion.' }, 422);
    }
    if (id !== undefined && !isUserId(id)) return json({ error: 'A valid report UUID is required.' }, 422);
    const query = request.nextUrl.searchParams;
    if (!canFilterBvas(user) && BVAS_GEOGRAPHY_FILTERS.some((field) => query.has(field))) return json({ error: 'Only super admins and national administrators can filter geography.' }, 403);
    const errors = validateBvasQuery(query, canFilterBvas(user));
    if (id !== undefined && query.size) errors.query = ['Individual report requests do not accept filters.'];
    if (Object.keys(errors).length) return json({ error: 'Check the BVAS Report 3 filters.', errors }, 422);
    const base = process.env.NEXT_PUBLIC_URL?.trim().replace(/\/+$/, '');
    if (!base) return json({ error: 'The BVAS API base URL is not configured.' }, 503);
    let response: Response;
    try {
      response = await fetch(`${base}/v1/bvas-report3${id ? `/${encodeURIComponent(id)}` : ''}${query.size ? `?${query}` : ''}`, {
        method: request.method,
        headers: { Accept: 'application/json', Authorization: `Bearer ${token}` },
        cache: 'no-store', redirect: 'manual', signal: AbortSignal.timeout(15000),
      });
    } catch {
      return json({ error: 'Unable to reach the BVAS Report 3 service. Please try again.' }, 502);
    }
    if (response.status === 204 && request.method === 'DELETE') return new NextResponse(null, { status: 204, headers: { 'Cache-Control': 'private, no-store' } });
    let data: unknown;
    try { data = await response.json(); }
    catch { return json({ error: 'The BVAS Report 3 service returned an invalid response.' }, 502); }
    if (!response.ok) {
      const result = json({
        error: isRecord(data) && typeof data.message === 'string' ? data.message : 'The BVAS Report 3 request failed.',
        ...(isRecord(data) && isRecord(data.errors) ? { errors: data.errors } : {}),
      }, response.status >= 400 && response.status < 500 ? response.status : 502);
      if (response.status === 401) for (const name of [SESSION_COOKIE_NAME, BACKEND_TOKEN_COOKIE_NAME]) result.cookies.set(name, '', { httpOnly: true, path: '/', sameSite: 'lax', maxAge: 0 });
      return result;
    }
    if (request.method === 'DELETE') return json({ error: 'The BVAS Report 3 service did not confirm deletion.' }, 502);
    if (id ? !isRecord(data) || !isBvasReport3(data.data) : !isBvasReport3Page(data)) return json({ error: 'The BVAS Report 3 service returned invalid records.' }, 502);
    return json(data, response.status);
  } catch (error) {
    console.error('BVAS Report 3 request failed:', error);
    return json({ error: 'Unable to process the BVAS Report 3 request.' }, 500);
  }
}
