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

#import "GMShareSDK.h"
#import <Weibo_SDK/WeiboSDK.h>
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import "TencentOpenAPI/QQApiInterfaceObject.h"
#import "WXApiObject.h"
#import "GMThirdPartyOauthManager.h"
#import "GMThirdPartyDefine.h"
#import "WeiboSDK.h"
#import <Photos/Photos.h>
#import "TencentOpenAPI/QQApiInterfaceObject.h"
#import <GMKit/UIImage+GM.h>
#import "UIImage+Compress.h"
#import "DouyinOpenSDKApi.h"
#import "UIAlertController+gm.h"
#import <WechatOpenSDK/WXApi.h>
#import "GMShareConstant.h"

@import SDWebImage;

@interface GMShareSDK ()
#warning TODO 待验证
//<WBMediaTransferProtocol>

@property (nonatomic, strong) WBMessageObject *messageObject;

@end

@implementation GMShareSDK

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

+ (BOOL)isClientInstalled:(GMSharePlatform)platformType{
    
    if (platformType == GMSharePlatformQQ ||
        platformType == GMSharePlatformQQSpace ||
        platformType == GMSharePlatformQQFriend) {
        return [QQApiInterface isQQInstalled] ? YES : NO;
    } else if (platformType == GMSharePlatformWechatTimeline ||
               platformType == GMSharePlatformWechatSession ||
               platformType == GMSharePlatformWechat) {
        return [WXApi isWXAppInstalled] ? YES : NO;
    } else if (platformType == GMSharePlatformSinaWeibo){
        return [WeiboSDK isWeiboAppInstalled] ? YES : NO;
    } else if (platformType == GMSharePlatformDouyin) {
        return [DouyinOpenSDKApi isAppInstalled];
    } else {
        return YES;
    }
}

#pragma mark - Image Utils
+ (UIImage *)compressImage:(UIImage *)image{
    // 图片下载成功后，分享到微信的图片不能太大
    if (image.size.width * image.size.height>  300 * 300) {
        CGFloat scale =  sqrt(300 * 300 / (image.size.width * image.size.height));
        image = [image resizedImageWithSize:CGSizeMake(image.size.width * scale, image.size.height * scale)];
    }
    return image;
}

#pragma mark - share parameters

- (void)share:(GMSharePlatform)platformType parameters:(NSMutableDictionary *)parameters onStateChanged:(GMSDKShareStateChangedHandler)stateChangedHandler{
    
    GMShareContentType contentType = (GMShareContentType)[parameters[ShareContentType] integerValue];
    if (contentType == GMShareContentTypeMiniProgram) {
        platformType = GMSharePlatformWechatMiniProgram;
    }
    switch (platformType) {
        case GMSharePlatformQQFriend:{
            if (parameters[ShareOnlyImage]) {
               [self shareImage:parameters[ShareImage] platform:platformType];
            } else {
               [self QQFriendShareWithParameters:parameters];
            }
            [self shareWithName:kQQShare onStateChanged:stateChangedHandler];
        }
            break;
        case GMSharePlatformQQSpace:{
            if (parameters[ShareOnlyImage]) {
               [self shareImage:parameters[ShareImage] platform:platformType];
            } else {
               [self QQSpaceShareWithParameters:parameters];
            }
            [self shareWithName:kQQShare onStateChanged:stateChangedHandler];
            break;
        }
        case GMSharePlatformWechatSession:{
            if (parameters[ShareOnlyImage]) {
               [self shareImage:parameters[ShareImage] platform:platformType];
            } else {
               [self wechatSessionShareWithParameters:parameters scene:WXSceneSession];
            }
            [self shareWithName:kWechatShare onStateChanged:stateChangedHandler];
            break;
        }
        case GMSharePlatformWechatTimeline:{
            if (parameters[ShareOnlyImage]) {
               [self shareImage:parameters[ShareImage] platform:platformType];
            } else {
               [self wechatSessionShareWithParameters:parameters scene:WXSceneTimeline];
            }
            [self shareWithName:kWechatShare onStateChanged:stateChangedHandler];
            break;
        }
        case GMSharePlatformWechatSessionSnapShot:
        case GMSharePlatformWechatTimelineSnapShot:
        case GMSharePlatformWechatMiniProgram:{
            [self wechatSessionShareWithParameters:parameters scene:WXSceneSession];
            [self shareWithName:kWechatShare onStateChanged:stateChangedHandler];
            break;
        }
        case GMSharePlatformSinaWeibo:{
            if (parameters[ShareOnlyImage]) {
               [[GMShareSDK shareInstance] shareImage:parameters[ShareImage] platform:platformType];
            } else {
               [self weiboShareWithParameters:parameters];
            }
            [self shareWithName:kSinaShare onStateChanged:stateChangedHandler];
            break;
        }
        case GMSharePlatformDouyin:{
            [self douYinShareWithParameters:parameters];
            [self shareWithName:kDouyinShare onStateChanged:stateChangedHandler];
            break;
        }

        default:
            break;
    }
}

