package com.goafanti.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.goafanti.admin.bo.CallDaysSumBo;
import com.goafanti.common.bo.Error;
import com.goafanti.common.bo.InputCallCompleter;
import com.goafanti.common.bo.Result;
import com.goafanti.common.dao.*;
import com.goafanti.common.model.*;
import com.goafanti.common.utils.DateUtils;
import com.goafanti.common.utils.HttpUtils;
import com.goafanti.common.utils.LoggerUtils;
import com.goafanti.common.utils.StringUtils;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.websocket.SystemWebSocketHandler;
import com.goafanti.customer.bo.InputCallNumber;
import com.goafanti.customer.bo.InputUserCallList;
import com.goafanti.customer.service.UserOutboundService;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.socket.TextMessage;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserOutboundServiceImpl extends BaseMybatisDao<CallLogMapper> implements UserOutboundService {
    @Value(value = "${zbtx.customer}")
    private final String	 customer=null;
    @Value(value = "${zbtx.seq}")
    private final String	 seq=null;
    @Value(value = "${zbtx.pwd}")
    private final String	 pwd=null;
    @Value(value = "${zbtx.version}")
    private final String	 version=null;
    private final String	 default_url ="https://webmc.zb-sx.cn:1443";



    @Resource
    private SystemWebSocketHandler systemWebSocketHandler;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserMidMapper userMidMapper;
    @Resource
    private AdminMapper adminMapper;
    @Resource
    private OrganizationContactBookMapper organizationContactBookMapper;
    @Resource
    private CallLogMapper callLogMapper;
    @Resource
    private AdminCallDayMapper adminCallDayMapper;
    @Resource
    private SalesTeamMapper salesTeamMapper;

    @Override
    public Object checkUser(Integer type) {
        String url= default_url +"/openapi/"+version+"/getClientInfo";
        Map<String,Object> param=new HashMap<>();
        param.put("authentication",getAuthentication());
        Map<String,Object> request=new HashMap<>();
        request.put("type",type);
        param.put("request",request);
        HttpUtils httpUtils=new HttpUtils();
        String s = httpUtils.sendHttpsRequest(url, "POST", param);
        System.out.println(s);
        return null;
    }

    private Map<String, Object> getAuthentication() {
        Map<String,Object> authentication=new HashMap<>();
        authentication.put("customer",customer);
        long timeMillis = System.currentTimeMillis();
        authentication.put("timestamp",timeMillis);
        authentication.put("seq",seq);
        String digestSource=customer+"@"+timeMillis+"@"+seq+"@"+pwd;
//        System.out.println("digestSource="+digestSource);
        String md5 = new SimpleHash("MD5", digestSource).toHex();
//        System.out.println("md5="+md5);
        authentication.put("digest",md5);
        return authentication;
    }

    @Override
    public Result pushCallNumber(InputCallNumber in) {
        String msg =null;
        if (StringUtils.isNotBlank(in.getUid())){
            User u =userMapper.queryById(in.getUid());
            if (u.getCallStatus()==1){
                return new Result().error(new Error("该用户正在通话中"));
            }
        }
        String url= default_url +"/openapi/"+version+"/callNumber";
        Map<String,Object> param=new HashMap<>();
        param.put("authentication",getAuthentication());
        Map<String,Object> request=new HashMap<>();
        request.put("agent",in.getAgent());
        request.put("callee",in.getCallee());
        request.put("userData",in.getUid());
        param.put("request",request);
        HttpUtils httpUtils=new HttpUtils();
        String s = httpUtils.sendHttpsRequest(url, "POST", param);
        System.out.println("url="+url);
        System.out.println("param="+param);
        System.out.println(s);
//        {"result":{"error":"0xF1000022","msg":"分机号未注册"},"data":{"seq":"20241101","response":{"seq":null,"userData":null,"result":{"error":4043309090},"data":null}}}
        JSONObject jsonObject = JSON.parseObject(s);
        JSONObject result = jsonObject.getJSONObject("result");
        msg = result.getString("msg");
        if (StringUtils.isNotBlank(msg)){
            if (msg.equals("成功")){
                if (StringUtils.isNotBlank(in.getUid())){
                    User u =new User();
                    u.setId(in.getUid());
                    u.setCallStatus(1);
                    userMapper.update(u);
                }
                return new Result().data("呼叫成功");
            }
            return new Result().error(new Error(msg));
        }
        return new Result().error(new Error("通信异常"));
    }

    @Override
    public Result blindTransferByAgent(InputCallNumber in) {
        String url= default_url +"/openapi/"+version+"/blindTransferByAgent";
        Map<String,Object> param=new HashMap<>();
        param.put("authentication",getAuthentication());
        Map<String,Object> request=new HashMap<>();
        request.put("agent",in.getAgent());
        request.put("transAgent",in.getTransAgent());
        request.put("userData",in.getUid());
        param.put("request",request);
        HttpUtils httpUtils=new HttpUtils();
        String s = httpUtils.sendHttpsRequest(url, "POST", param);
        LoggerUtils.debug(getClass(),"res="+s);
        JSONObject jsonObject = JSON.parseObject(s);
        JSONObject result = jsonObject.getJSONObject("result");
        String msg = result.getString("msg");
        String error = result.getString("error");
        if ("0".equals(error)){
            return new Result().data("转移成功");
        }else {
            LoggerUtils.debug(getClass(),"msg="+msg);
            return new Result().error(new Error(msg));
        }

    }

    @Override
    @Transactional
    public Object pushCallCompleted(InputCallCompleter in) {
        Map<String, Object> notify = in.getNotify();
        String staffNo=String.valueOf(notify.get("staffNo"));
        Admin admin = adminMapper.selectByCallStaffNo(staffNo);
        String  startTime = String.valueOf(notify.get("startTime"));
        String callee=String.valueOf(notify.get("callee"));
        String timeLength=String.valueOf(notify.get("timeLength"));
        String callResult=String.valueOf(notify.get("callResult"));
        String callResultMsg=String.valueOf(notify.get("callResultMsg"));
        String userDate=String.valueOf(notify.get("userData"));
        String name="暂无";
        String id=null;
        if(admin!=null){
            name=admin.getName();
            id=admin.getId();
        }
        String ContactName=null;
        String uid=null;
        if (userDate!=null){
            uid=userDate;
        }
        List<OrganizationContactBook> books = organizationContactBookMapper.selectUserByContact(callee);
        if (books!=null){
            if (uid==null){
                OrganizationContactBook book1 = books.get(0);
                ContactName=book1.getName();
                uid=book1.getUid();
            }else {
                for (OrganizationContactBook item:books){
                    if (item.getUid().equals(uid)){
                        ContactName=item.getName();
                        break;
                    }
                }
            }
        }
        CallLog callLog=new CallLog();
        callLog.setUid(uid);
        callLog.setAid(id);
        callLog.setAdminName(name);
        callLog.setContacts(ContactName);
        callLog.setCreateTime(DateUtils.parseDate(startTime));
        callLog.setMobile(callee);
        callLog.setCallNo(staffNo);
        String substring = callee.substring(callee.length() - 4);
        callLog.setMobileLastDigits(substring);
        callLog.setDuration(Integer.parseInt(timeLength));
        callLog.setStatus(0);
        callLog.setRemarks(callResultMsg);
        callLogMapper.insert(callLog);
        pushCountUser(uid,id);
        //需要关闭客户呼叫中
//        SseResult res =  SseMap.sseEmitterMap.get(TokenManager.getAdminId());

        try {
//        res.sseEmitter.send(callResult);
            systemWebSocketHandler.sendMessageToUser(admin.getId(), new TextMessage(callResult));
            LoggerUtils.debug(getClass(),String.format("通信成功=》%s=%s",callResult,callResultMsg));
        }catch (Exception e ){
            LoggerUtils.error(getClass(),"通信失败");
        }
//        finally {
//            res.sseEmitter.complete();
//            SseMap.sseEmitterMap.remove(TokenManager.getAdminId());
//        }
        return 1;
    }

    /**
     * 客户通话时长统计
     *
     * @param uid 客户编号
     * @param id 呼叫人编号
     */
    private void pushCountUser(String uid, String id) {
        LocalDate now = LocalDate.now();
        List<CallLog> callLogList = callLogMapper.selectByUid(uid);
        int count=0;
        int duration=0;
        for (CallLog log : callLogList) {
            count++;
            duration+=log.getDuration();
        }
        //统计客户呼叫时长
        UserMid mid=new UserMid();
        mid.setUid(uid);
        mid.setCallCount(count);
        mid.setCallDuration(duration);
        userMidMapper.updateCallByUid(uid,count,duration);
        //统计呼叫人每天的通话时长
        AdminCallDay adminCallDay = adminCallDayMapper.selectByAidAndDay(id, now);
        LocalDate endTime = now.plusDays(1);
        if (adminCallDay==null){
            adminCallDayMapper.insertDay(id,now,endTime);
        }else {
            adminCallDayMapper.updateDay(id,now,endTime);
        }

        User u =new User();
        u.setId(uid);
        u.setCallStatus(0);
        userMapper.update(u);
    }

    @Override
    public Object agentList() {
        return adminMapper.agentList();
    }

    @Override
    public Object getDefaultMobile(String uid) {
        return organizationContactBookMapper.getMajor(uid,null);
    }

    @Override
    public Object userCallList(InputUserCallList in) {
        CallLog select=new CallLog();
        select.setUid(in.getUid());
        Pagination<?> page = findPage("findCallLogList", "findCallLogCount", select, in.getPageNo(), in.getPageSize());
        UserMid userMid = userMidMapper.selectByUid(in.getUid());
        Map<String,Object> sumMap = new HashMap();
        int count=0;
        int duration=0;
        if (userMid!=null){
            User user = userMapper.queryById(in.getUid());
            count=userMid.getCallCount();
            duration=userMid.getCallDuration();
            sumMap.put("callCount",count);
            sumMap.put("callDuration",duration);
            sumMap.put("name",user.getNickname());
        }
        Map<String,Object> res = new HashMap();
        res.put("page",page);
        res.put("sum",sumMap);
        return res;
    }

    @Override
    public Object callAllList(InputUserCallList in) {
        Pagination<?> page = findPage("findCallLogList", "findCallLogCount", in);
        return page;
    }

    @Override
    public Object pushAllCall() {
        List<CallDaysSumBo> callDaysSumBos = callLogMapper.selectAllCount();
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
        for (CallDaysSumBo e : callDaysSumBos) {
            Admin admin = adminMapper.selectById(e.getAid());

            AdminCallDay adminCallDay = new AdminCallDay();
            adminCallDay.setAid(e.getAid());
            adminCallDay.setName(admin.getName());
            adminCallDay.setTeamId(admin.getTeamId());
            if (admin.getTeamId()!=null){
                SalesTeam salesTeam = salesTeamMapper.queryById(admin.getTeamId());
                adminCallDay.setTeamName(salesTeam.getName());
            }
            adminCallDay.setCallSum(e.getCallSum());
            adminCallDay.setDayDate(DateUtils.parseDate(e.getDates()));
            adminCallDay.setCallDurationSum(e.getCallDurationSum());
            adminCallDay.setValidSum(e.getValidSum());
            adminCallDay.setConnectSum(e.getConnectSum());
            LocalDate parse = LocalDate.parse(e.getDates(), formatter);
            AdminCallDay adminCallDay1 = adminCallDayMapper.selectByAidAndDay(e.getAid(), parse);
            if (adminCallDay1==null){
                adminCallDayMapper.insert(adminCallDay);
            }else {
                adminCallDay.setId(adminCallDay1.getId());
                adminCallDayMapper.update(adminCallDay);
            }

        }

        return 1;
    }




}
