const DEFAULT_JWT_EXPIRY_SECONDS = 7 * 24 * 60 * 60;

const isFiniteNumber = (value: unknown): value is number =>
  typeof value === "number" && Number.isFinite(value) && value > 0;

/**
 * Parse a JWT expiry configuration string (e.g. "15m", "7d") into seconds.
 * Falls back to a sensible default when parsing fails.
 */
export const parseJwtExpiry = (expiresIn: string | number | undefined | null): number => {
  if (isFiniteNumber(expiresIn)) {
    return Math.floor(expiresIn);
  }

  if (typeof expiresIn !== "string") {
    return DEFAULT_JWT_EXPIRY_SECONDS;
  }

  const trimmed = expiresIn.trim();
  if (!trimmed) {
    return DEFAULT_JWT_EXPIRY_SECONDS;
  }

  const unit = trimmed.slice(-1);
  const valuePortion = trimmed.slice(0, -1);
  const parsedValue = parseInt(valuePortion, 10);

  const toSeconds = (multiplier: number) => {
    if (Number.isNaN(parsedValue) || parsedValue <= 0) {
      return DEFAULT_JWT_EXPIRY_SECONDS;
    }
    return parsedValue * multiplier;
  };

  switch (unit) {
    case "s":
      return toSeconds(1);
    case "m":
      return toSeconds(60);
    case "h":
      return toSeconds(60 * 60);
    case "d":
      return toSeconds(24 * 60 * 60);
    default: {
      const numeric = Number(trimmed);
      if (isFiniteNumber(numeric)) {
        return Math.floor(numeric);
      }
      return DEFAULT_JWT_EXPIRY_SECONDS;
    }
  }
};

export const calculateExpiryDate = (
  expiresIn: string | number | undefined | null,
  referenceDate: number = Date.now()
): string => {
  const seconds = parseJwtExpiry(expiresIn);
  return new Date(referenceDate + seconds * 1000).toISOString();
};

export const JWT_EXPIRY_DEFAULT_SECONDS = DEFAULT_JWT_EXPIRY_SECONDS;
