package com.house365.ws.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.house365.beans.entity.*;
import com.house365.commons.system.HttpClientUtil;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.ws.beans.response.DepartmentResponse;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.dao.mapper.*;
import com.house365.ws.interfaces.server.IDepartment;
import com.house365.ws.service.interfaces.ISendMsgService;
import com.house365.ws.service.interfaces.IUserService;
import com.house365.ws.util.HttpUtil;
import com.house365.ws.util.PathUtil;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Created by Administrator on 2018/11/27.
 */
@Service("sendMessageTask")
public class SendMsgImpl implements ISendMsgService {

    private static final Logger logger = LoggerFactory.getLogger(SendMsgImpl.class);

    private final String AGENTID = MemoryPropertyPlaceholderConfigurer.getContextProperty("WECHAT.IM.AGENTID");

    @Value("${crm.track.url}")
    private String crmTrackUrl;

    @Autowired
    private YxMessageMapper mapper;

    @Autowired
    private IUserService userService;

    @Autowired
    private IDepartment department;

    @Autowired
    private MessageLogMapper logMapper;

    @Autowired
    private RedisUtilsInterface redisUtil;

    @Autowired
    private DictionaryMapper dictionaryMapper;

    @Autowired
    private CustomerMergeMapper mergeMapper;

    @Autowired
    private SignUpTrackMapper trackMapper;
    @Autowired
    private CustomerCallbackMapper callbackMapper;

    @Autowired
    private UserWxRelationMapper relationMapper;
    @Autowired
    private MessageLogMapper messageLogMapper;

