import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { NbAuthService } from '@nebular/auth';
import { Observable } from 'rxjs';
import { map, mergeMap, first } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { GoogleUserInfo, LoginTokenViewModel, RegisterViewModel } from '../entity/Auth';
import { PastoralDomainService } from './crudServices/pastoral-domain.service';
import { LoginUserService } from './login-user.service';
import { SessionService } from './session.service';

@Injectable({
  providedIn: 'root'
})
export class AuthService {


  constructor(
    private http: HttpClient,
    private sessionService: SessionService,
    private oAuthService: NbAuthService,
    protected router: Router,
    private pastoralDomainService: PastoralDomainService,
    private loginUserService: LoginUserService
  ) { }

  logout() {
    this.sessionService.loginUserToken = '';
    this.loginUserService.userAccess = {} as LoginTokenViewModel;
    this.pastoralDomainService.domains = [];
    this.oAuthService.getToken().pipe(first()).subscribe(result => {
      console.log('logoutToken', result);
      if (result.isValid() && result.getOwnerStrategyName()) {

        this.oAuthService.logout(result.getOwnerStrategyName()).pipe(first()).subscribe(result => {

          console.log('Logout Google', result);
        });
      }
    });
    this.router.navigate(['/']);
  }

  isAuthenticated(): Observable<LoginTokenViewModel> {
    if (this.loginUserService.userAccess) {
      if (this.loginUserService.userAccess.token && this.loginUserService.userAccess.tokenExpireTime > new Date()) {
        return Observable.of(this.loginUserService.userAccess);
      }
    } else if (this.sessionService.loginUserToken) {
      return this.loginWithToken(this.sessionService.loginUserToken).pipe(map(result => {
        if (!result) {
          this.sessionService.loginUserToken = "";
        } else {

          this.pastoralDomainService.initialize().pipe(first()).subscribe(result => {

          });
        }
        return result;
      }));;
    }
    return Observable.of(null);
  }
  isAuthenticatedOrRefreshToken(): Observable<LoginTokenViewModel> {

    // if (this.sessionService.loginUserToken) {
    //   return Observable.of(true);
    // }
    return Observable.of(null);
  }
  register(data: RegisterViewModel) {
    return this.post('auth/sign-up', data);
  }

  private headerObj = new HttpHeaders({ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36' })
  loginWithGoogleAccessToken(googleToken): Observable<LoginTokenViewModel> {

    return this.post('auth/oauth-login',
      {
        oAuthType: 'google',
        accessToken: googleToken
      } as RegisterViewModel,
    );

    // return this.http.get(`https://www.googleapis.com/oauth2/v2/userinfo?access_token=${googleToken}`, {
    //   headers: this.headerObj
    // })
    //   .pipe(
    //     map(googleUserInfo => { return googleUserInfo as GoogleUserInfo }),
    //     mergeMap(
    //       googleUserInfo => {
    //         if (!googleUserInfo.error) {

    //           return this.post('auth/sign-up',
    //             {
    //               email: googleUserInfo.email,
    //               fistName: googleUserInfo.given_name,
    //               lastName: googleUserInfo.family_name,
    //               avatarImage: googleUserInfo.picture
    //             } as RegisterViewModel,
    //           );
    //         }
    //         return Observable.of(null);
    //       }));

  }

  loginWithLineAccessToken(lineAccessToken) {


    this.http.post<LoginTokenViewModel>(
      'https://api.line.me/oauth2/v2.1/verify',
      JSON.stringify(
        {
          id: lineAccessToken,
          client_id: environment.LINE_CLIENT_ID
        }

      ),
      {
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }
      }
    ).pipe(first()).subscribe(result => {
      console.log('Line Profile', result);


    });


  }

  login(data: RegisterViewModel) {
    return this.post('auth/login', data);
  }

  requestPassword(data) {
    return this.post('auth/request-pass', data);

  }
  resetPassword(data) {
    return this.post('auth/reset-pass', data);
  }
  loginWithToken(token) {
    return this.post('auth/loginwithtoken', { token });
  }

  private post(url, data) {
    return this.http.post<LoginTokenViewModel>(
      url,
      JSON.stringify(data),
      {
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }
      }
    ).pipe(map(result => {
      if (result && result.token) {
        this.loginUserService.userAccess = result;
        this.sessionService.loginUserToken = result.token;
        this.sessionService.loginUserId = result.memberId;
      } else {
        this.loginUserService.userAccess = {} as LoginTokenViewModel;
      }
      return result;
    }));
  }
}
