/**
 * Error types for the SentryAgent.ai AgentIdP SDK.
 */

/** Standard error response shape from the AgentIdP API. */
interface ApiErrorBody {
  code: string;
  message: string;
  details?: Record<string, unknown>;
}

/** OAuth 2.0 error response shape from the token endpoint. */
interface OAuth2ErrorBody {
  error: string;
  error_description: string;
}

/**
 * Typed error thrown by the AgentIdP SDK for all API failures.
 * Never throws raw fetch errors or untyped exceptions.
 */
export class AgentIdPError extends Error {
  /** Machine-readable error code from the API (e.g. AGENT_NOT_FOUND). */
  readonly code: string;
  /** HTTP status code of the failed response. */
  readonly httpStatus: number;
  /** Optional structured details from the API error response. */
  readonly details?: Record<string, unknown>;

  constructor(code: string, message: string, httpStatus: number, details?: Record<string, unknown>) {
    super(message);
    this.name = 'AgentIdPError';
    this.code = code;
    this.httpStatus = httpStatus;
    this.details = details;
  }

  /**
   * Creates an AgentIdPError from a standard API error response body.
   * Accepts unknown to allow callers to pass raw parsed JSON without pre-casting.
   *
   * @param body - Parsed API error response (or unknown).
   * @param httpStatus - HTTP status code.
   * @returns AgentIdPError instance.
   */
  static fromApiError(body: unknown, httpStatus: number): AgentIdPError {
    if (
      typeof body === 'object' &&
      body !== null &&
      'code' in body &&
      'message' in body &&
      typeof (body as ApiErrorBody).code === 'string' &&
      typeof (body as ApiErrorBody).message === 'string'
    ) {
      const typed = body as ApiErrorBody;
      return new AgentIdPError(typed.code, typed.message, httpStatus, typed.details);
    }
    return new AgentIdPError('UNKNOWN_ERROR', String(body), httpStatus);
  }

  /**
   * Creates an AgentIdPError from an OAuth 2.0 error response body.
   *
   * @param body - Parsed OAuth2 error response.
   * @param httpStatus - HTTP status code.
   * @returns AgentIdPError instance.
   */
  static fromOAuth2Error(body: OAuth2ErrorBody, httpStatus: number): AgentIdPError {
    return new AgentIdPError(body.error, body.error_description, httpStatus);
  }
}