- (void)shareWithName:(NSString *)name onStateChanged:(GMSDKShareStateChangedHandler)stateChangedHandler {
    __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:name object:nil queue: [NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        GMShareResponseState state = (GMShareResponseState )[note.userInfo[@"state"] integerValue];
        stateChangedHandler(state, nil);
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }];
}

/**
    只分享一张图片
 */
- (void)shareImage:(UIImage *)image platform:(GMSharePlatform)platformType {
    if (![GMShareSDK isClientInstalled:platformType]) {
        NSString *platfomName = [self getPlatformNameWithType:platformType];
        if (platfomName) {
            [UIAlertController showgm_OKAlertWithTitle:@"提示" message:[NSString stringWithFormat:@"未安装%@",platfomName] actionTitle:@"取消" actionHandler:^{}];
            return;
        }
    }
    switch (platformType) {
        case GMSharePlatformQQFriend: {
            [self QQFriendShareWithImage:image];
        }
            break;
        case GMSharePlatformQQSpace: {
            [self QZoneShareWithImage:image];
        }
            break;
            
        case GMSharePlatformWechatSession: {
            [self wechatImageShareWithParameters:@{ShareImage: image} scene:WXSceneSession];
        }
            break;
            
        case GMSharePlatformWechatTimeline:{
            [self wechatImageShareWithParameters:@{ShareImage: image} scene:WXSceneTimeline];
        }
            break;
            
        case GMSharePlatformSinaWeibo:{
            [self weiboShareWithParameters:@{ShareImage: image}];
        }
            break;
        default:
            break;
    }
}

#pragma mark -- QQShare

- (void)QQFriendShareWithImage:(UIImage *)image {
    NSData *imageData = UIImagePNGRepresentation(image);
    //如果图片大于10M 需要对图片压缩 不然分享不出去  微信qq  要求图片在10m 以内
    if (imageData.length > (10*1024*1024)) {
        imageData = UIImageJPEGRepresentation(image, 0.1);
    } else if (imageData.length > (1024*1024)) {
        imageData = UIImageJPEGRepresentation(image, 0.6);
    }
   
    QQApiImageObject *imgObj = [QQApiImageObject objectWithData:imageData previewImageData:nil title:@"更美app" description:@"我是图片"];
    SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:imgObj];
    imgObj.shareDestType = ShareDestTypeQQ;
    QQApiSendResultCode sent = [QQApiInterface sendReq:req];
    [self handleSendResult:sent];
}

/// QQ 空间分享图片
- (void)QZoneShareWithImage:(UIImage *)image {
    NSData *imageData = UIImagePNGRepresentation(image);
    //如果图片大于10M 需要对图片压缩 不然分享不出去  微信qq  要求图片在10m 以内
    if (imageData.length > (10*1024*1024)) {
        imageData = UIImageJPEGRepresentation(image, 0.1);
    } else if (imageData.length > (1024*1024)) {
        imageData = UIImageJPEGRepresentation(image, 0.6);
    }

    QQApiImageArrayForQZoneObject *imgObj = [[QQApiImageArrayForQZoneObject alloc] initWithImageArrayData:@[imageData] title:nil extMap:nil];
//    QQApiImageObject *imgObj = [QQApiImageObject objectWithData:imageData previewImageData:nil title:@"更美app" description:@"我是图片"];

    SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:imgObj];
    imgObj.shareDestType = ShareDestTypeQQ;

    QQApiSendResultCode sent = [QQApiInterface sendReq:req];
    [self handleSendResult:sent];
}

