package com.tofly.xrtygis.custom.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.util.Date8Util;
import com.tofly.common.core.util.DateUtil;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.xrtygis.custom.entity.gs.KhInfo;
import com.tofly.xrtygis.custom.entity.gs.NoteSearch;
import com.tofly.xrtygis.custom.service.SendNoteService;
import com.tofly.xrtygis.custom.util.CallAPIUtil;
import com.tofly.xrtygis.entity.Qfkhjbxx;
import com.tofly.xrtygis.entity.Rxsmsmessage;
import com.tofly.xrtygis.service.QfkhjbxxService;
import com.tofly.xrtygis.service.RxsmsmessageService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.tofly.xrtygis.custom.util.SMSUtils.sendMsg;

/**
 * @author FlashWJL
 * @date 2021/4/6 13:05
 */
@AllArgsConstructor
@Service
public class SendNoteServcieImpl implements SendNoteService {
    private final RxsmsmessageService messageService;
    private final QfkhjbxxService qfkhjbxxService;

    @Override
    public IPage<Rxsmsmessage> getNote(Page page, NoteSearch noteSearch) {
        String state = noteSearch.getState();
        String inputContent = noteSearch.getInputContent();
        Date start = noteSearch.getStartTime();
        Date end = noteSearch.getEndTime();
        IPage<Rxsmsmessage> rxsmsmessageIPage = messageService.page(page, Wrappers.<Rxsmsmessage>lambdaQuery()
                .eq(StringUtil.isNotEmpty(state), Rxsmsmessage::getFszt, state)
                .like(StringUtil.isNotEmpty(inputContent), Rxsmsmessage::getTxnr, inputContent)
                .ge(StringUtil.isNotNull(start), Rxsmsmessage::getCreateDate, start)
                .le(StringUtil.isNotNull(end), Rxsmsmessage::getCreateDate, end)
                .orderByDesc(Rxsmsmessage::getCreateDate));
        return rxsmsmessageIPage;
    }

