//
//  GMDoctorVideoTelephoneLogin.m
//  Gengmei
//
//  Created by 卢悦明 on 2020/3/6.
//  Copyright © 2020 更美互动信息科技有限公司. All rights reserved.
//

#import "GMDoctorVideoTelephoneLogin.h"
#import "GMVideoTelephoneRequestTool.h"
#import "GMTelephoneAudioPlay.h"
#import "GMDoctorVideoTelephoneWindow.h"
#import "GMTelephoneView.h"
#import "GMEndConsultView.h"
#import "GMAppCameraAndMicrophone.h"
#import "GMVideoPhobos.h"
#import <GMBase/GMBaseTool.h>
#import "GMNimChannelManager.h"
#import <GMFoundation/NSString+GM.h>

@import GMHud;
@import GMRouter;

static GMDoctorVideoTelephoneLogin *loginManager = nil;

@interface GMDoctorVideoTelephoneLogin ()<GMTelephoneViewDelegate, TTTRtcEngineDelegate, GMVideoTelephoneWindowDelegate>

/// 用户id(更美的userId)
@property (nonatomic, assign) int64_t uid;
/// 聊天室房间id
@property (nonatomic, strong) NSString *channelId;
/// 角色
@property (nonatomic, assign) TTTRtcClientRole clientRole;
/// 推流地址
@property (nonatomic, strong) NSString *pushURL;
/// 扩展字段
@property (nonatomic, strong) NSDictionary *extensionDict;

/// 网易云信
@property (nonatomic, strong) GMNeteaseIMModel *neteaseModel;

@end

@implementation GMDoctorVideoTelephoneLogin
{
    GMRtcManager *TTManager;
    GMTelephoneAudioPlay *_audioPlay;
    GMTelephoneView *_telephoneView;//医生端接电话页面
    GMVideoTelephoneWindow *_window;
    
    GMVideoTelephoneModel *_videoModel;
    /// 加入房间重试次数，大于等于0，0代表不重试
    NSInteger _joinChannelRetryCount;

    /// 重试间隔，毫秒，大于等于0
    NSInteger _joinChannelRetryMs;

}

+ (GMDoctorVideoTelephoneLogin *)sharedDoctorVideoTelephoneLogin {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        loginManager = [[GMDoctorVideoTelephoneLogin alloc] init];
    });
    return loginManager;
}

