import jwt from "jsonwebtoken";

type JwtPayload = {
  sub: string;
  role: string;
};

function getRequiredEnv(name: string) {
  const value = process.env[name];

  if (!value) {
    throw new Error(`Missing required environment variable: ${name}`);
  }

  return value;
}

function getJwtSecret() {
  return getRequiredEnv("SECRET_KEY");
}

function getJwtAlgorithm() {
  return process.env.JWT_ALGORITHM ?? "HS256";
}

function getJwtExpirationHours() {
  const rawValue = process.env.JWT_EXPIRATION_HOURS ?? "24";
  const parsedValue = Number(rawValue);

  return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : 24;
}

export function issueJwtToken(username: string, role: string = "lecture") {
  const payload: JwtPayload = {
    sub: username,
    role,
  };

  return jwt.sign(payload, getJwtSecret(), {
    algorithm: getJwtAlgorithm() as jwt.Algorithm,
    expiresIn: `${getJwtExpirationHours()}h`,
  });
}

export function verifyJwtToken(token: string) {
  return jwt.verify(token.trim(), getJwtSecret(), {
    algorithms: [getJwtAlgorithm() as jwt.Algorithm],
  }) as jwt.JwtPayload & JwtPayload;
}

export function extractAuthToken(authorizationHeader: string | null) {
  if (!authorizationHeader) {
    return null;
  }

  const trimmedHeader = authorizationHeader.trim();
  const bearerMatch = /^Bearer\s+(.+)$/i.exec(trimmedHeader);

  if (bearerMatch?.[1]) {
    return bearerMatch[1].trim();
  }

  return trimmedHeader;
}