package com.artfess.base.huawei.message.demo;

import lombok.extern.slf4j.Slf4j;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 呼叫事件通知/话单通知
 * 客户平台收到RTC业务平台的呼叫事件通知/话单通知的接口通知
 */
@Slf4j
public class HostingVoiceEventDemoImpl {

    /**
     * 呼叫事件 for 语音回呼/语音通知/语音验证码
     * 
     * @param jsonBody
     * @breif 详细内容以接口文档为准
     */
    public static void onCallEvent(String jsonBody) {
        // 封装JOSN请求
        JSONObject json = JSON.parseObject(jsonBody);
        String eventType = json.getString("eventType"); // 通知事件类型
        
        if ("fee".equalsIgnoreCase(eventType)) {
            log.info("EventType error: " + eventType);
            return;
        }

        if (!(json.containsKey("statusInfo"))) {
            log.info("param error: no statusInfo.");
            return;
        }
        JSONObject statusInfo = json.getJSONObject("statusInfo"); // 呼叫状态事件信息
        
        log.info("eventType: " + eventType); // 打印通知事件类型

        //callout：呼出事件
        if ("callout".equalsIgnoreCase(eventType)) {
            /**
             * Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
             *
             * 'timestamp': 该呼叫事件发生时RTC业务平台的UNIX时间戳
             * 'userData': 用户附属信息
             * 'sessionId': 通话链路的标识ID
             * 'caller': 主叫号码
             * 'called': 被叫号码
             */
            if (statusInfo.containsKey("sessionId")) {
                log.info("sessionId: " + statusInfo.getString("sessionId"));
            }
            return;
        }
        //alerting：振铃事件
        if ("alerting".equalsIgnoreCase(eventType)) {
            /**
             * Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
             *
             * 'timestamp': 该呼叫事件发生时RTC业务平台的UNIX时间戳
             * 'userData': 用户附属信息
             * 'sessionId': 通话链路的标识ID
             * 'caller': 主叫号码
             * 'called': 被叫号码
             */
            if (statusInfo.containsKey("sessionId")) {
                log.info("sessionId: " + statusInfo.getString("sessionId"));
            }
            return;
        }
        //answer：应答事件
        if ("answer".equalsIgnoreCase(eventType)) {
            /**
             * Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
             *
             * 'timestamp': 该呼叫事件发生时RTC业务平台的UNIX时间戳
             * 'userData': 用户附属信息
             * 'sessionId': 通话链路的标识ID
             * 'caller': 主叫号码
             * 'called': 被叫号码
             */
            if (statusInfo.containsKey("sessionId")) {
                log.info("sessionId: " + statusInfo.getString("sessionId"));
            }
            return;
        }
        //collectInfo：放音收号结果事件,仅应用于语音通知场景
        if ("collectInfo".equalsIgnoreCase(eventType)) {
            /**
             * Example: 此处以解析digitInfo为例,请按需解析所需参数并自行实现相关处理
             *
             * 'timestamp': 该呼叫事件发生时RTC业务平台的UNIX时间戳
             * 'sessionId': 通话链路的标识ID
             * 'digitInfo': 放音收号场景中,RTC业务平台对开发者进行放音收号操作的结果描述
             */
            if (statusInfo.containsKey("digitInfo")) {
                log.info("digitInfo: " + statusInfo.getString("digitInfo"));
            }
            return;
        }
        //disconnect：挂机事件
        if ("disconnect".equalsIgnoreCase(eventType)) {
            /**
             * Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
             *
             * 'timestamp': 该呼叫事件发生时RTC业务平台的UNIX时间戳
             * 'userData': 用户附属信息
             * 'sessionId': 通话链路的标识ID
             * 'caller': 主叫号码
             * 'called': 被叫号码
             * 'partyType': 挂机的用户类型,仅在语音回呼场景携带
             * 'stateCode': 通话挂机的原因值
             * 'stateDesc': 通话挂机的原因值的描述
             */
            if (statusInfo.containsKey("sessionId")) {
                log.info("sessionId: " + statusInfo.getString("sessionId"));
            }
            return;
        }
    }

