import { NextResponse, type NextRequest } from "next/server";

const CORS_ORIGINS = process.env.CORS_ORIGINS?.split(",") ?? [
  "http://localhost:3000",
];

function getAllowedOrigin(request: NextRequest) {
  const origin = request.headers.get("origin");

  if (origin && CORS_ORIGINS.includes(origin)) {
    return origin;
  }

  return CORS_ORIGINS[0];
}

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  // If this request is a proxied call from the logger, skip proxying to avoid loops
  const isProxied = request.headers.get("x-logger-proxy") === "1";

  // Simple request logger so requests appear in container logs (and dev terminal)
  try {
    const now = new Date().toISOString();
    const client = request.headers.get("x-forwarded-for") ?? request.headers.get("x-real-ip") ?? "-";
    // eslint-disable-next-line no-console
    console.log(`[request] ${now} ${request.method} ${pathname} from ${client}`);
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error("[middleware logger] failed to log request", e);
  }
  // Let health route pass through; auth routes should still receive CORS headers
  if (pathname === "/api/health") {
  const res = NextResponse.next();

  res.headers.set(
    "Access-Control-Allow-Origin",
    getAllowedOrigin(request)
  );

  res.headers.set(
    "Access-Control-Allow-Headers",
    "Authorization,Content-Type"
  );

  res.headers.set(
    "Access-Control-Allow-Credentials",
    "true"
  );

  return res;
}
  // Only apply CORS handling to API routes
  if (!pathname.startsWith("/api/")) {
    return NextResponse.next();
  }

  // Handle preflight
  if (request.method === "OPTIONS") {
    const res = new NextResponse(null, { status: 204 });
    res.headers.set("Access-Control-Allow-Origin", getAllowedOrigin(request));
    res.headers.set(
  "Access-Control-Allow-Methods",
  "GET,POST,PUT,PATCH,DELETE,OPTIONS"
);
    res.headers.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
    res.headers.set("Access-Control-Allow-Credentials", "true");
    return res;
  }
  // If not API or if this is the proxied request, just continue
  if (isProxied) {
    const res = NextResponse.next();
    res.headers.set("Access-Control-Allow-Origin", getAllowedOrigin(request));
    res.headers.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
    res.headers.set("Access-Control-Allow-Credentials", "true");
    return res;
  }

  // For API requests, proxy once with a marker header so we can capture the downstream response
  try {
    const start = Date.now();
    const proxiedHeaders = new Headers(request.headers);
    proxiedHeaders.set("x-logger-proxy", "1");

    const proxiedReq = new Request(request.url, {
      method: request.method,
      headers: proxiedHeaders,
      body: request.body,
      redirect: "manual",
    });

    const response = await fetch(proxiedReq);
    const duration = Date.now() - start;

    // Clone response so we can mutate headers
    const res = new Response(response.body, response);
    res.headers.set("Access-Control-Allow-Origin", getAllowedOrigin(request));
    res.headers.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
    res.headers.set("Access-Control-Allow-Credentials", "true");

    // Log response status and duration
    try {
      const now = new Date().toISOString();
      // eslint-disable-next-line no-console
      console.log(`[response] ${now} ${request.method} ${pathname} -> ${res.status} in ${duration}ms`);
    } catch (e) {
      // eslint-disable-next-line no-console
      console.error("[middleware logger] failed to log response", e);
    }

    return res;
  } catch (e) {
    // If proxying fails, fallback to next and log the error
    // eslint-disable-next-line no-console
    console.error("[middleware logger] proxy failed", e);
    const res = NextResponse.next();
    res.headers.set("Access-Control-Allow-Origin", getAllowedOrigin(request));
    res.headers.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
    res.headers.set("Access-Control-Allow-Credentials", "true");
    return res;
  }
}

export const config = {
  matcher: ["/api/:path*"],
};
