import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';

/**
 * TokenResponseDto - Data Transfer Object for authentication token responses
 *
 * This DTO defines the structure of OAuth 2.0 compliant token responses
 * following RFC 6749 and RFC 6750 standards. It provides both access and
 * refresh tokens along with metadata for proper token management.
 *
 * Used by authentication endpoints (login, registration, token refresh) to
 * return tokens in a standardized format that OAuth clients can understand.
 *
 * @see https://datatracker.ietf.org/doc/html/rfc6749 - OAuth 2.0 Framework
 * @see https://datatracker.ietf.org/doc/html/rfc6750 - Bearer Token Usage
 *
 * @example
 * // Standard OAuth 2.0 token response
 * {
 *   "token_type": "Bearer",
 *   "expires_in": "3600",
 *   "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
 *   "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
 * }
 *
 * @example
 * // Usage in authentication services
 * generateTokens(user: User): TokenResponseDto {
 *   return {
 *     token_type: 'Bearer',
 *     expires_in: '3600',
 *     access_token: this.jwtService.sign(payload),
 *     refresh_token: this.jwtService.sign(refreshPayload, { expiresIn: '7d' })
 *   };
 * }
 */
export class TokenResponseDto {
  /**
   * Token type specification
   *
   * Indicates the type of token returned, following OAuth 2.0 token types.
   * 'Bearer' is the most common type, allowing clients to present the token
   * in the Authorization header.
   *
   * Common values:
   * - 'Bearer': Standard bearer token (RFC 6750)
   * - 'Mac': Message Authentication Code token
   * - 'DPoP': Demonstration of Proof-of-Possession token
   *
   * @note Always use 'Bearer' unless you have specific security requirements
   *
   * @example "Bearer"
   */
  @ApiProperty({
    description: 'Type of token (e.g., Bearer)',
    example: 'Bearer',
    type: String,
    enum: ['Bearer', 'Mac', 'DPoP'],
    default: 'Bearer',
  })
  @IsString()
  token_type: string;

  /**
   * Access token lifetime in seconds
   *
   * Specifies the duration (in seconds) that the access token is valid.
   * Helps clients manage token refresh cycles and implement proper caching.
   *
   * Typical values:
   * - 3600: 1 hour (common for web applications)
   * - 86400: 24 hours (longer sessions)
   * - 300: 5 minutes (high security applications)
   *
   * Security considerations:
   * - Balance security vs. user convenience
   * - Consider shorter lifetimes for sensitive applications
   * - Use refresh tokens to maintain sessions without frequent logins
   *
   * @note Returned as string for JSON compatibility, but represents a number
   *
   * @example "3600"
   * @example "86400"
   */
  @ApiProperty({
    description: 'Duration of token validity in seconds',
    example: '3600',
    type: String,
  })
  @IsString()
  expires_in: string;

  /**
   * Access token (JWT)
   *
   * The primary authentication token used to access protected resources.
   * Typically a JSON Web Token (JWT) containing claims about the user.
   *
   * Token characteristics:
   * - Signed to prevent tampering
   * - Contains user claims (id, role, permissions)
   * - Has expiration timestamp
   * - Used in Authorization header: "Bearer {access_token}"
   *
   * Security best practices:
   * - Sign with strong algorithm (RS256/HS256)
   * - Keep payload minimal to reduce token size
   * - Include standard claims (iss, sub, aud, exp, iat)
   * - Never include sensitive data in token payload
   *
   * @example "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
   */
  @ApiProperty({
    description: 'Access token (JWT)',
    example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    type: String,
  })
  @IsString()
  access_token: string;

  /**
   * Refresh token
   *
   * Long-lived token used to obtain new access tokens without requiring
   * user credentials. Provides better security than long-lived access tokens.
   *
   * Refresh token characteristics:
   * - Longer lifetime than access token (days/weeks/months)
   * - Stored securely by client application
   * - Single-use or limited-use to prevent replay attacks
   * - Can be revoked for security reasons
   *
   * Security best practices:
   * - Store in secure, HTTP-only cookies for web apps
   * - Implement token rotation (new refresh token on each use)
   * - Track refresh token usage for anomaly detection
   * - Allow manual revocation by users
   *
   * @example "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
   */
  @ApiProperty({
    description: 'Refresh token for obtaining new access tokens',
    example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    type: String,
  })
  @IsString()
  refresh_token: string;
}
