import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { socialLoginConstant } from 'src/constants/auth';
import { catchError, lastValueFrom, map, of } from 'rxjs';

/**
 * GoogleService - Service for Google OAuth token validation
 *
 * This service handles verification of Google ID tokens by making
 * an API call to Google's tokeninfo endpoint. It validates that tokens
 * are genuine, not expired, and retrieves user information.
 *
 * Google token verification flow:
 * 1. Client obtains Google ID token via OAuth/OpenID Connect
 * 2. Server sends token to Google for validation
 * 3. Google returns token metadata and user claims
 * 4. Server processes validated user data
 *
 * @see https://developers.google.com/identity/sign-in/web/backend-auth
 *
 * @example
 * // Verify a Google ID token
 * const googleData = await googleService.tokenVerify(googleIdToken);
 * // Returns Google API response with user data
 */
@Injectable()
export class GoogleService {
  constructor(private readonly http: HttpService) {}

  /**
   * Validates a Google ID token via Google's tokeninfo endpoint
   *
   * Makes an HTTP GET request to Google's OAuth2 tokeninfo endpoint to:
   * - Verify token signature and validity
   * - Retrieve user claims (email, name, picture, etc.)
   * - Validate audience (client ID) and issuer
   * - Check token expiration
   *
   * @param token - Google ID token to validate
   * @returns Promise resolving to Google tokeninfo response data
   * @throws Error if the HTTP request fails or returns invalid data
   *
   * @note Consider using JWT library verification for better security
   * @note Tokeninfo endpoint is convenient but verify locally for production
   *
   * @example
   * const result = await this.googleService.tokenVerify('google_id_token');
   * // Result contains: { aud, sub, email, email_verified, name, picture, ... }
   */
  async tokenVerify(token: string) {
    // Construct the Google tokeninfo endpoint URL
    const googleTokenInfoUrl = `${socialLoginConstant.google_url}${token}`;

    // Make HTTP request to Google and process response
    return lastValueFrom(
      this.http.get(googleTokenInfoUrl).pipe(
        // Extract data from HTTP response
        map((response) => response.data),

        // Handle errors gracefully
        catchError((error) => {
          // Log the error for debugging (consider using proper logger)
          console.error('Google token verification failed:', error);

          // Return user-friendly error message
          // Note: Consider throwing an exception instead for better error propagation
          return of(`Alert: ${error.message}`);
        }),
      ),
    );
  }
}
