/**
 * Description: 营销活动WS接口
 * Copyright:   Copyright (c)2017
 * Company:     江苏三六五网络股份有限公司
 *
 * @author: 江苏三六五网络股份有限公司
 * @version: 1.0
 * Create at:   2017-12-05 下午 19:20:59
 * <p>
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2017-12-05   江苏三六五网络股份有限公司   1.0         Initial
 */
package com.house365.ws.interfaces.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.house365.beans.entity.*;
import com.house365.beans.system.QueryParams;
import com.house365.beans.vo.MarketingActivityVo;
import com.house365.commons.system.HttpClientUtil;
import com.house365.rest.context.Parameter;
import com.house365.rest.exception.ServiceRunException;
import com.house365.rest.parameter.House365RestObject;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.web.util.StringUtils;
import com.house365.ws.beans.request.MarketingActivityListRequest;
import com.house365.ws.beans.request.MarketingActivityRequest;
import com.house365.ws.beans.response.MarketingActivityListResponse;
import com.house365.ws.beans.response.MarketingActivityResponse;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.dao.mapper.CrmSourceMapper;
import com.house365.ws.dao.mapper.CustomerMapper;
import com.house365.ws.dao.mapper.DictionaryMapper;
import com.house365.ws.dao.mapper.MarketingActivityMapper;
import com.house365.ws.interfaces.server.IMarketingActivity;
import com.house365.ws.service.interfaces.IMarketCustomerService;
import com.house365.ws.service.interfaces.IMarketingActivityService;
import com.house365.ws.system.ReturnResult;
import com.house365.ws.util.Constant;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
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.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 营销活动WS接口<br>
 *
 * @author 江苏三六五网络股份有限公司
 * @version 1.0, 2017-12-05
 * @see
 * @since 1.0
 */
@Service("marketingActivity")
public class MarketingActivityImpl implements IMarketingActivity {
    /**
     * 日志记录器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger("MarketingActivityImpl");

    /**
     * 营销活动服务对象
     */
    @Autowired
    private IMarketingActivityService<MarketingActivityEntity> marketingActivityService;

    @Autowired
    private MarketingActivityMapper marketingactivitymapper;

    @Autowired
    private IMarketCustomerService marketCustomer;

    @Autowired
    private RedisUtilsInterface redisUtils;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private DictionaryMapper dictionaryMapper;

    @Autowired
    private CrmSourceMapper crmSourceMapper;


    @Value("${CRM.CUSTOMERQUERY.URL}")
    private String crmQueryUrl;
    @Value("${CRM.SEEQUERY.URL}")
    private String crmSeeUrl;

