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.DateTimeUtils;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.dao.mapper.*;
import com.house365.ws.interfaces.server.ICustomerProject;
import com.house365.ws.service.interfaces.IProjectService;
import com.house365.ws.service.interfaces.IStaffDuty;
import com.house365.ws.util.OperateLogUtils;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 配置好表数据,定时轮询值日人员.onduty:是否值日,1:当前之日,0:不值日
 *
 * @author whh
 */
@Service("staffDuty")
public class StaffDuty implements IStaffDuty {

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

    @Autowired
    private UserMapper usermapper;
    @Autowired
    private CloudActivityMapper activityMapper;
    @Autowired
    private RedisUtilsInterface redisUtil;
    @Autowired
    private DictionaryMapper dictionaryMapper;
    @Autowired
    private DutyStaffOtherMapper staffOtherMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private IProjectService<ProjectEntity> projectService;
    @Autowired
    private OperateLogUtils logUtils;

    @Autowired
    private CloudCustomerMapper cloudCustomerMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerStatusLogMapper statusLogMapper;
    @Autowired
    private ExternalCustomerMapper externalCusMapper;
    @Autowired
    private CustomerCallbackMapper callbackMapper;
    @Autowired
    private CloudRuleMapper ruleMapper;
    @Autowired
    private ICustomerProject customerProject;
    @Autowired
    private CloudCountMapper cloudCountMapper;


    @Override
    public void updateDutyStaff() {
        List<DutyStaffEntity> list = usermapper.getStaffDutyList();
        Date date = new Date();
        if (CollectionUtils.isNotEmpty(list)) {
            int size = list.size();
            for (int i = 0; i < size; i++) {
                DutyStaffEntity staff = list.get(i);
                if ("1".equals(staff.getOnduty()) && staff.getId() == list.size()) {
                    staff.setOnduty("0");
                    staff.setUpdateTime(date);
                    usermapper.updateDutyStaff(staff);
                    list.get(0).setOnduty("1");//循环到第一个轮询值日
                    list.get(0).setUpdateTime(date);
                    usermapper.updateDutyStaff(list.get(0));
                    break;
                } else if ("1".equals(staff.getOnduty()) && staff.getId() != list.size()) {
                    staff.setOnduty("0");
                    staff.setUpdateTime(date);
                    usermapper.updateDutyStaff(staff);
                    list.get(i + 1).setOnduty("1");//下一个轮询值日
                    list.get(i + 1).setUpdateTime(date);
                    usermapper.updateDutyStaff(list.get(i + 1));
                    break;
                }
            }
        }
    }

