package com.dgtly.wxportal.utils.qywxutils;


import com.alibaba.fastjson.JSONObject;
import com.dgtly.common.utils.StringUtils;
import com.dgtly.common.utils.http.HttpUtils;
import com.dgtly.system.domain.CustomerModelVO;
import com.dgtly.system.service.ISysUserService;
import com.dgtly.system.service.impl.SysConfigServiceImpl;
import com.dgtly.wxportal.domain.SendOrderNoticeTaskModel;
import com.dgtly.wxportal.domain.SendOrderNoticeTaskModelCredit;
import com.dgtly.wxportal.domain.WxSendMessage;
import com.dgtly.wxportal.exception.QyWeixinException;
import com.dgtly.wxportal.mapper.WxSendMessageMapper;
import com.dgtly.wxportal.service.BatchSendCustomerCreditMessage;
import com.dgtly.wxportal.service.BatchSendQyWxMessage;
import com.dgtly.wxportal.utils.*;
import com.dgtly.wxportal.utils.qywxutils.messageModel.QyWxBaseMessage;
import com.dgtly.wxportal.utils.qywxutils.messageModel.QyWxTextMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 企业微信发送信息工具类
 */
@Component
public class QyWxSendMessageUtil {
    private static final Logger log = LoggerFactory.getLogger(QyWxSendMessageUtil.class);
    @Autowired
    private QyWxAccessTokenUtil qyWxAccessTokenUtil;


    @Autowired
    private SysConfigServiceImpl configService;
    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private WxSendMessageMapper wxSendMessageMapper;

    @Async
    public void sendApproveProcessMessage(String users, String msg, String form){
        List<WxSendMessage> wmList = new ArrayList<>();
        if (StringUtils.isNotEmpty(users)) {
            Set<String> userList = new HashSet<>(Arrays.asList(users.split(",")));
            for (String user : userList) {
                WxSendMessage wm = new WxSendMessage();
                QyWxTextMessage qyWxTextMessage = new QyWxTextMessage();
                qyWxTextMessage.setTouser(user);
                wm.setToUser(qyWxTextMessage.getTouser());
                qyWxTextMessage.setText(msg);
                wm.setSendText(qyWxTextMessage.getText().getContent());
                try {
                    sendMessage(qyWxTextMessage);
                    wm.setIsSuccess("1");
                    wm.setForm(form);
                } catch (Exception e) {
                    log.error("对" + user + "发送消息失败", e);
                } finally {
                    wmList.add(wm);
                }
            }
        }
        if (wmList.size() > 0) {
            try {
                wxSendMessageMapper.bathInsertWxSendMessage(wmList);
            } catch (Exception e) {

                log.error("发送微信信息时插入记录出错！！", e);
            }
        }
    }

    @Async
    public void sendMsgToCustomer(Set<String> customerCodes,Map<String,Map<String,Object>> maps,String msg, String form){
        List<WxSendMessage> wmList = new ArrayList<>();
        if(customerCodes.size()>0){
            for(String code:customerCodes){
                if(maps.containsKey(code)&&maps.get(code).get("touser")!=null&&!maps.get(code).get("touser").toString().trim().equals("")){
                    WxSendMessage wm= new WxSendMessage();
                    QyWxTextMessage qyWxTextMessage = new QyWxTextMessage();
                    qyWxTextMessage.setTouser(maps.get(code).get("touser").toString());
                    wm.setToUser(qyWxTextMessage.getTouser());
                    qyWxTextMessage.setText(msg);
                    wm.setSendText(qyWxTextMessage.getText().getContent());
                    wm.setForm(form);
                    try{
                        sendMessage(qyWxTextMessage);
                        wm.setIsSuccess("1");
                    }catch (Exception e){
                        log.error("对"+maps.get(code).get("touser")+"发送消息失败",e);
                    }finally {
                        wmList.add(wm);
                    }
                }else{
                    log.error("经销商code为："+code+"的经销商未发现相应人员！！");
                }
            }
        }
        if (wmList.size() > 0) {
            try {
                wxSendMessageMapper.bathInsertWxSendMessage(wmList);
            } catch (Exception e) {

                log.error("发送微信信息时插入记录出错！！", e);
            }
        }
    }

    @Async
    public void sendDeliveryMessage(Set<String> customerCodes,Map<String,Map<String,Object>> maps,String msg){
        List<WxSendMessage> wmList = new ArrayList<>();
        if(customerCodes.size()>0){
            for(String code:customerCodes){
                if(maps.containsKey(code)&&maps.get(code).get("touser")!=null&&!maps.get(code).get("touser").toString().trim().equals("")){
                    WxSendMessage wm= new WxSendMessage();
                    QyWxTextMessage qyWxTextMessage = new QyWxTextMessage();
                    qyWxTextMessage.setTouser(maps.get(code).get("touser").toString());
                    wm.setToUser(qyWxTextMessage.getTouser());
                    qyWxTextMessage.setText(msg);
                    wm.setSendText(qyWxTextMessage.getText().getContent());
                    try{
                        sendMessage(qyWxTextMessage);
                        wm.setIsSuccess("1");
                        wm.setForm("1");
                    }catch (Exception e){
                        log.error("对"+maps.get(code).get("touser")+"发送消息失败",e);
                    }finally {
                        wmList.add(wm);
                    }
                }else{
                    log.error("经销商code为："+code+"的经销商未发现相应人员！！");
                }
            }
        }
        if (wmList.size() > 0) {
            try {
                wxSendMessageMapper.bathInsertWxSendMessage(wmList);
            } catch (Exception e) {

                log.error("发送微信信息时插入记录出错！！", e);
            }
        }
    }