- (void)QQFriendShareWithParameters: (NSDictionary *)parameters {
    UIImage * thumbImage  = parameters[ShareImage]?:[UIImage imageNamed:@"icon"];
    
    NSURL* url = parameters[ShareUrl];
    NSString *title = parameters[ShareTitle];
    NSString *description = parameters[ShareText];
    
    QQApiNewsObject* img = [QQApiNewsObject objectWithURL:url title:title description:description previewImageData:UIImagePNGRepresentation(thumbImage)];
    SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:img];
    img.shareDestType = ShareDestTypeQQ;
    QQApiSendResultCode sent = [QQApiInterface sendReq:req];
    [self handleSendResult:sent];
}


- (void)QQSpaceShareWithParameters: (NSDictionary *)parameters {

    UIImage * previewImage = nil;
    id  images = parameters[ShareImage]?:[UIImage imageNamed:@"icon"];
    if ([images isKindOfClass:[NSArray class]]) {
        NSArray * tmp = (NSArray *)images;
        previewImage = tmp.firstObject;
    } else {
        previewImage = images;
    }
    NSURL* url = parameters[ShareUrl];
    NSString *title = parameters[ShareTitle];
    NSString *description = parameters[ShareText];
    NSData *data = UIImagePNGRepresentation(previewImage);
    QQApiNewsObject * imgObj = [QQApiNewsObject objectWithURL:url title:title description:description previewImageData:data];
    [imgObj setTitle:title ? : @""];
    [imgObj setCflag:kQQAPICtrlFlagQZoneShareOnStart]; //不要忘记设置这个flag
    SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:imgObj];
    QQApiSendResultCode sent = [QQApiInterface sendReq:req];
    [self handleSendResult:sent];
}


- (void)handleSendResult:(QQApiSendResultCode)sendResult{
    switch (sendResult)
    {
        case EQQAPIAPPNOTREGISTED:
        {
            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"App未注册" actionTitle:@"取消" actionHandler:^{
            }];
            break;
        }
        case EQQAPIMESSAGECONTENTINVALID:
        case EQQAPIMESSAGECONTENTNULL:
        case EQQAPIMESSAGETYPEINVALID:
        {
            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"发送参数错误" actionTitle:@"取消" actionHandler:^{
            }];
            break;
        }
        case EQQAPIQQNOTINSTALLED:
        {
//            UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"未安装手Q" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"未安装手Q" actionTitle:@"取消" actionHandler:^{
            }];
//            [msgbox show];
            NSLog(@"未安装手Q");
            [[NSNotificationCenter defaultCenter] postNotificationName:kQQShare object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
            break;
        }
        case EQQAPITIMNOTINSTALLED:
        {
//            UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"未安装TIM" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"未安装TIM" actionTitle:@"取消" actionHandler:^{
            }];
            break;
        }
        case EQQAPIQQNOTSUPPORTAPI:
        case EQQAPITIMNOTSUPPORTAPI:
        {

            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"API接口不支持" actionTitle:@"取消" actionHandler:^{
            }];
            break;
        }
        case EQQAPISENDFAILD:
        {
//            UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"发送失败" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
//            [msgbox show];
            NSLog(@"发送失败");
            [[NSNotificationCenter defaultCenter] postNotificationName:kQQShare object:nil userInfo:@{@"state": @(GMShareResponseStateFail)}];
            break;
        }
        case EQQAPIVERSIONNEEDUPDATE:
        {
//            UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"当前QQ版本太低，需要更新" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
//            [msgbox show];
            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"当前QQ版本太低，需要更新" actionTitle:@"取消" actionHandler:^{
            }];
            break;
        }
        case ETIMAPIVERSIONNEEDUPDATE:
        {
            [UIAlertController showgm_OKAlertWithTitle:@"Error" message:@"当前QQ版本太低，需要更新" actionTitle:@"取消" actionHandler:^{
            }];
            break;
        }
        default:
        {
            break;
        }
    }
}

#pragma mark -- WeiBoShare

- (void)weiboShareWithParameters: (NSDictionary *)parameters{
    _messageObject = [self manageWeiboMessageWithParameters:parameters];
    [self messageShare];
}

