//
//  GMThirdPartyOauthManager.m
//  Gengmei
//
//  Created by licong on 2017/8/2.
//  Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
//

#import "GMThirdPartyOauthManager.h"
#import "GMThirdPartyLoginHelper.h"
#import "GMShareSDK.h"
#import <GMFoundation/NSString+GM.h>
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import <WechatOpenSDK/WXApi.h>
#import <Weibo_SDK/WeiboSDK.h>
#import <DouyinOpenSDK/DouyinOpenSDKApi.h>
#import <AuthenticationServices/AuthenticationServices.h>


@interface GMThirdPartyOauthManager()<WBHttpRequestDelegate, DouyinOpenSDKLogDelegate, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding,TencentSessionDelegate, QQApiInterfaceDelegate, WXApiDelegate, WeiboSDKDelegate, DouyinOpenSDKApiDelegate>
@end
@implementation GMThirdPartyOauthManager

+ (instancetype)shareInstance
{
    static dispatch_once_t onceToken;
    static id instance = nil;
    dispatch_once(&onceToken, ^{
        instance = [[[self class] alloc] init];
    });
    return instance;
}

- (instancetype)init{
    if (self = [super init]) {
        _user =  [[GMThirdPartyUser alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:)
                                                     name:UIApplicationDidBecomeActiveNotification object:@{@"key":@"useForOauth"}];
    }
    return self;
}

- (void)applicationDidBecomeActive:(NSNotification *)noti {
    NSString *key = noti.object[@"key"];
    if (![_user.uid isNonEmpty] && [key isEqualToString:@"useForOauth"]){
        if (_user.platformType == GMSharePlatformQQ) {
            [[NSNotificationCenter defaultCenter] postNotificationName:kQQLogin object:nil userInfo:@{@"state": @(GMShareResponseStateBack)}];
        } else if (_user.platformType == GMSharePlatformSinaWeibo){
            [[NSNotificationCenter defaultCenter] postNotificationName:kSinaLogin object:nil userInfo:@{@"state": @(GMShareResponseStateBack)}];
        } else if (_user.platformType == GMSharePlatformWechat){
            [[NSNotificationCenter defaultCenter] postNotificationName:kWechatLogin object:nil userInfo:@{@"state": @(GMShareResponseStateBack)}];
        } else if (_user.platformType == GMSharePlatformApple){
            [[NSNotificationCenter defaultCenter] postNotificationName:kAppleLogin object:nil userInfo:@{@"state": @(GMShareResponseStateBack)}];
        }
    }
}
 
#pragma mark - WeiboSDKDelegate

- (void)didReceiveWeiboRequest:(WBBaseRequest *)request{}
    
