package com.yeejoin.amos.boot.module.tzs.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.enums.DictTypeEnum;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.tzs.api.dto.CtiUserDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.TzsCitInfo;
import com.yeejoin.amos.boot.module.tzs.api.service.ICtiService;
import com.yeejoin.amos.boot.module.tzs.biz.utils.HttpUtils;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
 * 联通cti 服务实现类
 *
 * @author kongfm
 * @date 2021-08-25
 */
@Service
public class CtiServiceImpl implements ICtiService {

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    TzsCitInfoServiceImpl ctiInfoService;

    @Autowired
    DataDictionaryServiceImpl dictionaryService;

    /**
     * token 过期时间， cti 系统为7200 ，tzs 系统小于7200 防止获取到无效token
     */
    private long time = 6000l;

    @Value("${tzs.cti.appkey}")
    private String APP_KEY;

    @Value("${tzs.cti.secretkey}")
    private String SECRET_KEY;

    @Value("${tzs.cti.url}")
    private String ctiUrl;

    @Override
    public String getAccessToken() {
        if(redisUtils.hasKey(RedisKey.CTI_TOKEN)){
            Object obj= redisUtils.get(RedisKey.CTI_TOKEN);
            return obj.toString();
        } else {
            String tokenAccessUrl = ctiUrl+ "/openauth/getAccessToken";
            Map<String,Object> params = new HashMap<>();
            params.put("appKey",APP_KEY);
            String randomStr = System.currentTimeMillis() + "";
            params.put("randomStr",randomStr);
            String signStr = APP_KEY+randomStr+SECRET_KEY;
            String sign = encrypt32(signStr).toLowerCase();
            params.put("sign",sign);
            String responseStr = HttpUtils.doPost(tokenAccessUrl,params);
            JSONObject response = null;
            try {
                response = JSONObject.parseObject(responseStr);
            } catch (Exception e) {
                throw  new BadRequest("获取token 出错：" + e.getMessage());
            }
            if(response.getInteger("code") == 0) { // 获取token 成功
                try {
                    String token = response.getJSONObject("data").getString("accessToken");
                    redisUtils.set(RedisKey.CTI_TOKEN, token,time);
                    return token;
                } catch (Exception e) {
                    throw  new BadRequest("获取token 出错：" + e.getMessage());
                }
            } else {
                throw  new BadRequest("获取token 出错：" + response.getString("msg"));
            }
        }
    }