#pragma mark - 副播
- (void)doctorEntryVideoRoom:(NSDictionary*)messageDict extension:(NSDictionary *)extentsionDict{
    TTManager = [GMRtcManager sharedRtcManager];

    if (TTManager.telephoneStatus != TelephoneVideoStatus_rest) {//此时有人呼入
        return;
    }
    [GMVideoPhobos video_monitoringWithActionStep:@"拉起呼叫页面" consultId:messageDict[@"consultation_record_id"] traceId:nil];
    [GMVideoPhobos channel_serviceWithRecordId:messageDict[@"consultation_record_id"] channel:[extentsionDict[@"channel"] integerValue] channelId:extentsionDict[@"channel_id"] serviceType:[extentsionDict[@"service_type"] integerValue]];

    _extensionDict = extentsionDict;
    _clientRole = TTTRtc_ClientRole_Broadcaster;
    TTManager.telephoneStatus = TelephoneVideoStatus_wating;
    _audioPlay = [[GMTelephoneAudioPlay alloc] initWithAudioSource:@"videoTelephone" ofType:@".mp3"];
    [GMVideoTelephoneRequestTool doctorVideoTelephoneMessage:messageDict finishBlock:^(BOOL success, NSDictionary *modelDict, NSString *errorMessage) {
        if (success) {
            [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
            if (_telephoneView == nil) {
                _videoModel = modelDict[@"model"];
                // 重试数据
                _joinChannelRetryMs = _videoModel.joinChannelRetryMs;
                _joinChannelRetryCount = _videoModel.joinChannelRetryCount;
                [self showTelephoneView:_videoModel];
                
                [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.GetRecordInfo" status:@"success" extraParam:@{@"consultation_record_id": SafeString(messageDict[@"consultation_record_id"]), @"referer": SafeString(extentsionDict[@"referer"])}];
            }
        } else {
            [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.GetRecordInfo" status:@"failed" extraParam:@{@"consultation_record_id": SafeString(messageDict[@"consultation_record_id"]), @"referer": SafeString(extentsionDict[@"referer"])}];
            
            TTManager.telephoneStatus = TelephoneVideoStatus_rest;
            [GMHudModule showWarning:errorMessage];
        }
    }];
}

#pragma mark - 主播
- (void)doctorCreatVideoRoom:(NSDictionary*)messageDict extension:(NSDictionary *)extentsionDict {
    TTManager = [GMRtcManager sharedRtcManager];
    if (TTManager.telephoneStatus != TelephoneVideoStatus_rest) {//此时有人呼入
        return;
    }
    TTManager.telephoneStatus = TelephoneVideoStatus_wating;
    _extensionDict = extentsionDict;
    _clientRole = TTTRtc_ClientRole_Anchor;
    GMVideoTelephoneModel *model = [[GMVideoTelephoneModel alloc] initWithDictionary:messageDict error:nil];
    [self doctorLoginVideoRoomModel:model];
}

#pragma mark - 初始化直播间
- (void)doctorLoginVideoRoomModel:(GMVideoTelephoneModel *)model {
    _uid = (NSInteger)[[GMRouter sharedInstance] pushScheme:@"gengmei://gm_userId"];;
    _channelId = model.channelId;
    _pushURL = model.streamUrl;
    _neteaseModel = model.neteaseIm;

    if (_channelId.integerValue == 0 || _channelId.length >= 19) {
        TTManager.telephoneStatus = TelephoneVideoStatus_rest;
        return;
    }
    [GMVideoPhobos video_monitoringWithActionStep:@"进入直播间" consultId:model.consultationRecordId traceId:nil];
    TTTRtcClientRole clientRole = _clientRole; //角色设置
    TTManager.me.clientRole = clientRole;
    TTManager.me.uid = _uid;
    TTManager.consultationRecordId = model.consultationRecordId;
    TTManager.vidoeTelephoneModel = model;
    TTManager.pushURL = _pushURL;
    TTManager.roomID = _channelId.longLongValue;
    TTManager.me.mutedSelf = false;
    TTTRtcEngineKit *rtcEngine = TTManager.rtcEngine;
    [TTManager beautyStatus:YES];//关闭美颜
    rtcEngine.delegate = self;
    [rtcEngine setChannelProfile:TTTRtc_ChannelProfile_LiveBroadcasting];
    [rtcEngine setClientRole:clientRole];
    [rtcEngine enableAudioVolumeIndication:200 smooth:3];

    if (_clientRole == TTTRtc_ClientRole_Anchor) {//主播推流
      TTTPublisherConfigurationBuilder *builder = [[TTTPublisherConfigurationBuilder alloc] init];
      //推流地址
      [builder setPublisherUrl:_pushURL];
      [rtcEngine configPublisher:builder.build];
    }
    [rtcEngine enableVideo];
    [rtcEngine muteLocalAudioStream:NO];
    BOOL swapWH = UIInterfaceOrientationIsPortrait(UIApplication.sharedApplication.statusBarOrientation);
    [rtcEngine setVideoProfile:TTTRtc_VideoProfile_720P swapWidthAndHeight:swapWH];
    [rtcEngine joinChannelByKey:nil channelName:_channelId uid:_uid joinSuccess:nil];
    [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.Santi.Join" status:@"success" extraParam:@{@"order_no": @"", @"consultation_record_id": SafeString(model.consultationRecordId), @"channel_id": SafeString(_channelId)}];

}

#pragma mark - 医生端展示电话页面
- (void)showTelephoneView:(GMVideoTelephoneModel *)model {
    [_audioPlay startAudioPlayAndVibration];
    _telephoneView = [[GMTelephoneView alloc] initWithFrame:CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_HEIGHT)];
    _telephoneView.model = model;
    _telephoneView.delegate = self;
    [[UIApplication sharedApplication].keyWindow addSubview:_telephoneView];

}

#pragma mark - 点击接受或是挂断
- (void)clickBtnType:(BOOL)status messageModel:(GMVideoTelephoneModel *)model {
    
    NSString *statusStr = status == 1 ? @"点击接听按钮":@"点击挂断按钮";
    [GMVideoPhobos video_monitoringWithActionStep:statusStr consultId:model.consultationRecordId traceId:nil];

    if (status) {
        [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.Accept.Click" status:@"success" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];
        if ([GMAppCameraAndMicrophone getAppCameraAction] == NO ||  [GMAppCameraAndMicrophone getAppMicrophoneAction] == NO) {
            //如果相机或是麦克风权限必须获取才能视频通话
            [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.NoRight" status:@"success" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];
            return;
        }

        [self killCurrentView];
        [GMVideoTelephoneRequestTool telephoneMessageEventType:GMEventType_jieTing consultationRecordId:model.consultationRecordId finishBlock:^(BOOL success, NSDictionary *message) {
            if (success) {
                [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.Accept" status:@"success" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];

                [self doctorLoginVideoRoomModel:model];
            } else {
                [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.Accept" status:@"failed" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];

                [GMHudModule showWarning:message[@"message"]];
                TTManager.telephoneStatus = TelephoneVideoStatus_rest;
            }
        }];
    } else {
        [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.Reject.Click" status:@"success" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];

        [self killCurrentView];
        TTManager.telephoneStatus = TelephoneVideoStatus_rest;
        
        [GMVideoTelephoneRequestTool telephoneMessageEventType:GMEventType_juJue consultationRecordId:model.consultationRecordId finishBlock:^(BOOL success, NSDictionary *message) {
            if (success) {
                [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.Reject.Click" status:@"success" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];
            } else {
                [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.Reject.Click" status:@"failed" extraParam:@{@"consultation_record_id": SafeString(model.consultationRecordId)}];
            }
                
            }];
        //医生点击取消挂断按钮
        [[NSNotificationCenter defaultCenter] postNotificationName:@"doctor_finshed_video" object:nil];
        [GMHudModule showWarning:@"已拒绝对方"];
    }
    
    NSString *button_name = status ? @"answer" : @"cancel";
    UIViewController *vc = [GMBaseTool getCurrentViewController].navigationController.viewControllers.lastObject;
    NSString *referrer = vc.pageName;
    [Phobos track:@"on_click_button" attributes:@{
        @"page_name":@"video_face_consultation_doctor",
        @"button_name":button_name,
        @"doctor_id": SafeString(model.counsellorInfo.doctorId),
        @"user_id":SafeString(model.userInfo.userId),
        @"referrer":SafeString(referrer)
    }];
}

- (void)killCurrentView {
    [_audioPlay stopAudioPlayAndVibration];
    _telephoneView.hidden = YES;
    [_telephoneView removeFromSuperview];
    _telephoneView = nil;
}

#pragma mark - 展示直播页面
- (void)showWindow:(TTTRtcClientRole)userType {
    TTManager.telephoneStatus = TelephoneVideoStatus_wating;
    //禁止自动休眠
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
    _window = [[GMDoctorVideoTelephoneWindow alloc]  initWithFrame:CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_HEIGHT)];
    _window.delgate = self;
    [[UIApplication sharedApplication].keyWindow addSubview:_window];

    [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.One2One.EvokeRecordPageSuceess" status:@"success" extraParam:@{@"consultation_record_id": SafeString(_videoModel.consultationRecordId)}];

}

#pragma mark - TTTRtcEngineDelegate初始化成功
-(void)rtcEngine:(TTTRtcEngineKit *)engine didJoinChannel:(NSString *)channel withUid:(int64_t)uid elapsed:(NSInteger)elapsed {
      // 加入房间并邀请
        if (_neteaseModel && [_neteaseModel.toAccountId isNonEmpty] && [_neteaseModel.channelId isNonEmpty]) {
            [[GMNimChannelManager shareInstance] doJoinAndInviteJoinChannelWithChannelId:_neteaseModel.channelId accountId:_neteaseModel.toAccountId customInfo:_neteaseModel.inviteExt resultBlock:^(BOOL isSuccess) {
                if (!isSuccess) {
                    [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.Dispatch.NeteaseIM.ReadySend" status:@"failed" extraParam:@{@"consultation_record_id": SafeString(TTManager.consultationRecordId), @"channel_id": SafeString(_channelId), @"user_id": SafeString(_neteaseModel.toAccountId)}];
    #ifdef DEBUG
                    [[GMBaseTool getCurrentViewController] toast:@"doJoinAndInviteJoinChannelWithChannelId失败"];
    #endif
                } else {
                    [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.Dispatch.NeteaseIM.ReadySend" status:@"success" extraParam:@{@"consultation_record_id": SafeString(TTManager.consultationRecordId), @"channel_id": SafeString(_channelId), @"user_id": SafeString(_neteaseModel.toAccountId)}];
                }
            }];
        }

    [GMVideoTelephoneRequestTool telephoneMessageEventType:GMEventType_addSuccess consultationRecordId:TTManager.consultationRecordId finishBlock:nil];
    [self showWindow:_clientRole];
}

#pragma mark -初始化错误
-(void)rtcEngine:(TTTRtcEngineKit *)engine didOccurError:(TTTRtcErrorCode)errorCode {
    NSString *errorInfo = @"";
    switch (errorCode) {
        case TTTRtc_Error_Enter_TimeOut:
            errorInfo = @"超时,10秒未收到服务器返回结果";
            break;
        case TTTRtc_Error_Enter_Failed:
            errorInfo = @"该直播间不存在";
            break;
        case TTTRtc_Error_Enter_BadVersion:
            errorInfo = @"版本错误";
            break;
        case TTTRtc_Error_InvalidChannelName:
            errorInfo = @"无效的房间";
            break;
        case TTTRtc_Error_Enter_NoAnchor:
//            errorInfo = @"房间内无主播";
            errorInfo = @"视频面诊接入失败";
            break;
        default:
            errorInfo = @"未知错误";
            break;
    }
    [self tryAgainIfFailedWithErrorInfo:errorInfo errorCode:errorCode];
}

- (void)tryAgainIfFailedWithErrorInfo:(NSString *)errorInfo errorCode:(TTTRtcErrorCode)errorCode {
    if (_clientRole == TTTRtc_ClientRole_Broadcaster && _joinChannelRetryCount > 0) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_joinChannelRetryMs / 1000.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self doctorLoginVideoRoomModel:_videoModel];
            _joinChannelRetryCount--;
        });
    } else {
        [GMVideoPhobos consultation_traceWithActionStep:@"Consultation.Santi.OnJoinError" status:@"failed" extraParam:@{@"consultation_record_id": SafeString(TTManager.consultationRecordId), @"channel_id": SafeString(_channelId), @"error_code": @(errorCode)}];
        [self uploadFailedRecordWithErrorInfo:errorInfo];
    }
}

- (void)uploadFailedRecordWithErrorInfo:(NSString *)errorInfo {
    TTManager.telephoneStatus = TelephoneVideoStatus_rest;
    [GMVideoTelephoneRequestTool telephoneMessageEventType:GMEventType_addFail consultationRecordId:TTManager.consultationRecordId finishBlock:nil];
    [GMHudModule showWarning:errorInfo];
    if (_telephoneView) {//关闭医生端接电话图层
        [_telephoneView removeFromSuperview];
        _telephoneView = nil;
        [_audioPlay stopAudioPlay];
    }
}


#pragma mark - 直播中
- (void)videoLiveIn {}

#pragma mark - 关闭直播间的回调
- (void)nomalExitRoom {
    //取消禁止自动休眠
    [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
    if (TTManager.telephoneStatus == TelephoneVideoStatus_rest) { //防止结束方法重复调用，导致套框
        return;
    }
    TTManager.telephoneStatus = TelephoneVideoStatus_rest;
    //如果接通时间为0，下面就不用走了
    if (TTManager.totalTime <= 0) {
        return;
    }
    GMEndConsultView *view = [[GMEndConsultView alloc] initWithType:TTManager.totalTime > 180 ? GMEndConsultViewTypeReport : GMEndConsultViewTypeDefault starNum:0];
    view.complaintType = GMComplaintTypeDoctor;
    view.recordId = TTManager.consultationRecordId;
    [[GMBaseTool getCurrentViewController].view addSubview:view];
    if (TTManager.totalTime > 180) {
       [[NSNotificationCenter defaultCenter] postNotificationName:@"doctor_finshed_video" object:nil];
    }
}
@end