    @Override
    public Map getNoteNum() {
        Integer faildNum = messageService.count(Wrappers.<Rxsmsmessage>lambdaQuery().eq(Rxsmsmessage::getFszt, "2"));
        Integer allNum = messageService.count();
        Map<String, Integer> map = new HashMap<>(5);
        map.put("faildNum", faildNum);
        map.put("allNum", allNum);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String aginSendNote(NoteSearch noteSearch) {
        Long id = noteSearch.getId();
        //查询短信
        Rxsmsmessage rxsmsmessage = messageService.getById(id);
        String phone = rxsmsmessage.getMobile();
        String nr = rxsmsmessage.getTxnr();
        //提示信息  1：成功；2：失败
        String hint = "1";
        //发送短信
        try {
            String result = sendMsg(phone, nr);
            rxsmsmessage.setCreateDate(Date8Util.getCurrentDate());
            //发送成功
            if (result.contains("发送成功")) {
                rxsmsmessage.setFszt("1");
                rxsmsmessage.setIslock("1");
            }
            //发送失败
            else {
                hint = "2";
                rxsmsmessage.setFszt("2");
                rxsmsmessage.setIslock("0");
            }
            rxsmsmessage.setBz(result);
            //修改
            messageService.updateById(rxsmsmessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "1".equals(hint) ? "成功" : "失败";
    }


    @Override
    @SneakyThrows
    public String sendNote(String phone, String content) {
//        String result = sendMsg(phone, content);
        //解析多个电话号码
        List<String> mobileList = Arrays.asList(phone.split(","));
        Long maxId = messageService.getMaxId("TF_YWPN_RXSMSMESSAGE_W");

        List<Rxsmsmessage> rxsmsmessageList = new ArrayList<>();
        Integer size = mobileList.size();
        //将电话与id放在map中，避免了多个对象的创建
        for (int i = 0; i < size; i++) {
            Rxsmsmessage message = new Rxsmsmessage();
            message.setId(maxId + i);
            message.setMobile(mobileList.get(i));
            message.setFszt("0");
            message.setCreateDate(Date8Util.getCurrentDate());
            message.setCreateUser(SecurityUtils.getUserId());
            message.setLsbh(DateUtil.parseDateToStr("yyyyMMddHHmmssSSS",Date8Util.getCurrentDate())+i);
            message.setTxnr(content);
            message.setIslock("0");
            message.setTxlx("");
            rxsmsmessageList.add(message);
        }
        messageService.insertMessage(rxsmsmessageList);
        //专门有个方法发送，专门发送短信和更改短信发送标志
        action(maxId, maxId + size - 1);
        return "发送成功";
    }

    @Override
    public String sendNoteTemplate(String clientId, String temp ,String tempId) {
//        //这里后期确认，是否有超过一千的数据量，如果有则需要判断
        List<String> clientList = Arrays.asList(clientId.split(","));
//
//        //先查询用户信息
        List<Qfkhjbxx> qfkhjbxxList = qfkhjbxxService.list(Wrappers.<Qfkhjbxx>lambdaQuery().in(Qfkhjbxx::getYhbh, clientList)
                .select(Qfkhjbxx::getYhbh, Qfkhjbxx::getYhxm, Qfkhjbxx::getLxdh, Qfkhjbxx::getYhbh, Qfkhjbxx::getYhdz));

        //        KhInfo khInfo = new KhInfo();
//        khInfo.setACTION("query");
//        khInfo.setYHBH(clientId);
//        List<Qfkhjbxx> qfkhjbxxList = getKH(khInfo);

        String currentTime = DateUtil.parseDateToStr("yyyy-MM-dd HH:mm:ss", Date8Util.getCurrentDate());
        //存放需要替换的变量以及值
        Map<String, String> replaceMap = new HashMap<>();
        //存电话号码以及模板转换后的文本短信信息
        Map<String, String> noteMap = new HashMap<>();
        if (StringUtil.isNotNull(qfkhjbxxList)) {
            qfkhjbxxList.forEach(k -> {
                //需要的替换的变量，如把 ${YHXM} 替换
                replaceMap.put("YHXM", k.getYhxm());
                replaceMap.put("YHDZ", k.getYhdz());
                replaceMap.put("LXDH", k.getLxdh());
                replaceMap.put("YHBH", k.getYhbh());
                replaceMap.put("TIME", currentTime);
                //这个是commons-text依赖中的
                StringSubstitutor sub = new StringSubstitutor(replaceMap);
                //替换模板文字中的变变量
                String sendContent = sub.replace(temp);
                noteMap.put(k.getLxdh(), sendContent);
            });
            List<Rxsmsmessage> rxsmsmessageList = new ArrayList<>();
            Long maxId = messageService.getMaxId("TF_YWPN_RXSMSMESSAGE_W");

            noteMap.forEach((k, v) -> {
                //发送短信在最后发送，先插入到数据库，然后再从数据库里面拿出来，再发送短信，避免同一条短信多同一个客户多个发送
                Rxsmsmessage message = new Rxsmsmessage();
                message.setTxlx(tempId);
                message.setMobile(k);
                message.setCreateDate(Date8Util.getCurrentDate());
                message.setCreateUser(SecurityUtils.getUserId());
                message.setFszt("0");
                message.setTxnr(v);
                message.setIslock("0");
                rxsmsmessageList.add(message);

            });
            Integer size = rxsmsmessageList.size();
            //设置主键ID
            for (int i = 0; i < size; i++) {
                rxsmsmessageList.get(i).setId(i + maxId);
                //用时间的流水编号会出现一样的，后面加个数
                rxsmsmessageList.get(i).setLsbh(DateUtil.parseDateToStr("yyyyMMddHHmmssSSS",Date8Util.getCurrentDate())+i);
            }
            messageService.insertMessage(rxsmsmessageList);
            //专门有个方法发送，专门发送短信和更改短信发送标志
            action(maxId, maxId + size - 1);
            return "成功";
        } else {
            return "未查询到用户";
        }
    }

    @Override
    public List<Qfkhjbxx> getKH(KhInfo khInfo) {
        try {
            Object info = CallAPIUtil.callAPIUtil(khInfo, "api/Business/GetCustomerData").get("data");
            List<Qfkhjbxx> mapList = JSONObject.parseArray(JSONObject.toJSONString(info), Qfkhjbxx.class);
            if (StringUtil.isNotNull(mapList) && mapList.size() > 0) {
                return mapList;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 专门发送短信及更改数据库短信信息
     * 根据ID范围确定短信信息
     *
     * @param startId
     * @param endId
     */
    @Async
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void action(Long startId, Long endId) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                //用ID的范围查询需要发送的短信；并且只能是未发送的短信信息
                List<Rxsmsmessage> rxsmsmessageList = messageService.list(Wrappers.<Rxsmsmessage>lambdaQuery().le(Rxsmsmessage::getId, endId)
                        .ge(Rxsmsmessage::getId, startId).eq(Rxsmsmessage::getIslock, "0").eq(Rxsmsmessage::getFszt, "0")
                        .select(Rxsmsmessage::getMobile, Rxsmsmessage::getTxnr, Rxsmsmessage::getId));

                //轮训发送短信，并修改短信字段信息
                rxsmsmessageList.forEach(k -> {
                    try {
                        //发送短信
                        String result = sendMsg(k.getMobile(), k.getTxnr());
                        //发送成功
                        if (result.contains("发送成功")) {
                            k.setFszt("1");
                            k.setIslock("1");
                        }//发送失败
                        else {
                            k.setFszt("2");
                            k.setIslock("0");
                        }
                        k.setBz(result);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
                //修改数据库短信信息数据
                messageService.updateMessage(rxsmsmessageList);
            }
        });
    }

}