    @Override
    public void sendMessage() {
        try {
            //通过redis查询key来实现只在一台机器上执行
            String key = "message_job";
            String value = "jobValue";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Date date = new Date();
                int day = getDay(date);
                int hours = getHour(date);
                int minutes = getMinute(date);
                //判断只在上班时间发送短信，下班不处理
                if ((hours == 8 && minutes >= 40) || (hours >= 9 && hours < 21)) {
                    List<YxMessageEntity> list = mapper.queryPersonList();
                    if (CollectionUtils.isNotEmpty(list)) {
                        Iterator<YxMessageEntity> iterator = list.iterator();
                        while (iterator.hasNext()) {
                            YxMessageEntity l = iterator.next();
                            String info = l.getInfo();
                            String fromAccount = l.getFromAccount();
                            Date createTime = l.getCreateTime();
                            Map<String, Object> map = new HashMap<>(10);
                            map.put("fromAccount", info);
                            map.put("info", fromAccount);
                            map.put("time", createTime);
                            List<YxMessageEntity> infoList = mapper.queryByConditions(map);
                            //保留没有回复的短信（自动回复不算回复）
                            if (CollectionUtils.isNotEmpty(infoList)) {
                                boolean flag = false;
                                for (YxMessageEntity entity : infoList) {
                                    String ext = entity.getExt();
                                    if (StringUtils.isNotBlank(ext)) {
                                        ObjectMapper objectMapper = new ObjectMapper();
                                        Map<String, String> jsonMap = objectMapper.readValue(ext, Map.class);
                                        if (jsonMap.containsKey("autoReply")) {
                                            String status = jsonMap.get("autoReply");
                                            if (StringUtils.isNotBlank(status) && "1".equals(status)) {
                                                flag = false;
                                            } else {
                                                flag = true;
                                                break;
                                            }
                                        } else {
                                            flag = true;
                                            break;
                                        }
                                    }
                                }
                                if (flag) {
                                    iterator.remove();
                                }
                            }
                        }
                    }
                    //筛选之后需要发短信的list
                    if (CollectionUtils.isNotEmpty(list)) {
                        list = removeDuplicate(list);
                        for (YxMessageEntity y : list) {
                            String accId = y.getInfo();
                            int userId = Integer.parseInt(accId.substring(4));
                            UserEntity entity = (UserEntity) userService.getById(userId);
                            if (entity != null) {
                                DepartmentResponse departmentResponse = department.getDepartmentById(entity.getDeptId());
                                DepartmentEntity dept = departmentResponse.getEntity();
                                Integer realDept = PathUtil.extractDept(dept.getUrlPath());
                                if (!entity.getDeptId().equals(realDept)) {
                                    dept = department.getDepartmentById(realDept).getEntity();
                                }
                                String cityId = dept.getCityID();
                                DepartmentResponse departmentResponse2 = department.getDepartmentById(Integer.valueOf(cityId));
                                String cityCode = departmentResponse2.getEntity().getDescripition();
                                entity.setCity(cityCode);
                                String city = entity.getCity();
                                String mobile = entity.getMobile();
                                String msg = "截止到" + day + "日" + hours + "时" + minutes + "分,";
                                msg += "您好，您收到了来自于淘房的用户消息！请打开全链条APP查看并及时回复。";
                                String message = msg;
                                msg = URLEncoder.encode(msg, "GBK");
                                String smUrl = "http://mysms.house365.com/index.php/Interface/apiSendMobil/jid/104/depart/1/city/";
                                smUrl = smUrl + city + "/" + "mobileno/" + mobile;
                                List<NameValuePair> params = new ArrayList<>();
                                params.add(new BasicNameValuePair("msg", msg));
                                String result = HttpClientUtil.doGet(smUrl, params, null);
                                MessageLogEntity logEntity = new MessageLogEntity();
                                if (result != null) {
                                    logEntity.setSendStatus(0);
                                    logger.info("定时发送短信成功");
                                } else {
                                    logEntity.setSendStatus(1);
                                    logger.error("定时发送短信失败", smUrl);
                                }
                                logEntity.setRelateId(y.getRelateId());
                                logEntity.setSender(y.getFromAccount());
                                logEntity.setReceiver(y.getInfo());
                                logEntity.setMessageTime(y.getCreateTime());
                                logEntity.setMobile(mobile);
                                logEntity.setSendTime(date);
                                logEntity.setMessageInfo(message);
                                logMapper.save(logEntity);
                            }
                        }

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("定时发送短信失败", e);
        }
    }

    @Override
    public void deleteMessage() {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) - 8);
            //获取2小时之前的时间
            Date date = calendar.getTime();
            Map<String, Object> map = new HashMap<>(8);
            map.put("time", date);
            mapper.deleteMessage(map);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("删除过期短信失败", e);
        }

    }

    @Override
    public void sendDlqMessage() {
        try {
            System.out.println("暂时关闭");
//            String city = "nj";
//            String mobile = "18862152977";
//            String msg = "您好，请及时去删除dlq死信队列。";
//            msg = URLEncoder.encode(msg, "GBK");
//            String smUrl = "http://mysms.house365.com/index.php/Interface/apiSendMobil/jid/104/depart/1/city/";
//            smUrl = smUrl + city + "/" + "mobileno/" + mobile;
//            List<NameValuePair> params = new ArrayList<>();
//            params.add(new BasicNameValuePair("msg", msg));
//            String result = HttpClientUtil.doGet(smUrl, params, null);
//            if (result != null) {
//                logger.info("定时发送dlq提醒短信成功");
//            } else {
//                logger.error("定时发送dlq提醒短信失败");
//            }
        } catch (Exception e) {
            logger.error("定时发送dlq提醒短信失败");
        }
    }

    private static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    private static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    private static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    private static ArrayList<YxMessageEntity> removeDuplicate(List<YxMessageEntity> list) {
        Set<YxMessageEntity> set = new TreeSet<>(new Comparator<YxMessageEntity>() {
            @Override
            public int compare(YxMessageEntity o1, YxMessageEntity o2) {
                //字符串,则按照asicc码升序排列
                return o1.getInfo().compareTo(o2.getInfo());
            }
        });
        set.addAll(list);
        return new ArrayList<>(set);
    }

    /**
     * 定时更新客户活跃标记
     */
    @Override
    public void updateActiveStatus() {
        try {
            //通过redis查询key来实现只在一台机器上执行
            String key = "updateStatus_job";
            String value = "jobValue";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Map<String, Object> dicMap = new HashMap<>(10);
                dicMap.put("dicKey", "active.remove.hour");
                List<DictionaryEntity> list = dictionaryMapper.getNoApproximateConfig(dicMap);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (DictionaryEntity d : list) {
                        String city = d.getCity();
                        String hour = d.getDicValue();
                        Map<String, Object> map = new HashMap<>(10);
                        map.put("city", city);
                        map.put("hour", hour);
                        mergeMapper.updateActiveStatus(map);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("定时更新客户活跃时间失败", e);
        }
    }

    /**
     * 定时发送企业微信号信息
     * 客服8点40 晚10点；房博士8点40到5点半
     */
    @Override
    public void sendWxMessage() {
        try {
            //通过redis查询key来实现只在一台机器上执行
            String key = "wx_message_job";
            String value = "wxJob";
            long seconds = 5;
            if (redisUtil.setNX(key, value, seconds)) {
                Date date = new Date();
                int hours = getHour(date);
                int minutes = getMinute(date);
                //判断只在上班时间发送短信，下班不处理
                if ((hours == 8 && minutes >= 40) || (hours >= 9 && hours <= 22)) {
                    List<YxMessageEntity> list = mapper.queryWxList();
                    if (CollectionUtils.isNotEmpty(list)) {
                        Iterator<YxMessageEntity> iterator = list.iterator();
                        while (iterator.hasNext()) {
                            YxMessageEntity l = iterator.next();
                            String info = l.getInfo();
                            String fromAccount = l.getFromAccount();
                            Date createTime = l.getCreateTime();
                            Map<String, Object> map = new HashMap<>(10);
                            map.put("fromAccount", info);
                            map.put("info", fromAccount);
                            map.put("time", createTime);
                            List<YxMessageEntity> infoList = mapper.queryByWxConditions(map);
                            //保留没有回复的短信（自动回复不算回复）
                            if (CollectionUtils.isNotEmpty(infoList)) {
                                boolean flag = false;
                                for (YxMessageEntity entity : infoList) {
                                    String ext = entity.getExt();
                                    if (StringUtils.isNotBlank(ext)) {
                                        ObjectMapper objectMapper = new ObjectMapper();
                                        Map<String, String> jsonMap = objectMapper.readValue(ext, Map.class);
                                        if (jsonMap.containsKey("autoReply")) {
                                            String status = jsonMap.get("autoReply");
                                            if (StringUtils.isNotBlank(status) && "1".equals(status)) {
                                                flag = false;
                                            } else {
                                                flag = true;
                                                break;
                                            }
                                        } else {
                                            flag = true;
                                            break;
                                        }
                                    }
                                }
                                if (flag) {
                                    iterator.remove();
                                }
                            }
                        }
                    }
                    //筛选之后需要发短信的list
                    if (CollectionUtils.isNotEmpty(list)) {
                        list = removeDuplicate(list);
                        for (YxMessageEntity y : list) {
                            //8小时内如果发过短信，过滤发送
                            Map<String, Object> queryMap = new HashMap<>(5);
                            queryMap.put("sender", y.getFromAccount());
                            queryMap.put("receiver", y.getInfo());
                            queryMap.put("time", new Date());
                            List<MessageLogEntity> logList = messageLogMapper.queryByConditions(queryMap);
                            if (CollectionUtils.isEmpty(logList)) {
                                String accId = y.getInfo();
                                int userId = Integer.parseInt(accId.substring(4));
                                UserEntity entity = (UserEntity) userService.getById(userId);
                                if (entity != null) {
                                    // 3代表房博士 7代表客服
                                    String type = entity.getIdentityType();
                                    boolean flag = true;
                                    if (StringUtils.isNoneBlank(type) && "3".equals(type)) {
                                        if ((hours == 8 && minutes >= 40) || (hours >= 9 && hours <= 17) || (hours == 17 && minutes <= 30)) {
                                            flag = true;
                                        } else {
                                            flag = false;
                                        }
                                    }
                                    if (flag) {
                                        Map<String, Object> searchMap = new HashMap<>(5);
                                        searchMap.put("userId", userId);
                                        List<UserWxRelation> relationList = relationMapper.queryByConditions(searchMap);
                                        if (CollectionUtils.isNotEmpty(relationList)) {
                                            StringBuilder toUser = new StringBuilder();
                                            for (UserWxRelation r : relationList) {
                                                toUser.append(r.getWxId()).append("|");
                                            }
                                            String result = sendWx(toUser.toString());
                                            ObjectMapper objectMapper = new ObjectMapper();
                                            Map<String, Object> map = objectMapper.readValue(result, Map.class);
                                            MessageLogEntity logEntity = new MessageLogEntity();
                                            int code = Integer.parseInt(map.get("errcode").toString());
                                            if (code == 0) {
                                                logEntity.setSendStatus(0);
                                            } else {
                                                logEntity.setSendStatus(1);
                                            }
                                            logEntity.setRelateId(y.getRelateId());
                                            logEntity.setSender(y.getFromAccount());
                                            logEntity.setReceiver(y.getInfo());
                                            logEntity.setMessageTime(y.getCreateTime());
                                            logEntity.setMobile(entity.getMobile());
                                            logEntity.setSendTime(date);
                                            logEntity.setMessageInfo("您有一条新的用户咨询需要处理，请尽快回复客户。");
                                            logMapper.save(logEntity);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("定时发送企业微信失败", e);
        }
    }

    private String sendWx(String toUser) {
        String result = "";
        try {
            String secret = MemoryPropertyPlaceholderConfigurer.getContextProperty("WECHAT.IM.SECRET");
            String token = HttpUtil.getToken(secret);
            String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?";
            url += "access_token=" + token;
            JSONObject jsonObject = new JSONObject();
            JSONObject text = new JSONObject();
            text.put("content", "您有一条新的用户咨询需要处理，请尽快回复客户。");
            jsonObject.put("agentid", AGENTID);
            jsonObject.put("msgtype", "text");
            jsonObject.put("touser", toUser);
            jsonObject.put("text", text);
            jsonObject.put("safe", "0");
            jsonObject.put("enable_id_trans", "0");
            jsonObject.put("enable_duplicate_check", "0");

            result = HttpUtil.postWithJson(jsonObject, url, token);
            if (Strings.isNullOrEmpty(result)) {
                logger.error("发送企业微信信息失败");
            } else {
                logger.info(result);
            }
        } catch (Exception e) {
            logger.error("发送企业微信信息失败", e);
        }
        return result;
    }

    /**
     * 同步crm报名轨迹数据
     */
    @Override
    public void addCrmTrack() {
        try {
            //通过redis查询key来实现只在一台机器上执行
            String key = "addTrack_job";
            String value = "jobValue";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                List<NameValuePair> params = new ArrayList<>();
                String result = HttpClientUtil.doGet(crmTrackUrl, params);
                logger.info("crm接口返回数据" + result);
                // 业务层统一处理
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, Map> dataMap = objectMapper.readValue(result, Map.class);
                Number total = (Number) dataMap.get("total");
                if (total.intValue() > 0) {
                    List<Map<String, Object>> dataList = (List<Map<String, Object>>) dataMap.get("data");
                    if (CollectionUtils.isNotEmpty(dataList)) {
                        for (Map<String, Object> m : dataList) {
                            String phone = m.get("phone").toString();
                            String city = m.get("city").toString();
                            String time = m.get("join_time").toString();
                            long longTime = Long.parseLong(time);

                            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            time = format.format(longTime * 1000);
                            Date signUpTime = format.parse(time);
                            Map<String, Object> searchMap = new HashMap<>(10);
                            searchMap.put("phone", phone);
                            searchMap.put("cityCode", city);
                            List<CustomerEntity> list = mergeMapper.queryByConditions(searchMap);
                            List<Integer> idList = new ArrayList<>();
                            if (CollectionUtils.isNotEmpty(list)) {
                                for (CustomerEntity c : list) {
                                    idList.add(c.getId());
                                }
                                Map<String, Object> callBackMap = new HashMap<>(10);
                                callBackMap.put("idList", idList);
                                List<CustomerCallbackLogEntity> backList = callbackMapper.queryByConditions(callBackMap);
                                if (CollectionUtils.isNotEmpty(backList)) {
                                    CustomerCallbackLogEntity logEntity = backList.get(0);
                                    int customerId = logEntity.getCustomerId();
                                    SignUpTrackEntity entity = new SignUpTrackEntity();
                                    entity.setCity(city);
                                    entity.setPhone(phone);
                                    entity.setCustomerId(customerId);
                                    entity.setSignUpTime(signUpTime);
                                    trackMapper.save(entity);
                                    Date callbackTime = logEntity.getCreateTime();
                                    //报名时间大于回访时间，修改客户状态为活跃
                                    if (callbackTime.before(signUpTime)) {
                                        //添加回访时更新客户是否交接标志(同时更新是否活跃标志)
                                        Map<String, Object> updateMap = new HashMap<>(10);
                                        updateMap.put("id", customerId);
                                        updateMap.put("isActive", 1);
                                        updateMap.put("updateTime", new Date());
                                        updateMap.put("activeTime", new Date());
                                        mergeMapper.update(updateMap);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("同步crm报名轨迹数据失败", e);
        }
    }

    public static void main(String[] args) {
        try {
            String result;
            String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?";
            String secret = MemoryPropertyPlaceholderConfigurer.getContextProperty("WECHAT.IM.SECRET");
            String token = HttpUtil.getToken(secret);
            try {
                url += "access_token=" + token;
                JSONObject jsonObject = new JSONObject();
                JSONObject text = new JSONObject();
                text.put("content", "您有一条新的用户咨询需要处理，请尽快回复客户。");
                jsonObject.put("agentid", "1000011");
                jsonObject.put("msgtype", "text");
                jsonObject.put("touser", "744|509");
                jsonObject.put("text", text);
                jsonObject.put("safe", "0");
                jsonObject.put("enable_id_trans", "0");
                jsonObject.put("enable_duplicate_check", "0");
                result = HttpUtil.postWithJson(jsonObject, url, token);

                if (Strings.isNullOrEmpty(result)) {
                    logger.info(result);
                    logger.info("发送企业微信信息失败");
                } else {
                    logger.info(result);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            logger.error("定时发送dlq提醒短信失败");
        }
    }

}
