package com.house365.ws.interfaces.impl;

import com.house365.beans.entity.CloudActivityEntity;
import com.house365.beans.entity.CloudCustomerEntity;
import com.house365.beans.entity.CustomerEntity;
import com.house365.beans.entity.UserEntity;
import com.house365.ws.beans.request.MapListRequest;
import com.house365.ws.beans.response.MapListResponse;
import com.house365.ws.beans.util.HResult;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.dao.mapper.*;
import com.house365.ws.interfaces.server.ICloudCustomerInterface;
import com.house365.ws.system.ReturnResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Created by Administrator on 2020/3/26.
 */
@Service("cloudCustomer")
public class CloudCustomerImpl implements ICloudCustomerInterface {

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

    @Autowired
    private CloudCustomerMapper mapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private RedisUtilsInterface redisUtil;
    @Autowired
    private CloudActivityMapper activityMapper;
    @Autowired
    private CustomerCallbackMapper callbackMapper;
    @Autowired
    private CustomerStatusLogMapper statusLogMapper;

    @Override
    public MapListResponse list(MapListRequest request, int activeId) {
        MapListResponse response = new MapListResponse();
        try {
            CloudActivityEntity activityEntity = activityMapper.getById(activeId);
            int type = activityEntity.getType();
            Map<String, Object> map = new HashMap<>(10);
            Map<String, Object> searchParams = request.getSearchParams();
            map.put("city", searchParams.get("city"));
            map.put("phone", searchParams.get("phone"));

            map.put("latestSource", searchParams.get("latestSource"));
            map.put("actSource", searchParams.get("actSource"));
            map.put("managerName", searchParams.get("managerName"));
            map.put("signupHouseName", searchParams.get("signupHouseName"));
            map.put("activeId", activeId);
            if (StringUtils.isNotBlank(searchParams.get("type").toString())) {
                map.put("type", 2);
            } else {
                map.put("type", 1);
            }
            List<Map<String, Object>> list;
            int count = 0;

            if (null != searchParams.get("status")) {
                int status = Integer.parseInt(searchParams.get("status").toString());
                int backStatus = Integer.parseInt(searchParams.get("backStatus").toString());
                if (type == 0) {
                    String backIdKey = "cloud_back_id" + activeId;
                    String seeIdKey = "cloud_see_Id" + activeId;
                    String daoIdKey = "cloud_dao_Id" + activeId;
                    String buyIdKey = "cloud_buy_Id" + activeId;
                    String signIdKey = "cloud_sign_Id" + activeId;
                    String cancelIdKey = "cloud_cancel_Id" + activeId;
                    String renIdKey = "cloud_ren_Id" + activeId;
                    list = mapper.queryList(map);
                    if (backStatus == 1) {
                        String value = redisUtil.getValByKey(backIdKey);
                        dealList(list, value);
                    } else if (backStatus == 2) {
                        String value = redisUtil.getValByKey(backIdKey);
                        list.removeIf(l -> value.contains(l.get("phone").toString()));
                    }
                    if (status == 1) {
                        String value = redisUtil.getValByKey(seeIdKey);
                        dealList(list, value);
                    } else if (status == 2) {
                        String value = redisUtil.getValByKey(daoIdKey);
                        dealList(list, value);
                    } else if (status == 3) {
                        String value = redisUtil.getValByKey(renIdKey);
                        dealList(list, value);
                    } else if (status == 4) {
                        String value = redisUtil.getValByKey(buyIdKey);
                        dealList(list, value);
                    } else if (status == 5) {
                        String value = redisUtil.getValByKey(signIdKey);
                        dealList(list, value);
                    } else if (status == 6) {
                        String value = redisUtil.getValByKey(cancelIdKey);
                        dealList(list, value);
                    }
                } else {
                    list = mapper.queryList(map);
                    if (status > 0 || backStatus > 0) {
                        Map<String, Object> searchMap = new HashMap<>(10);
                        searchMap.put("activeId", activeId);
                        searchMap.put("type", 2);
                        List<CloudCustomerEntity> cloudList = mapper.queryByConditions(searchMap);
                        List<Integer> idList = new ArrayList<>();
                        List<Integer> seaIdList = new ArrayList<>();
                        List<Integer> idAllList = new ArrayList<>();
                        if (CollectionUtils.isNotEmpty(cloudList)) {
                            cloudList.forEach(c -> {
                                if (c.getManagerId() > 0) {
                                    idList.add(c.getCustomerId());
                                } else {
                                    seaIdList.add(c.getCustomerId());
                                }
                            });
                            Date time = cloudList.get(0).getCreateTime();
                            dealList(idList, idAllList, time, 1);
                            dealSeaList(seaIdList, idAllList, time);
                            idAllList = removeDuplicate(idAllList);
                            Map<String, Object> backMap = new HashMap<>(10);
                            backMap.put("idList", idAllList);
                            backMap.put("notId", 1);
                            if (backStatus > 0 && CollectionUtils.isNotEmpty(idAllList)) {
                                StringBuilder builderBack = new StringBuilder();
                                List<String> backKeyIdList = new ArrayList<>();
                                List<Map<String, Object>> backList = callbackMapper.queryCloudBackCount(backMap);
                                if (CollectionUtils.isNotEmpty(backList)) {
                                    backList.forEach(s -> backKeyIdList.add(s.get("phone").toString()));
                                    backKeyIdList.forEach(s -> builderBack.append(s).append(","));
                                }
                                String value = builderBack.toString();
                                if (backStatus == 1) {
                                    dealList(list, value);
                                } else if (backStatus == 2) {
                                    list.removeIf(l -> value.contains(l.get("phone").toString()));
                                }
                            }
                            if (status > 0 && CollectionUtils.isNotEmpty(idAllList)) {
                                Map<String, Object> queryMap = new HashMap<>(5);

                                StringBuilder builder1 = new StringBuilder();
                                StringBuilder builder2 = new StringBuilder();
                                StringBuilder builder3 = new StringBuilder();
                                StringBuilder builder4 = new StringBuilder();
                                StringBuilder builder5 = new StringBuilder();
                                StringBuilder builder6 = new StringBuilder();

                                if (status == 1) {
                                    queryMap.put("status", 1);
                                    List<Map<String, Object>> seeList = statusLogMapper.queryCloudCount(queryMap);
                                    seeList.forEach(s -> builder1.append(s.get("phone").toString()).append(","));
                                    String value = builder1.toString();
                                    dealList(list, value);
                                } else if (status == 2) {
                                    queryMap.put("status", 2);
                                    List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
                                    daoList.forEach(s -> builder2.append(s.get("phone").toString()).append(","));
                                    String value = builder2.toString();
                                    dealList(list, value);
                                } else if (status == 3) {
                                    queryMap.put("status", 3);
                                    List<Map<String, Object>> renList = statusLogMapper.queryCloudCount(queryMap);
                                    renList.forEach(s -> builder3.append(s.get("phone").toString()).append(","));
                                    String value = builder3.toString();
                                    dealList(list, value);
                                } else if (status == 4) {
                                    queryMap.put("status", 4);
                                    List<Map<String, Object>> buyList = statusLogMapper.queryCloudCount(queryMap);
                                    buyList.forEach(s -> builder4.append(s.get("phone").toString()).append(","));
                                    String value = builder4.toString();
                                    dealList(list, value);
                                } else if (status == 5) {
                                    queryMap.put("status", 5);
                                    List<Map<String, Object>> signList = statusLogMapper.queryCloudCount(queryMap);
                                    signList.forEach(s -> builder5.append(s.get("phone").toString()).append(","));
                                    String value = builder5.toString();
                                    dealList(list, value);
                                } else if (status == 6) {
                                    queryMap.put("status", 6);
                                    List<Map<String, Object>> cancelList = statusLogMapper.queryCloudCount(queryMap);
                                    cancelList.forEach(s -> builder6.append(s.get("phone").toString()).append(","));
                                    String value = builder6.toString();
                                    dealList(list, value);
                                }
                            }
                        }
                    }
                }
                int total = list.size();
                //手动分页，需要先查出全部然后筛选重新分页
                for (int i = 0; i <= total; i++) {
                    // 开始索引
                    int currentPage = request.getPaging().getCurrentPage();
                    int fromIndex = (currentPage - 1) * request.getPaging().getPageSize();
                    // 结束索引
                    int toIndex = fromIndex + request.getPaging().getPageSize();
                    // 如果结束索引大于集合的最大索引，那么规定结束索引=集合大小
                    if (toIndex > total) {
                        toIndex = total;
                    }
                    if (fromIndex <= total) {
                        list = list.subList(fromIndex, toIndex);
                        if (toIndex >= fromIndex) {
                            break;
                        }
                    }
                }
                count = total;
                response.setObjectList(list);
            } else {
                int start = 50 * (request.getPaging().getCurrentPage() - 1);
                map.put("start", start);
                map.put("limit", 50);
                list = mapper.queryList(map);
                count = mapper.queryCount(map);
                response.setObjectList(list);
            }

            map.put("type", 1);
            List<CloudCustomerEntity> waitCountList = mapper.queryByConditions(map);
            response.setWaitCount(waitCountList.size());
            map.put("type", 2);
            List<CloudCustomerEntity> sentCountList = mapper.queryByConditions(map);
            response.setSentCount(sentCountList.size());
            map.put("type", 0);
            List<CloudCustomerEntity> customerCountList = mapper.queryByConditions(map);
            response.setCustomerCount(customerCountList.size());
            request.getPaging().setRecords(count);
            response.setPaging(request.getPaging());
            response.setObjectList(list);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(e.getMessage());
        }
        return response;
    }

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

    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());
                    }
                }
            }
        }
    }


    private void dealList(List<Map<String, Object>> list, String value) {
        Iterator<Map<String, Object>> iterator = list.iterator();
        while (iterator.hasNext()) {
            Map<String, Object> listMap = iterator.next();
            String phone = listMap.get("phone").toString();
            if (!value.contains(phone)) {
                iterator.remove();
            }
        }
    }

    @Override
    public List<CloudCustomerEntity> queryByConditions(Map<String, Object> map) {
        List<CloudCustomerEntity> list = mapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public CloudCustomerEntity getById(int id) {
        return mapper.getById(id);
    }

    @Override
    public HResult judgeCustomer(int id) {
        HResult result = new HResult();
        try {
            CloudCustomerEntity entity = mapper.getById(id);
            if (entity != null) {
                int customerId = entity.getCustomerId();
                CustomerEntity customerEntity = customerMapper.queryById(customerId);
                if (customerEntity != null) {
                    if (customerEntity.getManagerId() != null) {
                        if (customerEntity.getIsWaitCall() != null && customerEntity.getIsWaitCall() == 1) {
                            result.setErrorMessage("该客户尚未回访");
                            result.setStatus(-1);
                            return result;
                        } else {
                            result.setData(entity);
                        }
                    } else {
                        result.setData(entity);
                        result.setErrorMessage("该客户已回公海");
                        result.setStatus(101);
                        return result;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setErrorMessage("查看云迹活动客户是否是私客失败");
            result.setStatus(500);
        }
        return result;
    }

    @Override
    public void updateById(int customerId, UserEntity user) {
        Map<String, Object> map = new HashMap<>(10);
        map.put("customerId", customerId);
        List<CloudCustomerEntity> list = mapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(list)) {
            CloudCustomerEntity c = list.get(0);
            c.setManagerId(user.getId());
            c.setManagerName(user.getRealName());
            c.setBindTime(new Date());
            mapper.update(c);
        }
    }

    @Override
    public List<String> getExistByPhone(List<String> phoneList, int status) {
        Map<String, Object> map = new HashMap<>();
        map.put("phoneList",phoneList);
        map.put("status",status);

        return mapper.getExistByPhone(map);
    }
}
