import type { Permission } from "@/lib/constants/auth";
import { forbidden } from "@/modules/auth/errors";
import type { AuthContext } from "@/modules/auth/rbac";
import { verifyServiceTokenAsync } from "@/modules/auth/service-token";

export type ServiceAuthContext = Extract<AuthContext, { type: "service" }>;

function parsePermissionsHeader(raw: string): Permission[] {
  return raw
    .split(",")
    .map((p) => p.trim())
    .filter(Boolean) as Permission[];
}

function parseVerifiedServiceAuth(request: Request): ServiceAuthContext | null {
  const authType = request.headers.get("x-auth-type");
  if (authType !== "service") {
    return null;
  }

  const customerId = request.headers.get("x-customer-id");
  if (!customerId) {
    throw forbidden("缺少客户标识");
  }

  const verified = request.headers.get("x-service-verified");
  const permissionsRaw = request.headers.get("x-permissions") ?? "";
  if (verified === "true" || permissionsRaw.length > 0) {
    return {
      type: "service",
      customerId,
      permissions: parsePermissionsHeader(permissionsRaw),
    };
  }

  return null;
}

function extractBearerFromRequest(request: Request): string | null {
  const forwarded = request.headers.get("x-bearer-token")?.trim();
  if (forwarded) {
    return forwarded;
  }
  const authHeader = request.headers.get("authorization");
  if (authHeader?.startsWith("Bearer ")) {
    return authHeader.slice(7).trim();
  }
  return null;
}

/** 从 middleware 注入的请求头解析宿主鉴权上下文（含 DB Token 二次校验） */
export async function parseServiceAuth(
  request: Request,
): Promise<ServiceAuthContext> {
  const fastPath = parseVerifiedServiceAuth(request);
  if (fastPath) {
    return fastPath;
  }

  const bearerToken = extractBearerFromRequest(request);
  if (!bearerToken) {
    throw forbidden("需要宿主 Service Token");
  }

  const customerId = request.headers.get("x-customer-id")?.trim() || undefined;
  const verified = await verifyServiceTokenAsync(bearerToken, customerId);
  return {
    type: "service",
    customerId: verified.customerId,
    permissions: verified.permissions,
  };
}

/** 校验请求体 customer_id 与 token 租户一致 */
export function assertCustomerMatch(
  auth: ServiceAuthContext,
  bodyCustomerId: string,
): void {
  if (auth.customerId !== bodyCustomerId) {
    throw forbidden("customer_id 与令牌租户不匹配");
  }
}