//微博登陆、分享成功后的回调
- (void)didReceiveWeiboResponse:(WBBaseResponse *)response{
    NSString* accessToken = @"";
    NSString* userId = @"";
    if ([response isKindOfClass:WBSendMessageToWeiboResponse.class]){
        WBSendMessageToWeiboResponse* sendMessageToWeiboResponse = (WBSendMessageToWeiboResponse*)response;
        accessToken = [sendMessageToWeiboResponse.authResponse accessToken];
        userId = [sendMessageToWeiboResponse.authResponse userID];
        if ([response.userInfo[@"flag"] isEqualToString:@"authorize"]) {
            //sso登陆授权成功
            if (response.statusCode == WeiboSDKResponseStatusCodeSuccess){
                [self requstWeiBoUseInfoByAccessToken:accessToken userId:userId];
                if (response.requestUserInfo != nil) {
                    NSData *data = [NSJSONSerialization dataWithJSONObject:response.requestUserInfo options:NSJSONWritingPrettyPrinted error:NULL];
                    self.user.thirdDetail = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                }
            } else{
                NSLog(@"登陆授权失败");
                [[NSNotificationCenter defaultCenter] postNotificationName:kSinaLogin object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
            }
        } else if ([response.userInfo[@"flag"] isEqualToString:@"share"]){
            //sso微博分享成功
            if (response.statusCode == WeiboSDKResponseStatusCodeSuccess){
                [[NSNotificationCenter defaultCenter] postNotificationName:kSinaShare object:nil userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
            } else {
                [[NSNotificationCenter defaultCenter] postNotificationName:kSinaShare object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
            }
        }
        /*sso分享的时候response.requestUserInfo为nil，response.userInfo是有两个字段一个是预指的flag，另一个是startTime
        网页分享的时候response.userInfo为nil，response.requestUserInfo仅有一个字段，是预指的flag*/
        if ([response.requestUserInfo[@"flag"] isEqualToString:@"share"] && [accessToken isNonEmpty] && [userId isNonEmpty]){
            //网页微博分享成功
            if (response.statusCode == WeiboSDKResponseStatusCodeSuccess){
                [[NSNotificationCenter defaultCenter] postNotificationName:kSinaShare object:nil userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
            } else {
                [[NSNotificationCenter defaultCenter] postNotificationName:kSinaShare object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
            }
        }
    } else if ([response isKindOfClass:WBAuthorizeResponse.class]){
        //网页授权成功
        accessToken = [(WBAuthorizeResponse *)response accessToken];
        userId = [(WBAuthorizeResponse *)response userID];
        [self requstWeiBoUseInfoByAccessToken:accessToken userId:userId];
        if (response.requestUserInfo != nil) {
            NSData *data = [NSJSONSerialization dataWithJSONObject:response.requestUserInfo options:NSJSONWritingPrettyPrinted error:NULL];
            self.user.thirdDetail = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        }
    }
}

- (void)requstWeiBoUseInfoByAccessToken: (NSString *)accessToken userId: (NSString *)userId{
    //授权成功后获取用户信息
    NSDictionary * dic = @{};
    if ([accessToken isNonEmpty] && [userId isNonEmpty]) {
        dic = @{@"access_token": accessToken, @"uid": userId};
        //发送请求 获取各种数据 对应的URL和请求方式heepMethod是不同的 详细的参考微博开放平台
        [WBHttpRequest requestWithURL:@"https://api.weibo.com/2/users/show.json" httpMethod:@"GET" params:dic delegate:[GMThirdPartyOauthManager shareInstance] withTag:@"gengmei"];
    } else {
        [[NSNotificationCenter defaultCenter] postNotificationName:kSinaLogin object:nil userInfo:@{@"state": @(GMShareResponseStateCancel)}];
    }
}


//微博授权成功的回调
-(void)request:(WBHttpRequest *)request didFinishLoadingWithResult:(NSString *)result{
    NSData *data=[result dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSString *location = dic[@"location"];
    NSArray * array = [location componentsSeparatedByString:@" "];
    if (array.count == 1){
        _user.provice = array.firstObject;
    } else if(array.count == 2){
        _user.provice = array.firstObject;
        _user.city = array.lastObject;
    }
    _user.uid = [NSString stringWithFormat:@"%@",dic[@"id"]];
    _user.nickname = dic[@"screen_name"];
    _user.icon = dic[@"profile_image_url"];
    _user.platformType = GMSharePlatformSinaWeibo;
    [[NSNotificationCenter defaultCenter] postNotificationName:kSinaLogin object:_user userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
}


//微博授权失败的回调
- (void)request:(WBHttpRequest *)request didFailWithError:(NSError *)error{
    [[NSNotificationCenter defaultCenter] postNotificationName:kSinaLogin object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
}


#pragma mark -  TencentSessionDelegate

- (void)tencentDidLogin {
    if (![self.tencentOAuth.accessToken isNonEmpty]){
        NSArray* permissions = [NSArray arrayWithObjects:@"get_user_info",@"get_simple_userinfo", @"add_t", nil];
        [self.tencentOAuth reauthorizeWithPermissions:permissions];
    } else {
        [self.tencentOAuth getUserInfo];
    }
}


- (BOOL)tencentNeedPerformReAuth:(TencentOAuth *)tencentOAuth{
    return YES;
}

//点击返回的回调
- (void)tencentDidNotLogin:(BOOL)cancelled{
    [[NSNotificationCenter defaultCenter] postNotificationName:kQQLogin object:nil userInfo:@{@"state": @(GMShareResponseStateCancel)}];
}

- (void)tencentDidNotNetWork{
    [[NSNotificationCenter defaultCenter] postNotificationName:kQQLogin object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
}

- (BOOL)tencentNeedPerformIncrAuth:(TencentOAuth *)tencentOAuth withPermissions:(NSArray *)permissions{
    [tencentOAuth incrAuthWithPermissions:permissions];
    return NO;
}


- (void)getUserInfoResponse:(APIResponse *)response {
    if (response && response.retCode == URLREQUEST_SUCCEED) {
        _user.uid = self.tencentOAuth.getUserOpenID;
        _user.nickname = response.jsonResponse[@"nickname"];
        _user.icon = response.jsonResponse[@"figureurl_2"];
        _user.city = response.jsonResponse[@"city"];
        _user.provice = response.jsonResponse[@"province"];
        _user.platformType = GMSharePlatformQQ;
        _user.thirdDetail = response.message;
        [[NSNotificationCenter defaultCenter] postNotificationName:kQQLogin object:_user userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
    } else {
        [[NSNotificationCenter defaultCenter] postNotificationName:kQQLogin object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
    }
}


# pragma mark - WXApiDelegate
- (void)onResp:(BaseResp *)resp {
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回结果，实际支付结果需要去微信服务器端查询
        switch (resp.errCode) {
            case WXSuccess:
                [[NSNotificationCenter defaultCenter] postNotificationName:kWechatPaySuccess object:nil];
                break;
            default:
                [[NSNotificationCenter defaultCenter] postNotificationName:kWechatPayFail object:nil];
                break;
        }
    }else if([resp isKindOfClass:[SendAuthResp class]]){
        // 微信请求App提供内容，需要app提供内容后使用sendRsp返回
        SendAuthResp *authResp = (SendAuthResp *)resp;
        if (resp.errCode == 0) {
            [self requestWechatAccessTokenWithCode:authResp.code];
        } else if(resp.errCode == -2){
            [[NSNotificationCenter defaultCenter] postNotificationName:kWechatLogin object:_user userInfo:@{@"state": @(GMShareResponseStateCancel)}];
        } else {
            [[NSNotificationCenter defaultCenter] postNotificationName:kWechatLogin object:_user userInfo:@{@"state": @(GMShareResponseStateFail)}];
        }
    } else if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
        if (resp.errCode == 0) {
            [[NSNotificationCenter defaultCenter] postNotificationName:kWechatShare object:nil userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
        } else if(resp.errCode == -2){
            [[NSNotificationCenter defaultCenter] postNotificationName:kWechatShare object:nil userInfo:@{@"state": @(GMShareResponseStateCancel)}];
        }
    }
}

- (void)requestWechatAccessTokenWithCode:(NSString *)code {
    NSString *accessUrl = [NSString stringWithFormat:@"%@/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",WEICHAT_BASE_URL, WEIXIN_APPID, WEIXIN_SECRET, code];
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:accessUrl] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            NSString *refreshToken = responseObject[@"refresh_token"];
            if (refreshToken) {
                [self refreshAccessTokenByRefreshToken:refreshToken];
            } else {
                assert("获取accessToken出错");
            }
        } else {
            NSLog(@"获取accessToken出错");
        }
    }] resume];
}


//刷新access_token有效期
- (void)refreshAccessTokenByRefreshToken:(NSString *)refreshToken{
    NSString *refreshUrl = [NSString stringWithFormat:@"%@/oauth2/refresh_token?appid=%@&grant_type=refresh_token&refresh_token=%@",WEICHAT_BASE_URL, WEIXIN_APPID, refreshToken];
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:refreshUrl] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            NSString *accessToken = responseObject[@"access_token"];
            NSString *openId = responseObject[@"openid"];
            [[GMThirdPartyOauthManager shareInstance] requestWechatUserInfoByAccessToken:accessToken openId:openId];
        } else {
            NSLog(@"刷新access_token时出错，请重新授权");
        }
    }] resume];

}

