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 FacebookProvider
  extends BaseOAuthProvider {

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

  getProviderType() {
    return 'FACEBOOK';
  }

  async getAuthUrl(callbackPath: string) {
    const settings = await this.setting.getSettingValues([
      'facebook_client_id',
      'facebook_client_secret',
      'facebook_scopes',
      'url',
    ]);

    const redirectURI = new URL(callbackPath, settings['url']).toString();

    const params = new URLSearchParams({
      client_id: settings['facebook_client_id'],
      redirect_uri: redirectURI,
      response_type: 'code',
      scope: (settings['facebook_scopes'] ?? ['email']).join(','),
      auth_type: 'rerequest',
    });

    return `https://www.facebook.com/v17.0/dialog/oauth?${params}`;
  }

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

    const settings = await this.setting.getSettingValues([
      'facebook_client_id',
      'facebook_client_secret',
      'facebook_scopes',
      'url',
    ]);

    const token = await this.fetchToken({
      code,
      url: 'https://graph.facebook.com/v17.0/oauth/access_token',
      clientId: settings['facebook_client_id'],
      clientSecret: settings['facebook_client_secret'],
      redirectUri: `${settings['url']}/oauth/facebook/callback/${type}`,
    });
    const profile = await this.fetchProfile(
      token.access_token,
      'https://graph.facebook.com/me?fields=id,name,email,gender,birthday,picture',
    );
    return {
      ...profile,
      oauth_tokens: {
        access_token: token.access_token,
        refresh_token: token.refresh_token,
        expires_in: token.expires_in,
        token_type: token.token_type,
      },
    };
  }
}