    @Override
    public void addCloudActivity() {
        try {
            String key = "save_cloud_job";
            String value = "cloud";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                //获取云迹活动需要添加的城市
                Map<String, Object> dicMap = new HashMap<>(10);
                dicMap.put("city", "nj");
                dicMap.put("dicKey", "cloud.city");
                List<DictionaryEntity> dictionaryList = dictionaryMapper.getNoApproximateConfig(dicMap);
                if (CollectionUtils.isNotEmpty(dictionaryList)) {
                    String dutyCity = dictionaryList.get(0).getDicValue();
                    List<String> cityList = new ArrayList<>();
                    if (dutyCity.contains(",")) {
                        String[] dutyCitys = dutyCity.split(",");
                        for (String s : dutyCitys) {
                            cityList.add(s);
                        }
                    } else {
                        cityList.add(dutyCity);
                    }
                    if (CollectionUtils.isNotEmpty(cityList)) {
                        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                        date = date.replace("-", "");
                        Date now = new Date();
                        for (String city : cityList) {
                            //南京和其他城市区分
                            Map<String, Object> map = new HashMap<>(5);
                            if ("nj".equals(city)) {
                                map.put("onduty", 1);
                                List<DutyStaffEntity> list = usermapper.getDutyByCondition(map);
                                if (CollectionUtils.isNotEmpty(list)) {
                                    DutyStaffEntity staffEntity = list.get(0);
                                    //每天新增一个云迹活动
                                    CloudActivityEntity entity = new CloudActivityEntity();
                                    String name = "云迹数据" + date;
                                    entity.setName(name);
                                    entity.setCustomerCount(0);
                                    entity.setWaitCount(0);
                                    entity.setSentCount(0);
                                    entity.setCity(city);
                                    entity.setCreateId(Integer.valueOf(staffEntity.getUserId()));
                                    entity.setCreateName(staffEntity.getName());
                                    entity.setCreateTime(now);
                                    activityMapper.save(entity);
                                }
                            } else {
                                map.put("isDuty", 1);
                                map.put("city", city);
                                List<DutyStaffOtherEntity> dutyList = staffOtherMapper.queryByConditions(map);
                                if (CollectionUtils.isNotEmpty(dutyList)) {
                                    DutyStaffOtherEntity staffEntity = dutyList.get(0);
                                    //每天新增一个云迹活动
                                    CloudActivityEntity entity = new CloudActivityEntity();
                                    String name = "云迹数据" + date;
                                    entity.setName(name);
                                    entity.setCustomerCount(0);
                                    entity.setWaitCount(0);
                                    entity.setSentCount(0);
                                    entity.setCity(city);
                                    entity.setCreateId(staffEntity.getUserId());
                                    entity.setCreateName(staffEntity.getName());
                                    entity.setCreateTime(now);
                                    activityMapper.save(entity);
                                }
                            }
                        }
                    }
                }
            }
            String newKey = "save_cloud_job_new";
            String newValue = "cloud";
            if (redisUtil.setNX(newKey, newValue, seconds)) {
                addNewActivity();
            }
        } catch (Exception e) {
            logger.error("新增云迹轨迹活动失败");
        }
    }

    /**
     * 定时新增定制云迹活动
     */
    @Override
    public void addCloudActivityNew() {
        try {
            String key = "save_cloud_job_new";
            String value = "cloud";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                addNewActivity();
            }
        } catch (Exception e) {
            logger.error("新增定制云迹轨迹活动失败");
        }
    }

    private void addNewActivity() {
        Map<String, Object> searchMap = new HashMap<>(10);
        searchMap.put("group", 1);
        List<CloudRuleEntity> list = ruleMapper.queryByConditions(searchMap);
        if (CollectionUtils.isNotEmpty(list)) {
            String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            date = date.replace("-", "");
            Date now = new Date();
            for (CloudRuleEntity c : list) {
                CloudActivityEntity entity = new CloudActivityEntity();
                String name = "定制云迹数据" + date;
                entity.setName(name);
                entity.setCustomerCount(0);
                entity.setWaitCount(0);
                entity.setSentCount(0);
                entity.setCity(c.getCityCode());
                entity.setCreateId(c.getUserId());
                entity.setCreateName(c.getCreateName());
                entity.setCreateTime(now);
                activityMapper.save(entity);
            }
        }
    }

    /**
     * 定时同步经管项目开启关闭状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProjectStatus() {
        try {
            String key = "update_project_job";
            String value = "project";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Map<String, Object> map = new HashMap<>(5);
                map.put("showStatus", 1);
                List<ProjectEntity> projectList = projectMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(projectList)) {
                    for (ProjectEntity p : projectList) {
                        List<NameValuePair> params = new ArrayList<>();
                        params.add(new BasicNameValuePair("s", "/Api/getProInfo"));
                        params.add(new BasicNameValuePair("city", p.getCity()));
                        params.add(new BasicNameValuePair("limit", "1"));
                        params.add(new BasicNameValuePair("contract", p.getContractCode()));
                        params.add(new BasicNameValuePair("isAccurate", "1"));

                        String result = HttpClientUtil.doGet(MemoryPropertyPlaceholderConfigurer.getContextProperty("projects.server.url"), params);
                        if (result != null) {
                            ObjectMapper objectMapper = new ObjectMapper();
                            Map<String, Object> resultMap = objectMapper.readValue(result, Map.class);
                            boolean status = (boolean) resultMap.get("status");
                            if (status) {
                                if (resultMap.get("data") != null) {
                                    List<Map<String, Object>> list = (List<Map<String, Object>>) resultMap.get("data");
                                    if (CollectionUtils.isNotEmpty(list)) {
                                        Map<String, Object> dataMap = list.get(0);

                                        String projectCode = dataMap.get("projectCode").toString();
                                        String projectName = dataMap.get("projectName").toString();
                                        String buildingId = dataMap.get("buildingId").toString();
                                        String buildingName = dataMap.get("buildingName").toString();
                                        String statusNew = dataMap.get("status").toString();
                                        String manager = dataMap.get("manager").toString();
                                        String type = dataMap.get("type").toString();
                                        String kfs = dataMap.get("kfs").toString();
                                        String district = dataMap.get("district").toString();
                                        String address = dataMap.get("address").toString();
                                        String startTime = dataMap.get("startTime").toString();
                                        String business = dataMap.get("business").toString();
                                        p.setProjectCode(projectCode);
                                        p.setProjectName(projectName);
                                        p.setBuildingId(Integer.valueOf(buildingId));
                                        p.setBuildingName(buildingName);
                                        p.setStatus(Integer.valueOf(statusNew));
                                        p.setManager(manager);
                                        p.setType(type);
                                        p.setKfs(kfs);
                                        p.setDistrict(district);
                                        p.setAddress(address);
                                        p.setStartTimeStr(startTime);
                                        p.setBusiness(business);
                                        ProjectEntity oldEntity = projectService.getById(p.getId());
                                        projectService.update(p);
                                        ProjectEntity newEntity = projectService.getById(p.getId());
                                        logUtils.recordOperateLog(oldEntity, newEntity, p.getId(), 0, "经管系统");
                                    }
                                }
                            }
                        }
                    }

                }
            }
        } catch (Exception e) {
            logger.error("同步经管状态信息定时任务失败", e);
            throw new RuntimeException();
        }
    }

    /**
     * 定时设置云迹客户报备redis缓存
     */
    @Override
    public void setCloudCount() {
        try {
            String key = "set_cloud_job";
            String value = "cloud";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Map<String, Object> map = new HashMap<>(10);
                List<CloudActivityEntity> list = activityMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (CloudActivityEntity c : list) {
                        //开启线程池跑定时，防止超时
                        final CloudActivityEntity a = c;
                        ExecutorService executor = Executors.newCachedThreadPool();
                        executor.execute(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Map<String, Object> searchMap = new HashMap<>(10);
                                    searchMap.put("activeId", a.getId());
                                    searchMap.put("type", 2);
                                    List<CloudCustomerEntity> cloudList = cloudCustomerMapper.queryByConditions(searchMap);
                                    List<Integer> idList = new ArrayList<>();
                                    List<Integer> seaIdList = new ArrayList<>();
                                    List<Integer> idAllList = new ArrayList<>();
                                    if (CollectionUtils.isNotEmpty(cloudList)) {
                                        for (CloudCustomerEntity c : cloudList) {
                                            if (c.getManagerId() > 0) {
                                                idList.add(c.getCustomerId());
                                            } else {
                                                seaIdList.add(c.getCustomerId());
                                            }
                                        }
                                        //4.9需求 统计添加时间判断
                                        Date time = cloudList.get(0).getCreateTime();
                                        dealList(idList, idAllList, time, 1);
                                        dealSeaList(seaIdList, idAllList, time);
                                        idAllList = removeDuplicate(idAllList);
                                        //设置统计数目 已跟进  回公海  A/B意向数 约看数 到访数 认购数 签约数
                                        String backKey = "cloud_back_count" + a.getId();
                                        String abKey = "cloud_ab_count" + a.getId();
                                        String seeKey = "cloud_see_count" + a.getId();
                                        String daoKey = "cloud_dao_count" + a.getId();
                                        String buyKey = "cloud_buy_count" + a.getId();
                                        String signKey = "cloud_sign_count" + a.getId();
                                        String seeIdKey = "cloud_see_Id" + a.getId();
                                        String daoIdKey = "cloud_dao_Id" + a.getId();
                                        String buyIdKey = "cloud_buy_Id" + a.getId();
                                        String signIdKey = "cloud_sign_Id" + a.getId();
                                        String cancelIdKey = "cloud_cancel_Id" + a.getId();
                                        String renIdKey = "cloud_ren_Id" + a.getId();

                                        if (CollectionUtils.isNotEmpty(idAllList)) {
                                            //已跟进 不计算自动新增的回访
                                            Map<String, Object> backMap = new HashMap<>(10);
                                            backMap.put("idList", idAllList);
                                            backMap.put("notId", 1);
                                            List<Map<String, Object>> backList = callbackMapper.queryCloudBackCount(backMap);
                                            if (CollectionUtils.isNotEmpty(backList)) {
                                                redisUtil.setValueNew(backKey, String.valueOf(backList.size()));
                                            }

                                            Map<String, Object> queryMap = new HashMap<>(5);
                                            queryMap.put("abType", 1);
                                            queryMap.put("idList", idAllList);
                                            List<CustomerEntity> abList = customerMapper.queryCloudCount(queryMap);
                                            redisUtil.setValueNew(abKey, String.valueOf(abList.size()));

                                            StringBuilder builder1 = new StringBuilder();
                                            List<String> seeKeyIdList = new ArrayList<>();
                                            StringBuilder builder2 = new StringBuilder();
                                            List<String> daoIdKeyList = new ArrayList<>();
                                            StringBuilder builder3 = new StringBuilder();
                                            List<String> buyIdKeyList = new ArrayList<>();
                                            StringBuilder builder4 = new StringBuilder();
                                            List<String> signIdKeyList = new ArrayList<>();
                                            StringBuilder builder5 = new StringBuilder();
                                            List<String> cancelIdKeyList = new ArrayList<>();
                                            StringBuilder builder6 = new StringBuilder();
                                            List<String> renIdKeyList = new ArrayList<>();

                                            queryMap.put("status", 1);
                                            List<Map<String, Object>> seeList = statusLogMapper.queryCloudCount(queryMap);
                                            seeList.forEach(s -> seeKeyIdList.add(s.get("phone").toString()));
                                            seeKeyIdList.forEach(s -> builder1.append(s).append(","));
                                            redisUtil.setValueNew(seeKey, String.valueOf(seeList.size()));
                                            redisUtil.setValueNew(seeIdKey, builder1.toString());

                                            queryMap.put("status", 2);
                                            List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
                                            daoList.forEach(s -> daoIdKeyList.add(s.get("phone").toString()));
                                            daoIdKeyList.forEach(s -> builder2.append(s).append(","));
                                            redisUtil.setValueNew(daoKey, String.valueOf(daoList.size()));
                                            redisUtil.setValueNew(daoIdKey, builder2.toString());

                                            queryMap.put("status", 4);
                                            List<Map<String, Object>> buyList = statusLogMapper.queryCloudCount(queryMap);
                                            buyList.forEach(s -> buyIdKeyList.add(s.get("phone").toString()));
                                            buyIdKeyList.forEach(s -> builder3.append(s).append(","));
                                            redisUtil.setValueNew(buyKey, String.valueOf(buyList.size()));
                                            redisUtil.setValueNew(buyIdKey, builder3.toString());

                                            queryMap.put("status", 5);
                                            List<Map<String, Object>> signList = statusLogMapper.queryCloudCount(queryMap);
                                            signList.forEach(s -> signIdKeyList.add(s.get("phone").toString()));
                                            signIdKeyList.forEach(s -> builder4.append(s).append(","));
                                            redisUtil.setValueNew(signKey, String.valueOf(signList.size()));
                                            redisUtil.setValueNew(signIdKey, builder4.toString());

                                            queryMap.put("status", 6);
                                            List<Map<String, Object>> cancelList = statusLogMapper.queryCloudCount(queryMap);
                                            cancelList.forEach(s -> cancelIdKeyList.add(s.get("phone").toString()));
                                            cancelIdKeyList.forEach(s -> builder5.append(s).append(","));
                                            redisUtil.setValueNew(cancelIdKey, builder5.toString());

                                            queryMap.put("status", 3);
                                            List<Map<String, Object>> renList = statusLogMapper.queryCloudCount(queryMap);
                                            renList.forEach(s -> renIdKeyList.add(s.get("phone").toString()));
                                            renIdKeyList.forEach(s -> builder6.append(s).append(","));
                                            redisUtil.setValueNew(renIdKey, builder6.toString());
                                        } else {
                                            redisUtil.setValueNew(backKey, "0");
                                            redisUtil.setValueNew(abKey, "0");
                                            redisUtil.setValueNew(seeKey, "0");
                                            redisUtil.setValueNew(daoKey, "0");
                                            redisUtil.setValueNew(buyKey, "0");
                                            redisUtil.setValueNew(signKey, "0");

                                            redisUtil.setValueNew(seeIdKey, "");
                                            redisUtil.setValueNew(daoIdKey, "");
                                            redisUtil.setValueNew(renIdKey, "");
                                            redisUtil.setValueNew(buyIdKey, "");
                                            redisUtil.setValueNew(signIdKey, "");
                                            redisUtil.setValueNew(cancelIdKey, "");
                                        }
                                    }
                                } catch (Exception e) {
                                    logger.error("设置云迹统计数据定时失败", e);
                                }
                            }
                        });

                    }
                }
            }
        } catch (Exception e) {
            logger.error("设置云迹统计数据定时失败", e);
        }

    }

    /**
     * 平台客户推送至CRM
     */
    @Override
    public void syncPlatCustomers() {
        //查询满一个月的平台客户
        List<CustomerEntity> list = customerMapper.queryMonthPlatCustomers();
        //同步通知CRM
        if (CollectionUtils.isNotEmpty(list)) {
            for (CustomerEntity ce : list) {
                try {
                    post2CRM(ce);
                    ce.setCrmSync("1");
                    customerMapper.updateSync(ce);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

    }

    private String post2CRM(CustomerEntity customer) throws Exception {

        if (Strings.isNullOrEmpty(customer.getPhone()) || Strings.isNullOrEmpty(
                customer.getCityCode()) || Strings.isNullOrEmpty(customer.getActSource())) {
            throw new Exception("平台客户-CRM-参数不完整");
        }
        String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CUSTOMER.ADD.URL");
        URLEncoder.encode(crmUrl);

        final String url = crmUrl;
        final String mobile = customer.getPhone();
        final String city = customer.getCityCode();
        final String activename = customer.getActSource();
        final String activefrom = "563";//新来源
        final String username = customer.getName();
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    List<NameValuePair> pairs = new ArrayList<>();
                    pairs.add(new BasicNameValuePair("mobile", mobile));
                    pairs.add(new BasicNameValuePair("city", city));
                    pairs.add(new BasicNameValuePair("activename", activename));
                    pairs.add(new BasicNameValuePair("activefrom", activefrom));
                    pairs.add(new BasicNameValuePair("username", username));
                    String result = HttpClientUtil.doGet(url, pairs);
                    logger.info("call CRM add customer status result:{}", result);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        });

        return "";
    }

    /**
     * 推送外部客户至crm
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void putExterCusToCrm() {
        try {
            String key = "set_external_job";
            String value = "external";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Date checkDate = DateTimeUtils.getYearsAgo(new Date(), 1);
                Map<String, Object> map = new HashMap<>(10);
                map.put("crmSync", 0);
                map.put("putTime", checkDate);
                List<ExternalCustomerEntity> list = externalCusMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (ExternalCustomerEntity e : list) {
                        postToCrm(e);
                        e.setCrmSync(1);
                        externalCusMapper.update(e);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("推送外部客户至crm失败", e);
        }
    }

    private void postToCrm(ExternalCustomerEntity customer) throws Exception {
        if (Strings.isNullOrEmpty(customer.getPhone()) || Strings.isNullOrEmpty(
                customer.getCityCode()) || Strings.isNullOrEmpty(customer.getActSource())) {
            throw new Exception("外部客户推送crm参数不完整");
        }
        String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CUSTOMER.ADD.URL");
        URLEncoder.encode(crmUrl);

        final String url = crmUrl;
        final String mobile = customer.getPhone();
        final String city = customer.getCityCode();
        final String activeName = customer.getActSource();
        final String activeFrom = "564";
        final String userName = customer.getName();

        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    List<NameValuePair> pairs = new ArrayList<>();
                    pairs.add(new BasicNameValuePair("mobile", mobile));
                    pairs.add(new BasicNameValuePair("city", city));
                    pairs.add(new BasicNameValuePair("activename", activeName));
                    pairs.add(new BasicNameValuePair("activefrom", activeFrom));
                    pairs.add(new BasicNameValuePair("username", userName));
                    String result = HttpClientUtil.doGet(url, pairs);
                    logger.info("推送外部客户至crm result:{}", result);
                } catch (Exception e) {
                    logger.error("推送外部客户至crm失败", e);
                }
            }
        });
    }

    private static List removeDuplicate(List<Integer> list) {
        HashSet<Integer> h = new HashSet<>(list);
        list.clear();
        list.addAll(h);
        return list;
    }

    /**
     * 设置云迹年度报表
     */
    @Override
    public void setCloudReportCountYear() {
        String key = "set_cloud_create_year_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date date = new Date();
            String now = DateTimeUtils.getDateString(date, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            int year = Integer.parseInt(now.substring(0, 4));
            Date endDate = getCurrYearFirst(year);
            Date startDate = DateTimeUtils.getUpdateDateTime(endDate, Calendar.YEAR, -1);
            Date oldDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.DAY_OF_MONTH, 1);
            String startTime = DateTimeUtils.getDateString(startDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endTime = DateTimeUtils.getDateString(endDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            setReportCount(startTime, endTime, oldDate, 3);
        }
    }

    /**
     * 设置云迹季度报表
     */
    @Override
    public void setCloudReportCountJi() {
        String key = "set_cloud_create_Ji_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date startDate = DateTimeUtils.getCurrentQuarterStartTime();
            Date endDate = DateTimeUtils.getCurrentQuarterEndTime();
            startDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.MONTH, -3);
            endDate = DateTimeUtils.getUpdateDateTime(endDate, Calendar.MONTH, -3);
            Date oldDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.DAY_OF_MONTH, 1);
            String startTime = DateTimeUtils.getDateString(startDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endTime = DateTimeUtils.getDateString(endDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            setReportCount(startTime, endTime, oldDate, 1);
        }
    }

    /**
     * 设置云迹半年报表
     */
    @Override
    public void setCloudReportCountBn() {
        String key = "set_cloud_create_Bn_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date startDate = DateTimeUtils.getCurrentQuarterStartTime();
            Date endDate = DateTimeUtils.getCurrentQuarterEndTime();
            startDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.MONTH, -6);
            endDate = DateTimeUtils.getUpdateDateTime(endDate, Calendar.MONTH, -3);
            Date oldDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.DAY_OF_MONTH, 1);
            String startTime = DateTimeUtils.getDateString(startDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endTime = DateTimeUtils.getDateString(endDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            setReportCount(startTime, endTime, oldDate, 2);
        }
    }

    private Date getCurrYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 设置云迹报表缓存（根据创建人） 月度报表
     */
    @Override
    public void setCloudReportCount() {
        String key = "set_cloud_create_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date date = new Date();
            Map<String, String> monthMap = getMonthDate(date);
            Date oldDate = DateTimeUtils.getMonthAgo(date, 1);
            String startTime = monthMap.get("first");
            String endTime = monthMap.get("last");
            setReportCount(startTime, endTime, oldDate, 0);
        }
    }

    private void setReportCount(String startTime, String endTime, Date oldDate, final int type) {
        Map<String, Object> map = new HashMap<>(10);
        map.put("group", 1);
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        List<CloudActivityEntity> activeList1 = activityMapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(activeList1)) {
            final List<CloudActivityEntity> activeList = activeList1;
            final String timeStart = startTime;
            final String timeEnd = endTime;
            final Date date1 = oldDate;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    for (final CloudActivityEntity e : activeList) {
                        //开启线程池跑定时，防止超时
                        int createId = e.getCreateId();
                        String createName = e.getCreateName();
                        String city = e.getCity();

                        List<Integer> actIdList = new ArrayList<>();
                        Map<String, Object> map = new HashMap<>(5);
                        map.put("group", 0);
                        map.put("createId", createId);
                        map.put("startTime", timeStart);
                        map.put("endTime", timeEnd);
                        List<CloudActivityEntity> activeListNew = activityMapper.queryByConditions(map);

                        Map<String, Object> map1 = new HashMap<>(5);
                        map.put("city", city);
                        map1.put("createId", createId);
                        map1.put("startTime", timeStart);
                        map1.put("endTime", timeEnd);
                        map1.put("type", type);
                        List<CloudCountEntity> cloudList = cloudCountMapper.queryByConditions(map1);
                        if (CollectionUtils.isNotEmpty(cloudList)) {
                            continue;
                        }
                        if (CollectionUtils.isNotEmpty(activeListNew)) {
                            for (CloudActivityEntity l : activeListNew) {
                                actIdList.add(l.getId());
                            }
                            Map<String, Object> searchMap = new HashMap<>(10);
                            searchMap.put("actIdList", actIdList);
                            searchMap.put("group", 1);
                            List<CloudCustomerEntity> countList = cloudCustomerMapper.queryByConditions(searchMap);
                            int count = countList.size();

                            searchMap.put("type", 1);
                            List<CloudCustomerEntity> waitList = cloudCustomerMapper.queryByConditions(searchMap);
                            searchMap.put("type", 2);
                            List<CloudCustomerEntity> sendGroupList = cloudCustomerMapper.queryByConditions(searchMap);

                            searchMap.put("group", 0);
                            List<CloudCustomerEntity> sendList = cloudCustomerMapper.queryByConditions(searchMap);
                            List<Integer> idList = new ArrayList<>();
                            List<Integer> seaIdList = new ArrayList<>();
                            List<Integer> idAllList = new ArrayList<>();
                            if (CollectionUtils.isNotEmpty(sendList)) {
                                for (CloudCustomerEntity c : sendList) {
                                    if (c.getManagerId() > 0) {
                                        idList.add(c.getCustomerId());
                                    } else {
                                        seaIdList.add(c.getCustomerId());
                                    }
                                }
                                Date time = sendList.get(0).getCreateTime();
                                dealList(idList, idAllList, time, 0);
                                dealSeaList(seaIdList, idAllList, time);
                                idAllList = removeDuplicate(idAllList);

                                //其中跟进数 跟进率 其中意向数（AB） 有效率	其中约看数	约看转化率	其中到访数	到访转化率	其中认购数	其中签约数	成交数	成交转化率
                                if (CollectionUtils.isNotEmpty(idAllList)) {
                                    //已跟进 不计算自动新增的回访
                                    Map<String, Object> backMap = new HashMap<>(10);
                                    backMap.put("idList", idAllList);
                                    backMap.put("notId", 1);
                                    backMap.put("startTime", timeStart);
                                    backMap.put("endTime", timeEnd);
                                    List<Map<String, Object>> backList = callbackMapper.queryCloudBackCount(backMap);
                                    int backCount = backList.size();

                                    Map<String, Object> queryMap = new HashMap<>(5);
                                    queryMap.put("abType", 1);
                                    queryMap.put("idList", idAllList);
                                    queryMap.put("startTime", timeStart);
                                    queryMap.put("endTime", timeEnd);
                                    List<CustomerEntity> abList = customerMapper.queryCloudCount(queryMap);
                                    int abCount = abList.size();

                                    queryMap.put("abType", 0);
                                    queryMap.put("status", 1);
                                    List<Map<String, Object>> seeList = statusLogMapper.queryCloudCount(queryMap);
                                    int seeCount = seeList.size();

                                    queryMap.put("status", 2);
                                    List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
                                    int daoCount = daoList.size();

                                    queryMap.put("status", 4);
                                    List<Map<String, Object>> buyList = statusLogMapper.queryCloudCount(queryMap);

                                    queryMap.put("status", 5);
                                    List<Map<String, Object>> signList = statusLogMapper.queryCloudCount(queryMap);

                                    queryMap.put("status", 0);
                                    queryMap.put("buyStatus", 1);
                                    List<Map<String, Object>> successList = statusLogMapper.queryCloudCount(queryMap);

                                    String paiRate = dealRate(sendGroupList.size(), count);
                                    String backRate = dealRate(backCount, sendGroupList.size());
                                    String abRate = dealRate(abCount, backCount);
                                    String seeRate = dealRate(seeCount, backCount);
                                    String daoRate = dealRate(daoCount, seeCount);
                                    String successRate = dealRate(successList.size(), daoCount);
                                    CloudCountEntity entity = new CloudCountEntity();
                                    entity.setName(createName);
                                    entity.setCount(count);
                                    entity.setWaitCount(waitList.size());
                                    entity.setSendCount(sendGroupList.size());
                                    entity.setPaiRate(paiRate);
                                    entity.setBackCount(backCount);
                                    entity.setBackRate(backRate);
                                    entity.setAbCount(abCount);
                                    entity.setAbRate(abRate);
                                    entity.setSeeCount(seeCount);
                                    entity.setSeeRate(seeRate);
                                    entity.setDaoCount(daoCount);
                                    entity.setDaoRate(daoRate);
                                    entity.setBuyCount(buyList.size());
                                    entity.setSignCount(signList.size());
                                    entity.setSuccessCount(successList.size());
                                    entity.setSuccessRate(successRate);
                                    entity.setCreateId(createId);
                                    entity.setCreateTime(date1);
                                    entity.setCity(city);
                                    entity.setType(type);
                                    cloudCountMapper.save(entity);
                                }
                            } else {
                                CloudCountEntity entity = new CloudCountEntity();
                                entity.setName(createName);
                                entity.setCount(count);
                                entity.setWaitCount(waitList.size());
                                entity.setSendCount(sendGroupList.size());
                                entity.setPaiRate("");
                                entity.setBackCount(0);
                                entity.setBackRate("");
                                entity.setAbCount(0);
                                entity.setAbRate("");
                                entity.setSeeCount(0);
                                entity.setSeeRate("");
                                entity.setDaoCount(0);
                                entity.setDaoRate("");
                                entity.setBuyCount(0);
                                entity.setSignCount(0);
                                entity.setSuccessCount(0);
                                entity.setSuccessRate("");
                                entity.setCreateTime(date1);
                                entity.setCreateId(createId);
                                entity.setCity(city);
                                entity.setType(type);
                                cloudCountMapper.save(entity);
                            }
                        }
                    }
                }
            });

        }
    }

    private String dealRate(int count1, int count2) {
        String rate = "";
        if (count1 > 0 && count2 > 0) {
            double d = (double) count1 / count2;
            DecimalFormat df = new DecimalFormat("0.00%");
            rate = df.format(d);
        }
        return rate;
    }

    private void dealList(List<Integer> idList, List<Integer> idAllList, Date time, int type) {
        for (Integer id : idList) {
            CustomerEntity entity = customerMapper.queryById(id);
            if (null != entity && StringUtils.isNotBlank(entity.getPhone()) && entity.getManagerId() != null) {
                String phone = entity.getPhone();
                Map<String, Object> map = new HashMap<>(10);
                map.put("phone", phone);
                map.put("isPrivate", 1);
                int managerId = entity.getManagerId();
                map.put("managerId", managerId);
                if (type == 1) {
                    map.put("createTime", time);
                }
                List<CustomerEntity> customerList = customerMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(customerList)) {
                    for (CustomerEntity c : customerList) {
                        idAllList.add(c.getId());
                    }
                }
            }
        }
    }

    private void dealSeaList(List<Integer> seaIdList, List<Integer> idAllList, Date time) {
        for (Integer id : seaIdList) {
            CustomerEntity entity = customerMapper.queryById(id);
            if (null != entity && StringUtils.isNotBlank(entity.getPhone()) && StringUtils.isNotBlank(entity.getLastManager())) {
                String phone = entity.getPhone();
                String lastManager = entity.getLastManager();
                Map<String, Object> map = new HashMap<>(10);
                map.put("phone", phone);
                map.put("isPrivate", 1);
                map.put("lastManager", lastManager);
                map.put("createTime", time);
                List<CustomerEntity> customerList = customerMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(customerList)) {
                    for (CustomerEntity c : customerList) {
                        idAllList.add(c.getId());
                    }
                }
            }
        }
    }

    @Override
    public List<Map<String, Object>> queryListByStatus(List<CloudCustomerEntity> sendList, Map<String, Object> queryMap) {
        List<Integer> idList = new ArrayList<>();
        List<Integer> seaIdList = new ArrayList<>();
        List<Integer> idAllList = new ArrayList<>();
        List<Map<String, Object>> list = new ArrayList<>();
        for (CloudCustomerEntity c : sendList) {
            if (c.getManagerId() > 0) {
                idList.add(c.getCustomerId());
            } else {
                seaIdList.add(c.getCustomerId());
            }
        }
        Date time = sendList.get(0).getCreateTime();
        dealList(idList, idAllList, time, 0);
        dealSeaList(seaIdList, idAllList, time);
        idAllList = removeDuplicate(idAllList);
        int createId = Integer.parseInt(queryMap.get("createId").toString());
        UserEntity user = usermapper.getById(createId);
        String createName = "";
        if (null != user) {
            createName = user.getRealName();
        }
        //姓名 手机号 安家顾问 创建人 到访项目 到访时间 现在状态
        if (CollectionUtils.isNotEmpty(idAllList)) {
            queryMap.put("idList", idAllList);
            List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
            if (CollectionUtils.isNotEmpty(daoList)) {
                for (Map<String, Object> d : daoList) {
                    Map<String, Object> putMap = new HashMap<>(20);
                    putMap.put("name", d.get("name"));
                    putMap.put("phone", d.get("phone"));
                    putMap.put("createName", createName);
                    int projectId = Integer.parseInt(d.get("projectId").toString());
                    ProjectEntity project = projectMapper.getById(projectId);
                    if (null != project) {
                        putMap.put("projectName", project.getProjectName());
                    } else {
                        putMap.put("projectName", "");
                    }
                    putMap.put("occurTime", d.get("occurTime"));
                    if (null != d.get("managerName") && StringUtils.isNotBlank(d.get("managerName").toString())) {
                        putMap.put("managerName", d.get("managerName"));
                        putMap.put("customerStatus", "私客");
                    } else {
                        putMap.put("managerName", "");
                        putMap.put("customerStatus", "公海");
                    }
                    list.add(putMap);
                }
            }
        }
        return list;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateJgStatus() {
        String key = "update_jg_status_job";
        String value = "jgStatus";
        try {
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                List<Integer> list = new ArrayList<>();
                Map<String, Object> map = new HashMap<>(5);
                map.put("showStatus", 1);
                List<ProjectEntity> projectList = projectMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(projectList)) {
                    for (ProjectEntity p : projectList) {
                        list.add(p.getId());
                    }
                }
                customerProject.updateJgData(list, 2, "经管系统");
            }
        } catch (Exception e) {
            logger.error("定时同步经管状态失败", e);
        }
    }

    /**
     * 获取上个月第一天与最后一天
     *
     * @param date
     * @return
     */
    public static Map<String, String> getMonthDate(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        Date theDate = calendar.getTime();

        //上个月第一天
        GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
        gcLast.setTime(theDate);
        gcLast.set(Calendar.DAY_OF_MONTH, 1);
        String dayFirst = df.format(gcLast.getTime());
        StringBuilder str = new StringBuilder().append(dayFirst).append(" 00:00:00");
        dayFirst = str.toString();

        //上个月最后一天
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DATE, 1);
        calendar.add(Calendar.DATE, -1);
        String dayLast = df.format(calendar.getTime());
        StringBuilder endStr = new StringBuilder().append(dayLast).append(" 23:59:59");
        dayLast = endStr.toString();

        Map<String, String> map = new HashMap<>(10);
        map.put("first", dayFirst);
        map.put("last", dayLast);
        return map;
    }

}
