import { NextResponse } from "next/server";
import { verifyAudienceJwt, verifyJwt } from "@open-mercato/shared/lib/auth/jwt";
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { CUSTOMER_JWT_AUDIENCE } from "@open-mercato/core/modules/customer_accounts/services/customerSessionService";
async function assertSessionStillActive(sessionId) {
  try {
    const [{ createRequestContainer }, { CustomerSessionService }] = await Promise.all([
      import("@open-mercato/shared/lib/di/container"),
      import("@open-mercato/core/modules/customer_accounts/services/customerSessionService")
    ]);
    const container = await createRequestContainer();
    const service = container.resolve("customerSessionService");
    const session = await service.findActiveSessionById(sessionId);
    return session !== null;
  } catch {
    return false;
  }
}
function readCookieFromHeader(header, name) {
  if (!header) return void 0;
  const parts = header.split(";");
  for (const part of parts) {
    const trimmed = part.trim();
    if (trimmed.startsWith(`${name}=`)) {
      return trimmed.slice(name.length + 1);
    }
  }
  return void 0;
}
async function validateUserState(sub, tenantId, orgId, iat) {
  const [{ createRequestContainer }, { CustomerUser }] = await Promise.all([
    import("@open-mercato/shared/lib/di/container"),
    import("@open-mercato/core/modules/customer_accounts/data/entities")
  ]);
  const container = await createRequestContainer();
  const em = container.resolve("em");
  const user = await findOneWithDecryption(em, CustomerUser, { id: sub }, {
    fields: ["sessionsRevokedAt", "deletedAt", "isActive"]
  });
  if (!user) return { valid: false };
  if (user.deletedAt) return { valid: false };
  if (!user.isActive) return { valid: false };
  if (user.sessionsRevokedAt && typeof iat === "number" && iat * 1e3 < user.sessionsRevokedAt.getTime()) {
    return { valid: false };
  }
  const { CustomerRbacService } = await import("@open-mercato/core/modules/customer_accounts/services/customerRbacService");
  const rbac = container.resolve("customerRbacService");
  const acl = await rbac.loadAcl(sub, { tenantId, organizationId: orgId });
  return { valid: true, resolvedFeatures: acl.isPortalAdmin ? ["*"] : acl.features };
}
async function getCustomerAuthFromRequest(req) {
  const cookieHeader = req.headers.get("cookie") || "";
  const authHeader = (req.headers.get("authorization") || "").trim();
  let token;
  if (authHeader.toLowerCase().startsWith("bearer ")) {
    token = authHeader.slice(7).trim();
  }
  if (!token) {
    const cookieValue = readCookieFromHeader(cookieHeader, "customer_auth_token");
    if (cookieValue) {
      try {
        token = decodeURIComponent(cookieValue);
      } catch {
        token = cookieValue;
      }
    }
  }
  if (!token) return null;
  try {
    let payload = verifyAudienceJwt(CUSTOMER_JWT_AUDIENCE, token);
    if (!payload) {
      payload = verifyJwt(token);
      if (payload) payload._legacyToken = true;
    }
    if (!payload) return null;
    if (payload.type !== "customer") return null;
    const sid = typeof payload.sid === "string" ? payload.sid : "";
    if (!sid && payload._legacyToken !== true) return null;
    const stillActive = sid ? await assertSessionStillActive(sid) : true;
    if (!stillActive) return null;
    const userState = await validateUserState(
      String(payload.sub),
      String(payload.tenantId),
      String(payload.orgId),
      payload.iat
    );
    if (!userState.valid) return null;
    return {
      sub: String(payload.sub),
      sid,
      type: "customer",
      tenantId: String(payload.tenantId),
      orgId: String(payload.orgId),
      email: String(payload.email || ""),
      displayName: String(payload.displayName || ""),
      customerEntityId: payload.customerEntityId ? String(payload.customerEntityId) : null,
      personEntityId: payload.personEntityId ? String(payload.personEntityId) : null,
      resolvedFeatures: userState.resolvedFeatures
    };
  } catch {
    return null;
  }
}
async function requireCustomerAuth(req) {
  const auth = await getCustomerAuthFromRequest(req);
  if (!auth) {
    throw NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
  }
  return auth;
}
async function requireCustomerFeature(auth, features, rbac) {
  if (!features.length) return;
  const ok = await rbac.userHasAllFeatures(
    auth.sub,
    features,
    { tenantId: auth.tenantId, organizationId: auth.orgId }
  );
  if (!ok) {
    throw NextResponse.json({ ok: false, error: "Insufficient permissions" }, { status: 403 });
  }
}
export {
  getCustomerAuthFromRequest,
  readCookieFromHeader,
  requireCustomerAuth,
  requireCustomerFeature,
  validateUserState
};
//# sourceMappingURL=customerAuth.js.map