- (void)messageShare{
    WBAuthorizeRequest *authRequest = [WBAuthorizeRequest request];
    authRequest.redirectURI = SINAWEIBO_REDIRECTURI;
    authRequest.scope = @"all";
    WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:_messageObject authInfo:authRequest access_token:[GMThirdPartyOauthManager shareInstance].wbtoken];
    request.userInfo = @{@"flag": @"share"};
    [WeiboSDK sendRequest:request];
}

- (WBMessageObject *)manageWeiboMessageWithParameters: (NSDictionary *)parameters{
    UIImage * thumbImage  = parameters[ShareImage]?:[UIImage imageNamed:@"icon"];
    NSString *description = parameters[ShareText];
    WBMessageObject *message = [WBMessageObject message];
    message.text = description;
    WBImageObject *imageObject = [WBImageObject object];
//    imageObject.delegate = self;
    imageObject.imageData = UIImageJPEGRepresentation(thumbImage, 1);
    //这句话会crash
//    [imageObject addImages:@[,thumbImage]];
    message.imageObject = imageObject;
    return message;
}

- (void)wbsdk_TransferDidReceiveObject:(id)object{
    [self messageShare];
}



#pragma mark -- weChatShare

- (void)wechatSessionShareWithParameters: (NSDictionary *)parameters scene:(int)scene {
    GMShareContentType contentType = (GMShareContentType)[parameters[ShareContentType] integerValue];
    switch (contentType) {
        case GMShareContentTypeAuto: {
            NSURL* url = parameters[ShareUrl];
            if (url) {
                [self wechatLinkShareWith:parameters scene:scene];
            } else {
                [self wechatImageShareWithParameters:parameters scene:scene];
            }
        }
            break;
        case GMShareContentTypeImage:
        {
            [self wechatImageShareWithParameters:parameters scene:scene];
        }
            break;
        case GMShareContentTypeWebPage:
        {
            [self wechatLinkShareWith:parameters scene:scene];
        }
            break;
        case GMShareContentTypeMiniProgram:
        {
            [self wechatMiniProgramWithParameters:parameters scene:scene];
        }
            break;
        case GMShareContentTypeAudio:
        case GMShareContentTypeVideo:
        case GMShareContentTypeFile:
        case GMShareContentTypeFBMessageImages:
        case GMShareContentTypeFBMessageVideo:
        case GMShareContentTypeText:
            break;
        default:
            break;
    }
}

- (void)wechatMiniProgramWithParameters: (NSDictionary *)parameters scene:(int)scene {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        WXMiniProgramObject *wxMiniObject = [WXMiniProgramObject object];
        wxMiniObject.webpageUrl = parameters[ShareUrl];
        wxMiniObject.userName = parameters[ShareUserName];
        wxMiniObject.path = parameters[SharePath];
        // 压缩图片（不大于128K）
        UIImage *hdImage = parameters[ShareHdImageData]?:[UIImage imageNamed:@"share_smallProgram"];
        NSData * hdImageData = [UIImage compressImage:hdImage toByte:128 * 1024 size:CGSizeMake(300, 240)];
        wxMiniObject.hdImageData = hdImageData;
        WXMediaMessage *message = [WXMediaMessage message];
        message.title = parameters[ShareTitle];
        message.description = parameters[ShareDescription];
        message.mediaObject = wxMiniObject;
        
        UIImage *thumbImage = parameters[ShareThumbImage]?:[UIImage imageNamed:@"icon"];
        thumbImage = [UIImage imageWithData:[UIImage compressImage:thumbImage toByte:32 * 1024 size:CGSizeMake(150, 150)]];
        [message setThumbImage:thumbImage];
        SendMessageToWXReq * req = [[SendMessageToWXReq alloc]init];
        req.message = message;
        req.scene = scene;   
        // 转回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            [WXApi sendReq:req completion:^(BOOL success) {

            }];
        });
    });
}