- (void)requestWechatUserInfoByAccessToken:(NSString *)accessToken openId:(NSString *)openId{
    NSString *userUrlStr = [NSString stringWithFormat:@"%@/userinfo?access_token=%@&openid=%@", WEICHAT_BASE_URL, accessToken, openId];
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:userUrlStr] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.user.uid = responseObject[@"openid"];
                self.user.nickname = responseObject[@"nickname"];
                self.user.icon = responseObject[@"headimgurl"];
                self.user.city = responseObject[@"city"];
                self.user.provice = responseObject[@"province"];
                self.user.unionid = responseObject[@"unionid"];
                self.user.platformType = GMSharePlatformWechat;
                self.user.thirdDetail = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                [[NSNotificationCenter defaultCenter] postNotificationName:kWechatLogin object:_user userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
            });
        } else {
            [[NSNotificationCenter defaultCenter] postNotificationName:kWechatLogin object:_user userInfo:@{@"state": @(GMShareResponseStateFail)}];
        }
    }] resume];
}

#pragma 抖音
- (void)didReceiveResponse:(DouyinOpenSDKBaseResp *)resp {
    if ([resp isKindOfClass:[DouyinOpenSDKShareResp class]]) { // 是分享的回调
        DouyinOpenSDKShareResp *shareResp = (DouyinOpenSDKShareResp *)resp;
        if (shareResp.errCode == 0) {
            [[NSNotificationCenter defaultCenter] postNotificationName:kDouyinShare object:nil userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
        } else {
            //handle the error
            [[NSNotificationCenter defaultCenter] postNotificationName:kDouyinShare object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
        }
    }
}

#pragma mark - Apple delegate
//@optional 授权成功地回调
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)){
    if (@available(iOS 13.0, *)) {
        if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
            // 用户登录使用ASAuthorizationAppleIDCredential
            ASAuthorizationAppleIDCredential *appleIDCredential = (ASAuthorizationAppleIDCredential *)authorization.credential;
            NSString *user = appleIDCredential.user;
            // 使用过授权的，可能获取不到以下三个参数
            NSString *fimilyName = appleIDCredential.fullName.familyName ?: @"";
            NSString *givenName = appleIDCredential.fullName.givenName ?: @"";
            
            NSData *identityToken = appleIDCredential.identityToken;
            NSData *authorizationCode = appleIDCredential.authorizationCode;
            
            _user.uid = appleIDCredential.user;
            _user.nickname = [fimilyName stringByAppendingString:givenName];
            _user.email = appleIDCredential.email;
            _user.thirdDetail = [[NSString alloc] initWithData:identityToken encoding:NSUTF8StringEncoding];
            _user.authorizationCode = [[NSString alloc] initWithData:authorizationCode encoding:NSUTF8StringEncoding];
            _user.platformType = GMSharePlatformApple;
            [[NSNotificationCenter defaultCenter] postNotificationName:kAppleLogin object:_user userInfo:@{@"state": @(GMShareResponseStateSuccess)}];
        } else {
            [[NSNotificationCenter defaultCenter] postNotificationName:kAppleLogin object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
        }
    } else {
        [[NSNotificationCenter defaultCenter] postNotificationName:kAppleLogin object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
    }
}

// 授权失败的回调
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)){
    [[NSNotificationCenter defaultCenter] postNotificationName:kAppleLogin object:nil userInfo:@{@"state": @(error.code == ASAuthorizationErrorCanceled ? GMShareResponseStateCancel : GMShareResponseStateFail)}];
}

// 告诉代理应该在哪个window 展示内容给用户
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)){
    // 返回window
    return [UIApplication sharedApplication].windows.lastObject;
}

- (void)onLog:(NSString *)log {
    NSLog(@"%@",log);
}
@end