    /**
     * 营销活动列表查询
     *
     * @param request 营销活动列表查询请求
     * @return 营销活动列表查询响应
     */
    @Override
    public MarketingActivityListResponse getMarketingActivityList(MarketingActivityListRequest request) {
        MarketingActivityListResponse response = new MarketingActivityListResponse();
        try {
            QueryParams<MarketingActivityEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            queryParams.setOrderColumn(request.getOrderColumn());
            queryParams.setOrderMode(request.getOrderMode());
            List<MarketingActivityEntity> marketingActivitys = marketingActivityService.queryByPage(queryParams);
            response.setPaging(queryParams.getPaging());
            response.setObjectList(marketingActivitys);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 保存营销活动查询条件
     *
     * @param request 营销活动请求
     * @return 保存营销活动响应
     */
    @Override
    public MarketingActivityResponse addQueryCond(MarketingActivityRequest request) {
        MarketingActivityResponse response = new MarketingActivityResponse();
        try {
            MarketingActivityEntity entity = request.getEntity();
            marketingactivitymapper.addQueryCond(entity);
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 保存营销活动
     *
     * @param request 营销活动请求
     * @return 保存营销活动响应
     */
    @Override
    public MarketingActivityResponse addMarketingActivity(MarketingActivityRequest request) {
        MarketingActivityResponse response = new MarketingActivityResponse();
        try {
            MarketingActivityEntity entity = request.getEntity();
            marketingActivityService.save(entity);
            response.setEntity(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    @Override
    public MarketingActivityListResponse queryAllPullCount(MarketingActivityListRequest request) {
        MarketingActivityListResponse response = new MarketingActivityListResponse();
        try {
            QueryParams<MarketingActivityEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            queryParams.setOrderColumn(request.getOrderColumn());
            queryParams.setOrderMode(request.getOrderMode());
            Integer marketingActivitys = marketingActivityService.queryAllPullCount(queryParams);
            queryParams.getPaging().setRecords(marketingActivitys == null ? 0 : marketingActivitys);
            response.setPaging(queryParams.getPaging());
            response.setObjectList(null);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 删除营销活动通过唯一标识
     *
     * @param id 唯一标识
     * @return 删除营销活动响应
     */
    @Override
    public MarketingActivityResponse deleteMarketingActivityById(Integer id) {
        MarketingActivityResponse response = new MarketingActivityResponse();
        try {
            marketingActivityService.setDisable(id);
            response.setEntity(marketingActivityService.getById(id));
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 修改营销活动
     *
     * @param request 修改营销活动请求
     * @return 修改营销活动响应
     */
    @Override
    public MarketingActivityResponse updateMarketingActivity(MarketingActivityRequest request) {
        MarketingActivityResponse response = new MarketingActivityResponse();
        try {
            marketingActivityService.update(request.getEntity());
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    @Override
    public MarketingActivityEntity getQueryCondByActiveId(Integer id) {
        return marketingactivitymapper.getQueryCondByActiveId(id);
    }

    /**
     * 通过ID获取营销活动
     *
     * @param id 唯一标识
     * @return 通过ID获取营销活动响应
     */
    @Override
    public MarketingActivityResponse getMarketingActivityById(Integer id) {
        MarketingActivityResponse response = new MarketingActivityResponse();
        try {
            MarketingActivityEntity entity = marketingActivityService.getById(id);
            response.setEntity(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    @Override
    public void importCustomers(House365RestObject object, DepartmentEntity city) {
        ExecutorService pool = Executors.newFixedThreadPool(5);
        try {
            Integer total = Integer.valueOf(object.getTotal());
            Integer activeId = Integer.valueOf(String.valueOf(object.getEntity()));
            Map<String, Object> nameValuePair = (Map<String, Object>) object.getParaMap();
            List<NameValuePair> nameValuePairList = new ArrayList<>();
            for (Map.Entry entry : nameValuePair.entrySet()) {
                nameValuePairList.add(
                        new BasicNameValuePair(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())));
            }
            //mark assess is end
            redisUtils.setValueExpireNew("active:process:" + activeId, "0", 1, TimeUnit.HOURS);
            redisUtils.addKeyVal("active:total:" + activeId, String.valueOf(total));

            if (redisUtils.hasKey("active:protect:" + activeId)) {
                redisUtils.deleteByKeyNew("active:protect:" + activeId);
            }
            if (redisUtils.hasKey("active:done:" + activeId)) {
                redisUtils.deleteByKeyNew("active:done:" + activeId);
            }

            ArrayList<Future<Integer>> futures = new ArrayList<>();
            ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService(pool);
            total = Strings.isNullOrEmpty(object.getTotal()) ? 50 : Integer.parseInt(object.getTotal());
            int limit = 1000;
            int num = (total % limit > 0) ? (total / limit) + 1 : (total / limit);
            if (num > 3) {
                num = 3;
            }
            for (int i = 1; i <= num; i++) {
                //arraylist 非线程安全,删除时报错，重新组织条件列表
                List<NameValuePair> localList = new ArrayList<>();
                for (NameValuePair nameValuePair1 : nameValuePairList) {
                    if (!"page".equalsIgnoreCase(nameValuePair1.getName()) && !"limit".equalsIgnoreCase(nameValuePair1.getName())) {
                        localList.add(nameValuePair1);
                    }
                }

                localList.add(new BasicNameValuePair("page", String.valueOf(i)));
                localList.add(new BasicNameValuePair("limit", String.valueOf(limit)));
                GetCustomers t = new GetCustomers(i, limit, activeId, localList, total, city.getDescripition());
                Future<Integer> f = completionService.submit(t);
                futures.add(f);
            }

            int doenTask = 0;
            while (doenTask < futures.size()) {
                Integer res = completionService.take().get();
                LOGGER.info("task done total handle num [{}]", res);
                doenTask++;
            }
            // 关闭线程池。
            pool.shutdown();
            redisUtils.addKeyVal("active:process:" + activeId, "1");

            //通知CRM所使用的数据
            MarketCustomerEntity mce = new MarketCustomerEntity();
            mce.setActiveId(activeId);
            List<MarketCustomerEntity> useList = marketCustomer.getUseMarketingActivity(mce);
            if (CollectionUtils.isNotEmpty(useList)) {
                String confirmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CONFIRM.URL");
                List<NameValuePair> inParam = new ArrayList<>();
                inParam.add(new BasicNameValuePair("city", city.getDescripition()));
                inParam.add(new BasicNameValuePair("timestamp", String.valueOf(System.currentTimeMillis() / 1000)));
                JSONArray array = new JSONArray();
                for (int k = 0; k < useList.size(); k++) {
                    JSONObject jo = new JSONObject();
                    jo.put("phone", useList.get(k).getPhone());
                    jo.put("crm_id", useList.get(k).getCrmId());
                    array.add(jo);
                }
                inParam.add(new BasicNameValuePair("data", array.toString()));
                String confirmresult = HttpClientUtil.doPost(confirmUrl, inParam);
                LOGGER.info("******通知CRM营销拉取客户信息返回结果:" + confirmresult);
            }

            MarketingActivityRequest request = new MarketingActivityRequest();
            MarketingActivityEntity entity = marketingActivityService.getById(activeId);
            entity.setGainCount(redisUtils.getIntegerByKey("active:done:" + activeId));
            entity.setProtectCount(redisUtils.getIntegerByKey("active:protect:" + activeId));
            request.setEntity(entity);
            updateMarketingActivity(request);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            pool.shutdown();
        }
    }

    /**
     * 设置crm来源名称
     * @param entity
     */
    void setSignSourceName(MarketCustomerEntity entity) {
        if(org.apache.commons.lang3.StringUtils.isNotBlank(entity.getSignupSourceId())) {
            int sourceId = Integer.parseInt(entity.getSignupSourceId());
            Map<String, Object> map = new HashMap<>(5);
            map.put("sourceId", sourceId);
            List<CrmSourceEntity> list = crmSourceMapper.queryByConditions(map);
            if (CollectionUtils.isNotEmpty(list)) {
                entity.setSignupSourceName(list.get(0).getSourceName());
            }
        }else {
            entity.setSignupSourceName("");
        }
    }

    @Override
    public void importCustomerNew(MarketingActivityVo vo, Map<String, Object> paraMap, DepartmentEntity city) {
        try {
            Integer total = vo.getEntity().getExpectExtractCount();
            Integer activeId = vo.getEntity().getId();
            List<NameValuePair> nameValuePairList = new ArrayList<>();
            for (Map.Entry entry : paraMap.entrySet()) {
                nameValuePairList.add(
                        new BasicNameValuePair(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())));
            }
            //mark assess is end
            redisUtils.setValueExpireNew("active:process:" + activeId, "0", 1, TimeUnit.HOURS);
            redisUtils.addKeyVal("active:total:" + activeId, String.valueOf(total));

            if (redisUtils.hasKey("active:protect:" + activeId)) {
                redisUtils.deleteByKeyNew("active:protect:" + activeId);
            }
            if (redisUtils.hasKey("active:done:" + activeId)) {
                redisUtils.deleteByKeyNew("active:done:" + activeId);
            }
            List<Map<String, Object>> seeList = new ArrayList<>();
            List<Map<String, Object>> crmList = new ArrayList<>();

            Map<String, Object> dicMap = new HashMap<>(10);
            dicMap.put("city", city.getDescripition());
            dicMap.put("dicKey", "customer.protect.day");
            List<DictionaryEntity> dictionaryList = dictionaryMapper.getNoApproximateConfig(dicMap);

            //获取浏览轨迹的list
            String cityName = city.getName();
            List<NameValuePair> pairList = new ArrayList<>();
            String projectName = vo.getProjectName();
            String[] projectNames = projectName.split(",");
            for (int j = 0; j < projectNames.length; j++) {
                String name = projectNames[j].split("\\(")[0];
                pairList.add(new BasicNameValuePair("items[]", name));
            }
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String startTime = formatter.format(vo.getSeeStartTime());
            String endTime = formatter.format(vo.getSeeEndTime());
            pairList.add(new BasicNameValuePair("city_name", cityName));
            pairList.add(new BasicNameValuePair("from", startTime));
            pairList.add(new BasicNameValuePair("to", endTime));
            pairList.add(new BasicNameValuePair("lower", String.valueOf(vo.getSeeCount())));
            pairList.add(new BasicNameValuePair("has_login_account", "true"));
            pairList.add(new BasicNameValuePair("limit", "2000"));
            String seeResult = HttpClientUtil.doGet(crmSeeUrl, pairList);
            if (seeResult != null) {
                JSONArray jsonarray = JSONArray.fromObject(seeResult);
                seeList = (List) JSONArray.toCollection(jsonarray, Map.class);
                LOGGER.info("浏览轨迹接口返回数据：", seeResult);
            } else {
                List<String> params = new ArrayList<>();
                for (NameValuePair pair : pairList) {
                    params.add(pair.getName() + "=" + pair.getValue());
                }
                LOGGER.error("浏览轨迹接口URL:[{}] ", crmSeeUrl + Joiner.on("&").join(params));
            }
            //获取浏览轨迹的list结束

            if (vo.getEntity().getApplyStartTime() != null && vo.getEntity().getApplyEndTime() != null) {
                nameValuePairList.add(new BasicNameValuePair("page", "1"));
                nameValuePairList.add(new BasicNameValuePair("limit", "1000"));
                String preResult = HttpClientUtil.doGet(crmQueryUrl, nameValuePairList);
                JSONObject jsonObject = JSONObject.fromObject(preResult);
                if (jsonObject.containsKey("total")) {
                    crmList = (List) jsonObject.get("docs");
                }
            }

            //判断取两个list的交集
            if (vo.getEntity().getApplyStartTime() != null && vo.getEntity().getApplyEndTime() != null) {
                if (CollectionUtils.isNotEmpty(crmList)) {
                    List<Map<String, Object>> newList = new ArrayList<>();
                    for (Map<String, Object> m : crmList) {
                        String phone = m.get("phone").toString();
                        if (CollectionUtils.isNotEmpty(seeList)) {
                            for (Map<String, Object> o : seeList) {
                                if (o.get("login_account").equals(phone)) {
                                    newList.add(m);
                                }
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(newList)) {
                        if (CollectionUtils.isNotEmpty(dictionaryList) && !"0".equals(dictionaryList.get(0).getDicValue())) {
                            //过滤400已跟踪的数据
                            Map<String, Object> hotMap = new HashMap<>(10);
                            hotMap.put("status", 0);
                            hotMap.put("createSource", "HOTLINE");
                            hotMap.put("isProtect", dictionaryList.get(0).getDicValue());
                            hotMap.put("isAdd", 1);
                            hotMap.put("city", city.getDescripition());
                            List<CustomerEntity> list = customerMapper.queryForAddHot(hotMap);
                            if (CollectionUtils.isNotEmpty(list)) {
                                dealList(list, newList, 2);
                            }
                        }
                        for (Map<String, Object> m : newList) {
                            MarketCustomerEntity customerEntity = MarketingActivityImpl.getCustomer(m);
                            customerEntity.setActiveId(activeId);
                            if (marketCustomer.queryProtectCount(customerEntity.getPhone()) > 0) {
                                increaseProtectKey(activeId);
                            } else {
                                increaseDoneKey(activeId);
                                setSignSourceName(customerEntity);
                                marketCustomer.save(customerEntity);
                            }
                            decreaseKey(activeId);
                        }
                    }
                    //通知CRM所使用的数据
                    MarketCustomerEntity mce = new MarketCustomerEntity();
                    mce.setActiveId(activeId);
                    List<MarketCustomerEntity> uselist = marketCustomer.getUseMarketingActivity(mce);
                    if (uselist != null && uselist.size() > 0) {
                        String confirmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CONFIRM.URL");
                        List<NameValuePair> inParam = new ArrayList<>();
                        inParam.add(new BasicNameValuePair("city", city.getDescripition()));
                        inParam.add(new BasicNameValuePair("timestamp", String.valueOf(System.currentTimeMillis() / 1000)));
                        JSONArray array = new JSONArray();
                        for (int k = 0; k < uselist.size(); k++) {
                            JSONObject jo = new JSONObject();
                            jo.put("phone", uselist.get(k).getPhone());
                            jo.put("crm_id", uselist.get(k).getCrmId());
                            array.add(jo);
                        }
                        inParam.add(new BasicNameValuePair("data", array.toString()));
                        String confirmresult = HttpClientUtil.doPost(confirmUrl, inParam);
                        LOGGER.info("******通知CRM营销拉取客户信息返回结果:" + confirmresult);
                    }
                }
            } else {
                //判断只取浏览轨迹的list
                if (CollectionUtils.isNotEmpty(seeList)) {
                    if (CollectionUtils.isNotEmpty(dictionaryList) && !"0".equals(dictionaryList.get(0).getDicValue())) {
                        //过滤400已跟踪的数据
                        Map<String, Object> hotMap = new HashMap<>(10);
                        hotMap.put("status", 0);
                        hotMap.put("createSource", "HOTLINE");
                        hotMap.put("isProtect", dictionaryList.get(0).getDicValue());
                        hotMap.put("isAdd", 1);
                        hotMap.put("city", city.getDescripition());
                        List<CustomerEntity> list = customerMapper.queryForAddHot(hotMap);
                        if (CollectionUtils.isNotEmpty(list)) {
                            dealList(list, seeList, 1);
                        }
                    }
                    for (Map<String, Object> m : seeList) {
                        Map<String, Object> map = new HashMap<>(5);
                        map.put("phone", m.get("login_account"));
                        MarketCustomerEntity customerEntity = MarketingActivityImpl.getCustomer(map);
                        customerEntity.setActiveId(activeId);
                        customerEntity.setCityCode(city.getDescripition());
                        customerEntity.setCityName(city.getName());
                        customerEntity.setCrmSync("0");
                        if (marketCustomer.queryProtectCount(customerEntity.getPhone()) > 0) {
                            increaseProtectKey(activeId);
                        } else {
                            increaseDoneKey(activeId);
                            //同时获取signupSourceName
                            setSignSourceName(customerEntity);
                            marketCustomer.save(customerEntity);
                        }
                        decreaseKey(activeId);
                    }
                }
            }

            redisUtils.addKeyVal("active:process:" + activeId, "1");

//            marketCustomer.updateSignupSourceName();

            MarketingActivityRequest request = new MarketingActivityRequest();
            MarketingActivityEntity entity = marketingActivityService.getById(activeId);
            entity.setGainCount(redisUtils.getIntegerByKey("active:done:" + activeId));
            entity.setProtectCount(redisUtils.getIntegerByKey("active:protect:" + activeId));
            request.setEntity(entity);
            updateMarketingActivity(request);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage(), e);
            LOGGER.error("营销活动导入失败", e);
        }
    }

    private List<Map<String, Object>> dealList(List<CustomerEntity> list, List<Map<String, Object>> listNew, int type) {

        if (CollectionUtils.isNotEmpty(list)) {
            for (CustomerEntity c : list) {
                Iterator<Map<String, Object>> iterator = listNew.iterator();
                while (iterator.hasNext()) {
                    Map<String, Object> iterMap = iterator.next();
                    if (type == 1) {
                        if (iterMap.get("login_account").toString().equals(c.getPhone())) {
                            iterator.remove();
                        }
                    } else if (type == 2) {
                        if (iterMap.get("phone").toString().equals(c.getPhone())) {
                            iterator.remove();
                        }
                    }
                }
            }
        }
        return listNew;
    }

    @Override
    public Integer queryCustomerCountByActive(Integer id) {
        return marketingActivityService.queryCustomerCountByActive(id);
    }

    private synchronized Integer getFinishCount(Integer activeId) {
        return redisUtils.getIntegerByKey("active:done:" + activeId) + redisUtils.getIntegerByKey(
                "active:protect:" + activeId);
    }

    private synchronized Integer getRemainLeftCache(Integer activeId) {
        return redisUtils.getIntegerByKey("active:total:" + activeId);
    }

    private synchronized void decreaseKey(Integer activeId) {
        redisUtils.decreaseByKey("active:total:" + activeId);
    }

    private synchronized Long increaseDoneKey(Integer activeId) {
        return redisUtils.increaseByKey("active:done:" + activeId);
    }

    private synchronized Long increaseProtectKey(Integer activeId) {
        return redisUtils.increaseByKey("active:protect:" + activeId);
    }

    private class GetCustomers implements Callable<Integer> {
        private AtomicInteger atomicInteger = new AtomicInteger(0);
        private int page;
        private int limit;
        private int activeId;
        private int total;
        private List<NameValuePair> nameValuePairList;
        private String city;

        public GetCustomers(int page, int limit, int activeId, List<NameValuePair> nameValuePairList, int total, String city) {
            this.page = page;
            this.limit = limit;
            this.activeId = activeId;
            this.nameValuePairList = new ArrayList<>();
            this.nameValuePairList.addAll(nameValuePairList);
            this.total = total;
            this.city = city;
        }

        @Override
        public Integer call() throws Exception {
            String result = HttpClientUtil.doGet(crmQueryUrl, nameValuePairList, 60000, "utf-8");
            String url = crmQueryUrl + "?";
            List<String> params = new ArrayList<>();
            for (NameValuePair pair : nameValuePairList) {
                params.add(pair.getName() + "=" + pair.getValue());
            }

            url += Joiner.on("&").join(params);
            LOGGER.warn("URL===[{}]", url);

            LOGGER.warn("线程:" + page + "-" + limit + "-" + total + " -> 运行..." + "result:" + result);
            JSONObject resobj = JSONObject.fromObject(result);
            if (resobj.containsKey("docs") && resobj.get("docs") != null) {
                JSONArray objArray = (JSONArray) resobj.get("docs");

                //获取开始时间
                long startTime = System.currentTimeMillis();

                Map<String, Object> dicMap = new HashMap<>(10);
                dicMap.put("city", city);
                dicMap.put("dicKey", "customer.protect.day");
                List<DictionaryEntity> dictionaryList = dictionaryMapper.getNoApproximateConfig(dicMap);
                List<CustomerEntity> list = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(dictionaryList) && !"0".equals(dictionaryList.get(0).getDicValue())) {
                    Map<String, Object> hotMap = new HashMap<>(10);
                    hotMap.put("status", 0);
                    hotMap.put("createSource", "HOTLINE");
                    hotMap.put("isProtect", dictionaryList.get(0).getDicValue());
                    hotMap.put("isAdd", 1);
                    hotMap.put("city", city);
                    list = customerMapper.queryForAddHot(hotMap);
                }
                if (CollectionUtils.isNotEmpty(list)) {
                    try {
                        for (CustomerEntity c : list) {
                            Iterator<Map<String, Object>> iterator = objArray.iterator();
                            while (iterator.hasNext()) {
                                Map<String, Object> iterMap = iterator.next();
                                if (iterMap.get("phone").toString().equals(c.getPhone())) {
                                    iterator.remove();
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                //获取结束时间
                long endTime = System.currentTimeMillis();
                System.out.println("程序运行时间1： " + (endTime - startTime) + "ms");

                long startTime1 = System.currentTimeMillis();
                for (Object c : objArray) {

                    JSONObject cu = (JSONObject) c;
                    MarketCustomerEntity customerEntity = MarketingActivityImpl.getCustomer(cu);

                    //break if handle num bigger then total
                    if (getFinishCount(activeId) >= total) {
                        LOGGER.warn("enough break [{}]",
                                "线程:" + page + "-" + getFinishCount(activeId) + "-" + redisUtils.getIntegerByKey(
                                        "active:total:" + activeId));
                        break;
                    }
                    LOGGER.warn("线程:" + page + "-" + "active:done: " + getFinishCount(activeId) + " active:total:" + getRemainLeftCache(activeId));

                    atomicInteger.set(atomicInteger.get() + 1);
                    //check protect customer and save
                    if (marketCustomer.queryProtectCount(customerEntity.getPhone()) > 0) {
                        if (getFinishCount(activeId) > total || getRemainLeftCache(activeId) <= 0) {
                            LOGGER.warn("break [{}]", "线程:" + page + "-" + redisUtils.getIntegerByKey("active:done:" + activeId));
                            break;
                        }
                        Long count = increaseProtectKey(activeId);
                        LOGGER.warn("protect " + customerEntity.getPhone() + " count :" + count + " total:" + getFinishCount(activeId));
                        continue;
                    } else {
                        if (getFinishCount(activeId) >= total) {
                            LOGGER.warn("break [{}]", "线程:" + page + "-" + redisUtils.getIntegerByKey("active:done:" + activeId));
                            break;
                        }

                        Long count = increaseDoneKey(activeId);
                        LOGGER.warn("线程:" + page + "-" + limit + "-" + total + " done count:" + count + " total:" + getFinishCount(activeId));
                        customerEntity.setActiveId(activeId);
                        //同时获取signupSourceName
                        setSignSourceName(customerEntity);
                        marketCustomer.save(customerEntity);
                        //数据库负载较大，为避免报警，调大阀值
                        Thread.sleep(300);
                    }

                    decreaseKey(activeId);
                }
                long endTime1 = System.currentTimeMillis();
                System.out.println("程序运行时间2： " + (endTime1 - startTime1) + "ms");
            }
            LOGGER.warn("线程:" + page + "-" + limit + " -> 结束.");
            return atomicInteger.get();
        }

    }

    private synchronized static MarketCustomerEntity getCustomer(Map<String, Object> map) {
        String name = getMapValueByKey(Constant.CUSTOMER_NAME, map, "", 150);
        String phone = getMapValueByKey(Constant.CUSTOMER_PHONE, map, "", 90);
        String cityCode = getMapValueByKey(Constant.CITY_CODE, map, "", 15);
        String cityName = getMapValueByKey(Constant.CITY_NAME, map, "", 15);
        String crmId = getMapValueByKey(Constant.CRMID, map, "", 20);
        String sex = getMapValueByKey(Constant.CUSTOMER_SEX, map,
                String.valueOf(Constant.CustomerSexEnum.NOTSURE.getMsg()), 5);
        String actSource = getMapValueByKey(Constant.CUSTOMER_ACTSOURCE, map, "", 300);
        String firstSource = getMapValueByKey(Constant.CUSTOMER_FIRSTSOURCE, map, "", 100);
        String latestSource = getMapValueByKey(Constant.CUSTOMER_LATESTSOURCE, map, "", 100);
        String latestCall = getMapValueByKey(Constant.CUSTOMER_CRM_LATESTSCALL, map, "", 100);
        String latestCallResult = getMapValueByKey(Constant.CUSTOMER_CRM_LATESTSCALL_RESULT, map, "", 100);
        String bizPort = getMapValueByKey("bizPort", map, "", 30);
        String buyIntention = getMapValueByKey("latestCallResult", map, "", 30);
        String projectIds = getMapValueByKey("projectIds", map, "", 200);
        String projectSourceId = getMapValueByKey("projectSourceId", map, "", 10);
        String projectSourceTime = getMapValueByKey("projectSourceTime", map, "", 30);

        List<String> contact = new ArrayList<>();
        if (!Strings.isNullOrEmpty(projectIds)) {
            JSONArray pids = JSONArray.fromObject(projectIds);
            for (Object object : pids) {
                contact.add(String.valueOf(object));
            }
        }

        actSource = StringUtils.StringFilter(actSource);
        MarketCustomerEntity customerEntity = new MarketCustomerEntity();
        customerEntity.setName(name);
        customerEntity.setPhone(phone);
        customerEntity.setCityCode(cityCode);
        customerEntity.setCityName(cityName);
        customerEntity.setCrmId(crmId);
        customerEntity.setSex(Integer.valueOf(sex));
        customerEntity.setBizPort(bizPort);
        customerEntity.setActSource(actSource);
        customerEntity.setFirstSource(firstSource);
        customerEntity.setCreateSource("CRM拉取");
        customerEntity.setCustomerType(Constant.CustomerTypeEnum.ONLINE.getMsg());
        customerEntity.setLatestSource(latestSource);
        customerEntity.setCrmLatestCall(latestCall);
        customerEntity.setCrmLatestCallResult(latestCallResult);
        customerEntity.setCreateTime(new Date());
        customerEntity.setCreater(Constant.CustomerSourceEnum.CRM.getMsg());
        customerEntity.setUpdater(Constant.CustomerSourceEnum.CRM.getMsg());
        customerEntity.setUpdateTime(new Date());
        customerEntity.setStatus(Constant.CustomerStatusEnum.NORECORD.getStatus());
        customerEntity.setBuyIntention(buyIntention);
        customerEntity.setTraceStatus(1);
        customerEntity.setCrmSync("1");
        customerEntity.setIsDelete(0);
        customerEntity.setIsOvertime(0);
        customerEntity.setSignupSourceId(projectSourceId);
        customerEntity.setSignupSourceName("");
        customerEntity.setSignupTime(projectSourceTime);
        customerEntity.setSignupHouseId(Joiner.on(",").join(contact));
        customerEntity.setSignupHouseName("");

        return customerEntity;

    }


    /**
     * 获取map中的值
     *
     * @param key          key
     * @param map          map
     * @param defaultValue 默认值
     * @return value
     */
    private static String getMapValueByKey(String key, Map<String, Object> map, String defaultValue, Integer length) {
        String value = "";
        if (map.containsKey(key) && map.get(key) != null && !Strings.isNullOrEmpty(String.valueOf((map.get(key))))) {
            value = String.valueOf(map.get(key));
        }

        if (Strings.isNullOrEmpty(value) || "null".equalsIgnoreCase(value)) {
            value = defaultValue;
        }

        if (null != length) {
            value = value.length() > length ? value.substring(0, length) : value;
        }
        return value;
    }

    @Override
    public void putOvertimeWaitCallToOcean() {
        marketingActivityService.putOvertimeWaitCallToOcean();
    }

    /**
     * 以下均为自动生成
     */

    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isControlService() {
        return false;
    }

    @Override
    public boolean isLogService() {
        return false;
    }

    @Override
    public boolean isMonitorService() {
        return false;
    }

    @Override
    public Object rollback() {
        return null;
    }

    @Override
    public void commit() {
    }
}