    @Override
    public JSONObject getLoginInfo() {
        String token = this.getAccessToken();
        // gid code extphone 根据用户获取
        AgencyUserModel me = Privilege.agencyUserClient.getme().getResult();
        LambdaQueryWrapper<TzsCitInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TzsCitInfo::getCtiUserId,me.getUserId());
        TzsCitInfo citInfo = ctiInfoService.getOne(wrapper);
        if(ValidationUtil.isEmpty(citInfo)){
            return null;
        }
        String gid = citInfo.getGid();
        String code = citInfo.getCode();
        String extphone = citInfo.getExtphone();
        String loginUrl = ctiUrl + "/cti/login" + "?accessToken=" + token;
        Map<String,Object> params = new HashMap<>();
        params.put("accessToken",token);
        params.put("gid",gid);
        params.put("code",code);
        params.put("extphone",extphone);
        String responseStr = HttpUtils.doPost(loginUrl,params);
        JSONObject response = null;
        try {
            response = JSONObject.parseObject(responseStr);
        } catch (Exception e) {
            throw  new BadRequest("登陆出错：" + e.getMessage());
        }
        if(response.getInteger("code") == 0) { // 登陆成功
            try {
                JSONObject loginData = response.getJSONObject("loginData");
                return loginData;
            } catch (Exception e) {
                throw  new BadRequest("获取loginData 出错：" + e.getMessage());
            }
        } else { //登陆失败
            throw  new BadRequest("登陆失败出错：" + response.getString("message"));
        }
    }

    /**
     * 获取坐席登录情况
     * @return
     */
    @Override
    public Map<Object, Object> getUserStatus(){
        Map<Object, Object> map = new HashMap<>();
        String token = this.getAccessToken();
        Map<String,Object> params = new HashMap<>();
        params.put("accessToken",token);
        String loginUrl = ctiUrl + "/cti/getagentinfomonitor" + "?accessToken=" + token;
        String responseStr = HttpUtils.doPost(loginUrl,params);
        JSONObject response = null;
        try {
            response = JSONObject.parseObject(responseStr);
        } catch (Exception e) {
            throw  new BadRequest("获取登录状态出错：" + e.getMessage());
        }
        JSONArray jsonArray = response.getJSONArray("rows");
        if(ValidationUtil.isEmpty(jsonArray)){
            return map;
        }
        for (Object object : jsonArray) {
            JSONObject jsonObject = JSON.parseObject(String.valueOf(object));
            map.put(jsonObject.get("code"),jsonObject.get("state"));
        }
        return map;
    }

    @Override
    public JSONArray getCallInfo(String serviceconnectionid) {
        String token = this.getAccessToken();
        String url = ctiUrl + "/onOpenAuth/cti/openApi/queryservicelist1";
        JSONObject params = new JSONObject();
        params.put("serviceconnectionid",serviceconnectionid);
        Map<String,String> header = new HashMap<>();
        header.put("accessToken",token);
        String responseStr = HttpUtils.doPostWithHeader(url,params.toJSONString(),header);

        JSONObject response = null;
        try {
            response = JSONObject.parseObject(responseStr);
        } catch (Exception e) {
            throw  new BadRequest("获取话单出错：" + e.getMessage());
        }
        if(response.getInteger("code") == 0) { // 登陆成功
            try {
                JSONArray loginData = response.getJSONArray("data");
                return loginData;
            } catch (Exception e) {
                throw  new BadRequest("获取话单出错: " + e.getMessage());
            }
        } else { //登陆失败
            throw  new BadRequest("获取话单出错：" + response.getString("msg"));
        }
    }

    @Override
    public Map<String, String> downLoadRecordFile(String connectionid) {
        String token = this.getAccessToken();
        String url = ctiUrl + "/onOpenAuth/cti/openApi/downloadvoice";
        JSONObject params = new JSONObject();
        params.put("connectionid",connectionid);
        Map<String,String> header = new HashMap<>();
        header.put("accessToken",token);
        byte[] bytes = HttpUtils.doPostWithHeaderDownload(url,params.toJSONString(),header);
        if(bytes == null || bytes.length == 0) {
            throw  new BadRequest("获取录音失败");
        } else {
            MultipartFile file = new MockMultipartFile("录音.MP3","录音.MP3","application/octet-stream" ,bytes);
            FeignClientResult<Map<String, String>> result =  Systemctl.fileStorageClient.updateCommonFile(file);
            Map<String, String> map = result.getResult();
            return map;
        }
    }


    /**
     * 获取MD加密串
     * @param encryptStr
     * @return
     */
    private String encrypt32(String encryptStr) {
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] md5Bytes = md5.digest(encryptStr.getBytes());
            StringBuffer hexValue = new StringBuffer();
            for (int i = 0; i < md5Bytes.length; i++) {
                int val = ((int) md5Bytes[i]) & 0xff;
                if (val < 16)
                    hexValue.append("0");
                hexValue.append(Integer.toHexString(val));
            }
            encryptStr = hexValue.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return encryptStr;
    }

    @Override
    public CtiUserDto getCallPhone(String userId) {
        CtiUserDto ctiUserDto = new CtiUserDto();
        if (ValidationUtil.isEmpty(userId)) {
            return ctiUserDto;
        }
        LambdaQueryWrapper<TzsCitInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TzsCitInfo::getCtiUserId, userId);
        TzsCitInfo ctiInfo = ctiInfoService.getOne(wrapper);
        if (!ValidationUtil.isEmpty(ctiInfo)) {
            String groupCode = ctiInfo.getGid().split(",")[0];
            DataDictionary dataDictionary = dictionaryService.getByCode(groupCode, DictTypeEnum.坐席技能组.getType());
            ctiUserDto.setCallerNo(dataDictionary.getName());
        }
        return ctiUserDto;
    }
}