- (void)wechatImageShareWithParameters: (NSDictionary *)parameters scene:(int)scene {
    UIImage * originlaImage = parameters[ShareImage]?:[UIImage imageNamed:@"icon"];
    WXImageObject *ext = [WXImageObject object];
    ext.imageData = UIImagePNGRepresentation(originlaImage);
    //如果图片大于10M 需要对图片压缩
    if (ext.imageData.length > (10*1024*1024)) {
        ext.imageData = UIImageJPEGRepresentation(originlaImage, 0.1);
    } else if (ext.imageData.length > (1024*1024)) {
        ext.imageData = UIImageJPEGRepresentation(originlaImage, 0.6);
    }
    WXMediaMessage *message = [WXMediaMessage message];
    message.mediaObject = ext;
    [message setThumbImage:[GMShareSDK compressImage:originlaImage]];
    SendMessageToWXReq *req = [self requestWithText:nil OrMediaMessage:message bText:NO InScene:scene];
    [WXApi sendReq:req completion:^(BOOL success) {
        
    }];
}

- (void)wechatLinkShareWith:(NSDictionary *)parameters scene:(int)scene{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        id image = parameters[ShareImage];
        UIImage * thumbImage  = image;
        NSURL* url = parameters[ShareUrl];
        NSString *title = parameters[ShareTitle];
        NSString *description = parameters[ShareText];
        
        WXWebpageObject *ext = [WXWebpageObject object];
        if ([url isKindOfClass:[NSURL class]]) {
            ext.webpageUrl = url.absoluteString;
        } else {
            ext.webpageUrl = url;
        }

        WXMediaMessage *message = [WXMediaMessage message];
        message.title = title;
        message.description = description;
        message.mediaObject = ext;
        
        [message setThumbImage:[UIImage imageWithData:[UIImage compressImage:thumbImage toByte:32 * 1024 size:CGSizeMake(150, 150)]]];
        SendMessageToWXReq* req =  [self requestWithText:nil OrMediaMessage:message bText:NO InScene:scene];
        // 转回到主线程
        dispatch_sync(dispatch_get_main_queue(), ^{
            [WXApi sendReq:req completion:^(BOOL success) {}];
        });
    });
}

- (SendMessageToWXReq *)requestWithText:(NSString *)text
                         OrMediaMessage:(WXMediaMessage *)message
                                  bText:(BOOL)bText
                                InScene:(enum WXScene)scene {
    SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
    req.bText = bText;
    req.scene = scene;
    if (bText)
        req.text = text;
    else
        req.message = message;
    return req;
}

#pragma mark -- douYin
- (void)douYinShareWithParameters:(NSDictionary *)parameters{
    DouyinOpenSDKShareReq *req = [DouyinOpenSDKShareReq new];
    req.mediaType = DouyinOpenSDKShareMediaTypeVideo;
    
    NSMutableArray *mediaUrl = [NSMutableArray array];
    NSURL *videoUrl = [NSURL new];
    if ([parameters.allKeys containsObject:ShareVideoUrl]) {
        videoUrl= parameters[ShareVideoUrl];
    }
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *req = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:videoUrl];
        NSString *localId = req.placeholderForCreatedAsset.localIdentifier;
        [mediaUrl addObject:localId];
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            dispatch_async(dispatch_get_main_queue(), ^{
                //                            [self sendShareReq];
                // 分享视频
                req.localIdentifiers = mediaUrl;
                BOOL success = [DouyinOpenSDKApi sendReq:req];
                if (success) {
                    NSLog(@"send share req success");
                } else {
                    NSLog(@"send share req failure");
                }
            });
        }
    }];
    ////     #话题，需要额外开通，视频中会有 #变脸挑战 的话题标签, 非必须属性
    //    req.hashtag = @"变脸挑战";
    //
    //    // 小程序，在分享的视频右下角显示抖音小程序入口, 非必须属性
    //    req.mpInfo = [DouyinOpenSDKMPInfo mpInfoWithIdentifier:@"you_mp_identifier" title:@"title" desc:@"desc" startPageURL:nil];
}

- (NSString *)getPlatformNameWithType:(GMSharePlatform)platformType {
    switch (platformType) {
        case GMSharePlatformSinaWeibo:
            return @"微博客户端";
        case GMSharePlatformQQSpace:
            return @"QQ客户端";
        case GMSharePlatformQQFriend:
            return @"QQ客户端";
        case GMSharePlatformWechatSession:
            return @"微信客户端";
        case GMSharePlatformWechatTimeline:
            return @"微信客户端";
        default:
            break;
    }
    return nil;
}

@end

