import { HttpService } from '@nestjs/axios';
import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { SettingService } from '../../setting/setting.service';
import { BaseOAuthProvider } from './abstract.provider';

@Injectable()
export class MicrosoftProvider
  extends BaseOAuthProvider  {

  constructor(
    http: HttpService,
    @Inject(forwardRef(() => SettingService))
    private readonly setting: SettingService,
  ) {
    super(http);
  }

  getProviderType() {
    return 'MICROSOFT';
  }

  async getAuthUrl(callbackPath: string) {

    const settings = await this.setting.getSettingValues([
      'microsoft_client_id',
      'microsoft_client_secret',
      'microsoft_scopes',
      'url',
    ]);

    const redirectURI = new URL(callbackPath, settings['url']).toString();
    const scopes = settings['microsoft_scopes']
    const params = new URLSearchParams({
      client_id: settings['microsoft_client_id'],
      redirect_uri: redirectURI,
      response_type: 'code',
      scope: scopes.join(' '),
      response_mode: 'query',
      prompt: 'consent',
    });

    return `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?${params}`;
  }

  async getProfile(code: string, type: string): Promise<any> {

    const settings = await this.setting.getSettingValues([
      'microsoft_client_id',
      'microsoft_client_secret',
      'microsoft_scopes',
      'url',
    ]);

    const token = await this.fetchToken({
      code,
      url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
      clientId: settings['microsoft_client_id'],
      clientSecret: settings['microsoft_client_secret'],
      redirectUri: `${settings['url']}/callback/microsoft/${type}`,
    });

    const profile = await this.fetchProfile(
      token.access_token,
      'https://graph.microsoft.com/v1.0/me',
    );

    const pictureUrl = 'https://graph.microsoft.com/v1.0/me/photo/$value';
    return {
      id: profile.id,
      email: profile.mail || profile.userPrincipalName,
      name: profile.displayName,
      picture: pictureUrl,
      oauth_tokens: {
        access_token: token.access_token,
        refresh_token: token.refresh_token,
        expires_in: token.expires_in,
        token_type: token.token_type,
      },
    };
  }
}
