import { NextRequest, NextResponse } from "next/server";
import { ADMIN_ROLE } from "@/lib/constants/auth";
import {
  hostPublicDefaultCustomerId,
  isHostPublicApiEnabled,
} from "@/lib/constants/host-public-api";
import {
  DEFAULT_HOST_CUSTOMER_ID,
  isHostServiceAuthDisabled,
} from "@/lib/constants/host-service";
import { verifyToken } from "@/modules/auth/jwt";
import { AuthError } from "@/modules/auth/errors";
import {
  parseServiceTokenFromEnv,
  resolveEnvServiceToken,
} from "@/modules/auth/service-token-env";
import {
  EMBED_DEMO_COOKIE,
  verifyEmbedDemoToken,
} from "@/modules/embed-demo/auth";

const PUBLIC_API_PATHS = [
  "/api/auth/login",
  "/api/embed-demo/login",
];

function isHostPublicRoute(pathname: string): boolean {
  return pathname.startsWith("/api/host/");
}

function isPublicApi(pathname: string): boolean {
  if (pathname.startsWith("/api/embed-demo/")) {
    return true;
  }
  return PUBLIC_API_PATHS.some(
    (path) => pathname === path || pathname.startsWith(`${path}/`),
  );
}

function isAdminRoute(pathname: string): boolean {
  return (
    pathname.startsWith("/api/alerts") ||
    pathname.startsWith("/api/metrics") ||
    pathname.startsWith("/api/rpa") ||
    pathname.startsWith("/api/admin/queues") ||
    pathname.startsWith("/api/admin/markup-configs") ||
    pathname.startsWith("/api/admin/customers") ||
    pathname === "/api/quotes/manual-fallback"
  );
}

function isHostRoute(pathname: string): boolean {
  if (pathname === "/api/quotes/manual-fallback") {
    return false;
  }
  return (
    pathname.startsWith("/api/quotes") ||
    pathname.startsWith("/api/priority1") ||
    pathname.startsWith("/api/flock") ||
    pathname.startsWith("/api/markup-configs") ||
    pathname.startsWith("/api/addresses") ||
    pathname.startsWith("/api/host")
  );
}

function extractBearerToken(request: NextRequest): string | null {
  const header = request.headers.get("authorization");
  if (!header?.startsWith("Bearer ")) {
    return null;
  }
  const token = header.slice(7).trim();
  return token || null;
}

function extractBullBoardCookieToken(request: NextRequest): string | null {
  if (!request.nextUrl.pathname.startsWith("/api/admin/queues")) {
    return null;
  }
  const raw = request.cookies.get("bull_board_auth")?.value;
  if (!raw) {
    return null;
  }
  try {
    return decodeURIComponent(raw);
  } catch {
    return raw;
  }
}

function jsonError(code: string, message: string, status: number): NextResponse {
  return NextResponse.json(
    { code, message, data: null },
    { status, headers: { "Cache-Control": "no-store" } },
  );
}

function passWithHeaders(
  request: NextRequest,
  headers: Record<string, string>,
): NextResponse {
  const requestHeaders = new Headers(request.headers);
  for (const [key, value] of Object.entries(headers)) {
    requestHeaders.set(key, value);
  }
  return NextResponse.next({ request: { headers: requestHeaders } });
}

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  if (!pathname.startsWith("/api/")) {
    return NextResponse.next();
  }

  if (isPublicApi(pathname)) {
    return NextResponse.next();
  }

  if (isHostPublicApiEnabled() && isHostPublicRoute(pathname)) {
    return passWithHeaders(request, {
      "x-auth-type": "service",
      "x-customer-id": hostPublicDefaultCustomerId(),
      "x-permissions": "",
    });
  }

  if (isHostServiceAuthDisabled() && isHostRoute(pathname)) {
    const customerId =
      request.headers.get("x-customer-id")?.trim() ||
      hostPublicDefaultCustomerId() ||
      DEFAULT_HOST_CUSTOMER_ID;
    return passWithHeaders(request, {
      "x-auth-type": "service",
      "x-customer-id": customerId,
      "x-permissions": "pricing:markup:write",
    });
  }

  const token = extractBearerToken(request) ?? extractBullBoardCookieToken(request);
  if (!token) {
    const embedRaw = request.cookies.get(EMBED_DEMO_COOKIE)?.value;
    if (embedRaw && isHostRoute(pathname)) {
      try {
        const embed = await verifyEmbedDemoToken(embedRaw);
        return passWithHeaders(request, {
          "x-auth-type": "service",
          "x-customer-id": embed.sub,
          "x-permissions": "pricing:markup:write",
          "x-service-verified": "true",
        });
      } catch {
        return jsonError("UNAUTHORIZED", "演示会话无效或已过期", 401);
      }
    }
    return jsonError("UNAUTHORIZED", "缺少 Authorization 头", 401);
  }

  try {
    if (isAdminRoute(pathname)) {
      const payload = await verifyToken(token);
      if (payload.role !== ADMIN_ROLE) {
        return jsonError("FORBIDDEN", "需要管理员权限", 403);
      }
      return passWithHeaders(request, {
        "x-auth-type": "admin",
        "x-user-id": payload.sub,
        "x-user-role": payload.role,
      });
    }

    if (isHostRoute(pathname)) {
      const customerId = request.headers.get("x-customer-id")?.trim() || null;
      try {
        if (customerId) {
          const verified = resolveEnvServiceToken(token, customerId);
          if (verified) {
            return passWithHeaders(request, {
              "x-auth-type": "service",
              "x-customer-id": verified.customerId,
              "x-permissions": verified.permissions.join(","),
              "x-service-verified": "true",
            });
          }
        } else {
          const parsed = parseServiceTokenFromEnv(token);
          if (parsed) {
            return passWithHeaders(request, {
              "x-auth-type": "service",
              "x-customer-id": parsed.customerId,
              "x-permissions": parsed.permissions.join(","),
              "x-service-verified": "true",
            });
          }
        }
      } catch (error) {
        if (error instanceof AuthError) {
          return jsonError(error.code, error.message, error.httpStatus);
        }
        throw error;
      }

      return passWithHeaders(request, {
        "x-auth-type": "service",
        "x-customer-id": customerId ?? "",
        "x-bearer-token": token,
        "x-permissions": "",
        "x-service-verified": "false",
      });
    }

    // 未分类 API 默认要求管理员 JWT
    const payload = await verifyToken(token);
    return passWithHeaders(request, {
      "x-auth-type": "admin",
      "x-user-id": payload.sub,
      "x-user-role": payload.role,
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return jsonError(error.code, error.message, error.httpStatus);
    }
    console.error("[middleware] 鉴权异常:", error);
    return jsonError("INTERNAL_ERROR", "鉴权处理失败", 500);
  }
}

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