import { socialConfig } from '../../../config/social.config';
import { SocialProfile } from '../social.service';

/**
 * EN: Google OAuth 2.0 Provider
 * VI: Provider OAuth 2.0 của Google
 */

export class GoogleProvider {
  private readonly clientId = socialConfig.google.clientId;
  private readonly clientSecret = socialConfig.google.clientSecret;
  private readonly redirectUri = socialConfig.google.redirectUri;

  /**
   * EN: Get authorization URL
   * VI: Lấy URL xác thực
   */
  getAuthorizationUrl(state?: string): string {
    const params = new URLSearchParams({
      client_id: this.clientId!,
      redirect_uri: this.redirectUri,
      response_type: 'code',
      scope: 'openid email profile',
      access_type: 'offline',
      prompt: 'consent',
      ...(state && { state }),
    });

    return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
  }

  /**
   * EN: Get user profile from authorization code
   * VI: Lấy profile người dùng từ authorization code
   */
  async getProfile(code: string, redirectUri?: string): Promise<SocialProfile> {
    // Exchange code for access token
    const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: new URLSearchParams({
        code,
        client_id: this.clientId!,
        client_secret: this.clientSecret!,
        redirect_uri: redirectUri || this.redirectUri,
        grant_type: 'authorization_code',
      }),
    });

    if (!tokenResponse.ok) {
      throw new Error('Failed to exchange code for token');
    }

    const tokenData = await tokenResponse.json();
    const accessToken = tokenData.access_token;

    // Get user info
    const userResponse = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });

    if (!userResponse.ok) {
      throw new Error('Failed to get user info');
    }

    const userData = await userResponse.json();

    return {
      id: userData.id,
      email: userData.email,
      name: userData.name,
      avatar: userData.picture,
      username: userData.email.split('@')[0],
    };
  }
}
