export enum OAuth2Type {
  AUTHORIZATION_CODE = 'auth_code',
  AUTHORIZATION_CODE_PKCE = 'auth_code_pkce',
  CLIENT_CREDENTIALS = 'client_credentials',
}

export enum AuthFormat {
  BASIC_AUTH = 'basic',
  IN_BODY = 'body',
}

export enum RequestFormat {
  JSON = 'json',
  FORM = 'form',
}

export interface SimpleAuthorizationRequestParams extends Record<string, string> {
  response_type: 'code';
  /**
   * The client ID of your application
   */
  client_id: string;
  /**
   * The URL in your app where users will be sent after authorization
   */
  redirect_uri: string;
  /**
   * A random string generated by your application, which you'll verify later
   */
  state: string;
  /**
   * A space-separated list of scopes
   */
  scope: string;
}
export interface CodeChallengeAuthorizationRequestParams
  extends SimpleAuthorizationRequestParams {
  code_challenge: string;
  code_challenge_method: 'S256';
}
export type AuthorizationRequestParams =
  | SimpleAuthorizationRequestParams
  | CodeChallengeAuthorizationRequestParams;

export interface AuthorizationRedirectResponse {
  /**
   * The authorization code received from the authorization server
   */
  code: string;
  /**
   * The exact value of the state parameter passed by the client in the authorization request
   */
  state: string;
}

export interface AuthorizationRedirectErrorResponse {
  error: string;
  state: string;
  error_description?: string;
  error_uri?: string;
}

export interface AuthorizationCode_AccessTokenRequest {
  grant_type: 'authorization_code';
  /**
   * The authorization code received from the authorization server
   */
  code: string;
  /**
   * The redirect URI used in the initial request
   */
  redirect_uri: string;
  client_id: string;
  client_secret: string;
}
export interface AuthorizationCodePKCE_AccessTokenRequest
  extends AuthorizationCode_AccessTokenRequest {
  code_verifier: string;
}

// https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
export interface ClientCredentials_AccessTokenRequest {
  grant_type: 'client_credentials';
  client_id: string;
  client_secret: string;
  scope?: string;
}

// https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
export type AccessTokenRequest =
  | AuthorizationCode_AccessTokenRequest
  | AuthorizationCodePKCE_AccessTokenRequest
  | ClientCredentials_AccessTokenRequest;

export interface AccessTokenResponse {
  /**
   * The access token issued by the authorization server
   */
  access_token: string;
  /**
   * The type of the token issued
   */
  token_type: string;
  /**
   * The exact value of the state parameter passed by the client in the authorization request
   */
  state: string;
  /**
   * The lifetime in seconds of the access token
   */
  expires_in?: number;
  refresh_token?: string;
  id_token?: string;
  scope?: string;
}

export interface AccessTokenErrorResponse {
  error: string;
  state: string;
  error_description?: string;
  error_uri?: string;
}
