import {
  exchangeLaunchForSession,
  TokenClaimError,
  userClaimsFromPayload,
} from "./tokenService.js";

function getJwtSecret() {
  const secret = process.env.JWT_SECRET;
  if (typeof secret === "string" && secret.trim() !== "") {
    return secret.trim();
  }
  if (process.env.NODE_ENV === "test") {
    return "test-jwt-secret";
  }
  throw new Error("JWT_SECRET is not configured");
}

function readBearerToken(req) {
  const authHeader = req.headers.authorization || "";
  const [scheme, token] = authHeader.split(" ");
  if (scheme === "Bearer" && token) {
    return token;
  }
  const bodyToken = req.body?.token;
  if (typeof bodyToken === "string" && bodyToken.trim()) {
    return bodyToken.trim();
  }
  return null;
}

/**
 * Express handler: exchange a short-lived launch JWT for an app session JWT.
 * Mount at POST /api/{app}/auth/session (public — launch token is the credential).
 */
export function createSessionExchangeHandler(expectedAud) {
  return (req, res) => {
    const launchToken = readBearerToken(req);
    if (!launchToken) {
      return res.status(401).json({
        success: false,
        message: "Missing launch token",
      });
    }

    try {
      const secret = getJwtSecret();
      const { decoded, sessionToken } = exchangeLaunchForSession(
        launchToken,
        expectedAud,
        secret
      );
      const user = userClaimsFromPayload(decoded);
      return res.status(200).json({
        success: true,
        token: sessionToken,
        tokenType: "Bearer",
        user: {
          userId: user.userId,
          employeeName: user.employeeName,
          email: user.email,
          roles: user.roles,
          roleIds: user.roleIds,
        },
      });
    } catch (error) {
      if (error instanceof TokenClaimError) {
        return res.status(error.status).json({
          success: false,
          message: error.message,
        });
      }
      return res.status(401).json({
        success: false,
        message: "Invalid or expired launch token",
      });
    }
  };
}