    @Async
    public void sendCreditMessage(SendOrderNoticeTaskModel model) {
        if(model.getCredit()!=null){
            sendCreditMessage(model.getCredit(),0);
        }
        if(model.getNotCredit()!=null){
            sendCreditMessage(model.getNotCredit(),1);
        }


    }

    /**
     * 发送信用相关信息
     * @param credit
     * @param type 0过信用未要货  1 未过信用
     */
    void sendCreditMessage(SendOrderNoticeTaskModelCredit credit,int type){
        //发送经销商过信用通知
        if(credit.getCustomerMap()!=null&&credit.getCustomerMap().size()>0){
            try{
                //需要发送的组织codeset列表
                Collection<CustomerModelVO> orgCodeSet = credit.getCustomerMap().values();
                Map<String,Integer> customerMap = new HashMap<>();
                Set<String> customerId=new HashSet<>();
                //需要发送的组织凑的
                for (CustomerModelVO customerModelVO:orgCodeSet
                     ) {
                    customerId.add(customerModelVO.getCustomerId());
                    customerMap.put(customerModelVO.getCustomerId(),customerModelVO.getCount());
                }
                Map<String,Map<String,Object>> orgCodeTouser = sysUserService.selectLoginNamesByCostumerVoCode(orgCodeSet);
                String conKey = "";
                String form="";
                if(type==0){
                    conKey ="wx.notification.credit.customer";
                    form="3";
                }else {
                    conKey ="wx.notification.nocredit.customer";
                    form="7";
                }
                String temple =configService.selectConfigByKey(conKey);
                BatchSendGetToUser<String> getToUser = new CreditGetToUser<>(orgCodeTouser);
                BatchSendGetSendMessage getText = new CreditGetSendMessageCus(temple,customerMap);
                BatchSendQyWxMessage batchSendQyWxMessage = new BatchSendCustomerCreditMessage<String,Map<String,Object>>(customerId,getToUser,getText);
                List<QyWxBaseMessage> messageList = batchSendQyWxMessage.getMessageList();
                int success =  batchSendMessage(messageList,form);
                log.info("批量发送信息,成功："+success+"条,总共："+messageList.size());
            }catch (Exception e){
                log.error("发送信用相关经销商通知出错",e);
            }



        }

        //发送销售过信用通知
        if(credit.getSalesMap()!=null&&credit.getSalesMap().size()>0){
            try{
                //codeSet 为销售的雇员id
                Set<String> employeeSet = credit.getSalesMap().keySet();
                Map<String,Map<String,Object>> employeeCodeTouser = sysUserService.selectLoginNamesByEmployeeCode(employeeSet);


                String conKey = "";
                String form="";
                if(type==0){
                    conKey ="wx.notification.credit.sales";
                    form="4";
                }else {
                    conKey ="wx.notification.nocredit.sales";
                    form="8";
                }
                //信息模板
                String temple =configService.selectConfigByKey(conKey);
                //经销商链接模板
                String cusLintTemp =configService.selectConfigByKey("wx.notification.credit.sales.cuslink");

                BatchSendGetToUser getToUser = new CreditGetToUser(employeeCodeTouser);

                //String template,String cusLintTemp,Map<T,List<SendOrderNoticeTaskModelCustomer>> map
                BatchSendGetSendMessage getText = new CreditGetSendMessageSale(temple,cusLintTemp,credit.getSalesMap());

                BatchSendQyWxMessage batchSendQyWxMessage = new BatchSendCustomerCreditMessage<String,Map<String,Object>>(employeeSet,getToUser,getText);
                List<QyWxBaseMessage> messageList = batchSendQyWxMessage.getMessageList();
                int success =  batchSendMessage(messageList,form);
                log.info("批量发送信息,成功："+success+"条,总共："+messageList.size());
            }catch (Exception e){
                log.error("发送信用相关销售通知出错",e);
            }


        }

        //发送分部过信用通知
        if(credit.getSubOfficeMap()!=null&&credit.getSubOfficeMap().size()>0){
            try{

                Set<String> orgCodeSet = credit.getSubOfficeMap().keySet();
                Map<String,Map<String,Object>> maps = sysUserService.selectLoginNamesByEmployeeCode(orgCodeSet);
                String conKey = "";
                String form="";
                if(type==0){
                    conKey ="wx.notification.credit.suboffice";
                    form = "5";
                }else {
                    conKey ="wx.notification.nocredit.suboffice";
                    form = "9";
                }
                sendMessageSubAndOffice(orgCodeSet,maps,credit.getSubOfficeMap(),conKey,form);
            }catch (Exception e){
                log.error("发送信用相关分部通知出错",e);
            }

        }
        //发送销售部过信用通知

        if(credit.getOfficeMap()!=null&&credit.getOfficeMap().size()>0){
            try{
                Set<String> employeeCodeSet = credit.getOfficeMap().keySet();
                Map<String,Map<String,Object>> maps = sysUserService.selectLoginNamesByEmployeeCode(employeeCodeSet);
                String conKey = "";
                String form="";
                if(type==0){
                    conKey ="wx.notification.credit.office";
                    form="6";
                }else {
                    conKey ="wx.notification.nocredit.office";
                    form="10";
                }
                sendMessageSubAndOffice(employeeCodeSet,maps,credit.getOfficeMap(),conKey,form);
            }catch (Exception e){
                log.error("发送信用相关销售部通知出错",e);
            }

        }
    }