    /**
     * 话单通知 for 语音回呼/语音通知/语音验证码
     * 
     * @param jsonBody
     * @breif 详细内容以接口文档为准
     */
    public static void onFeeEvent(String jsonBody) {
        // 封装JSON请求
        JSONObject json = JSON.parseObject(jsonBody);
        String eventType = json.getString("eventType"); // 通知事件类型
        
        if (!("fee".equalsIgnoreCase(eventType))) {
            log.info("EventType error: " + eventType);
            return;
        }

        if (!(json.containsKey("feeLst"))) {
            log.info("param error: no feeLst.");
            return;
        }
        JSONArray feeLst = json.getJSONArray("feeLst"); // 呼叫话单事件信息
        /**
         * Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
         *
         * 'direction': 通话的呼叫方向,以RTC业务平台为基准
         * 'spId': 客户的云服务账号
         * 'appKey': 应用的app_key
         * 'icid': 呼叫记录的唯一标识
         * 'bindNum': 发起此次呼叫的CallEnabler业务号码
         * 'sessionId': 通话链路的唯一标识
         * 'callerNum': 主叫号码
         * 'calleeNum': 被叫号码
         * 'fwdDisplayNum': 转接呼叫时的显示号码(仅语音回呼场景携带)
         * 'fwdDstNum': 转接呼叫时的转接号码(仅语音回呼场景携带)
         * 'fwdStartTime': 转接呼叫操作的开始时间(仅语音回呼场景携带)
         * 'fwdAlertingTime': 转接呼叫操作后的振铃时间(仅语音回呼场景携带)
         * 'fwdAnswerTime': 转接呼叫操作后的应答时间(仅语音回呼场景携带)
         * 'callEndTime': 呼叫结束时间
         * 'fwdUnaswRsn': 转接呼叫操作失败的Q850原因值
         * 'failTime': 呼入,呼出的失败时间
         * 'ulFailReason': 通话失败的拆线点
         * 'sipStatusCode': 呼入,呼出的失败SIP状态码
         * 'callOutStartTime': Initcall的呼出开始时间
         * 'callOutAlertingTime': Initcall的呼出振铃时间
         * 'callOutAnswerTime': Initcall的呼出应答时间
         * 'callOutUnaswRsn': Initcall的呼出失败的Q850原因值
         * 'dynIVRStartTime': 自定义动态IVR开始时间(仅语音通知场景携带)
         * 'dynIVRPath': 自定义动态IVR按键路径(仅语音通知场景携带)
         * 'recordFlag': 录音标识
         * 'recordStartTime': 录音开始时间(仅语音回呼场景携带)
         * 'recordObjectName': 录音文件名(仅语音回呼场景携带)
         * 'recordBucketName': 录音文件所在的目录名(仅语音回呼场景携带)
         * 'recordDomain': 存放录音文件的域名(仅语音回呼场景携带)
         * 'recordFileDownloadUrl': 录音文件下载地址(仅语音回呼场景携带)
         * 'ttsPlayTimes': 应用TTS功能时,使用TTS的总次数
         * 'ttsTransDuration': 应用TTS功能时,TTS Server进行TTS转换的总时长(单位为秒)
         * 'serviceType': 携带呼叫的业务类型信息
         * 'hostName': 话单生成的服务器设备对应的主机名
         * 'userData': 用户附属信息
         */
        //短时间内有多个通话结束时RTC业务平台会将话单合并推送,每条消息最多携带50个话单
        if (feeLst.size() > 1) {
            for (Object loop : feeLst) {
                if (((JSONObject)loop).containsKey("sessionId")) {
                    log.info("sessionId: " + ((JSONObject)loop).getString("sessionId"));
                }
            }
        } else if (feeLst.size() == 1) {
            if (feeLst.getJSONObject(0).containsKey("sessionId")) {
                log.info("sessionId: " + feeLst.getJSONObject(0).getString("sessionId"));
            }
        } else {
            log.info("feeLst error: no element.");
        }
    }
}