    /**
     *
     * @param orgCodeSet 组织代码Set
     * @param orgCodeTouser 组织代码为KET 值为 toUser：123||456
     * @param configKey
     * @param form
     */
    /**
     * 批量发送企业微信信息  销售部和分部
     * @param orgCodeSet
     * @param employeeCodeTouser
     * @param orgCodeValue
     * @param configKey
     * @param form
     */
    public void sendMessageSubAndOffice(Set<String> orgCodeSet,Map<String,Map<String,Object>> employeeCodeTouser,Map<String,Set<String>> orgCodeValue,String configKey,String form){
        //信息模板
        String temple =configService.selectConfigByKey(configKey);
        BatchSendGetToUser<String> getToUser = new CreditGetToUser<>(employeeCodeTouser);

        BatchSendGetSendMessage getText = new CreditGetSendMessageSubAndOffice(temple,orgCodeValue,employeeCodeTouser);

        BatchSendQyWxMessage batchSendQyWxMessage = new BatchSendCustomerCreditMessage<String,Map<String,Object>>(orgCodeSet,getToUser,getText);
        List<QyWxBaseMessage> messageList = batchSendQyWxMessage.getMessageList();
        int success =  batchSendMessage(messageList,form);
        log.info("批量发送信息,成功："+success+"条,总共："+messageList.size());

    }

    public int batchSendMessage(List<QyWxBaseMessage> messageList,String form){
        int success = 0;
        int faile =0;
        List<WxSendMessage> wmList = new ArrayList<>();
        for(QyWxBaseMessage qyWxBaseMessage:messageList){
            WxSendMessage wm = new WxSendMessage();
            try{
                wm.setForm(form);
                wm.setToUser(qyWxBaseMessage.getTouser());
                if(qyWxBaseMessage.getClass()==QyWxTextMessage.class){
                    QyWxTextMessage qt = (QyWxTextMessage)qyWxBaseMessage;
                    wm.setSendText(qt.getText().getContent());
                }
                boolean f =  sendMessage(qyWxBaseMessage);
                if(f){
                   success++;
                   wm.setIsSuccess("1");
                }else{
                   faile++;
                }
            }catch (Exception e){
                log.error("对" + qyWxBaseMessage.getTouser() + "发送消息失败", e);
                faile++;
            } finally {
                wmList.add(wm);
            }
        }
        if(wmList.size()>0){
            try{
                wxSendMessageMapper.bathInsertWxSendMessage(wmList);
            }catch (Exception e){
                log.error("发送微信信息时插入记录出错！！",e);
            }
        }
        return success;
    }

    /**
     * 发送一条企业微信
     * @param message
     * @return
     */
    public boolean sendMessage(QyWxBaseMessage message){
        message.setAgentid(qyWxAccessTokenUtil.getAgentId());
        String url = QyWxServiceUrl.SEND_MESSAGE_URL.getformatUrl(qyWxAccessTokenUtil.getAccessToken());
        String result =  HttpUtils.sendJsonPost(url,message);
        JSONObject json = JSONObject.parseObject(result);
        Integer errcode = json.getInteger("errcode");
        if(errcode!=0){
            throw new QyWeixinException(errcode,url);
        }
        return true;

    }


    @Async
    public void sendMsgSelfToCustomer(String user,String msg, String form){
        List<WxSendMessage> wmList = new ArrayList<>();
                    WxSendMessage wm= new WxSendMessage();
                    QyWxTextMessage qyWxTextMessage = new QyWxTextMessage();
                    qyWxTextMessage.setTouser(user);
                    wm.setToUser(qyWxTextMessage.getTouser());
                    qyWxTextMessage.setText(msg);
                    wm.setSendText(qyWxTextMessage.getText().getContent());
                    wm.setForm(form);
                    try{
                        sendMessage(qyWxTextMessage);
                        wm.setIsSuccess("1");
                    }catch (Exception e){
                        log.error("对"+user+"发送消息失败",e);
                    }finally {
                        wmList.add(wm);
                    }
                    if (wmList.size() > 0) {
                        try {
                            wxSendMessageMapper.bathInsertWxSendMessage(wmList);
                        } catch (Exception e) {

                            log.error("发送微信信息时插入记录出错！！", e);
                        }
                    }
    }

}
