package com.kiisoo.ic.customer.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.kiisoo.ic.customer.entity.*;
import com.kiisoo.ic.customer.mapper.OpCustomerDOMapper;
import com.kiisoo.ic.customer.mapper.OpVipDOMapper;
import com.kiisoo.ic.domain.service.PrivilageDomainService;
import com.kiisoo.ic.generalize.entity.PoiCustomerContactDataStat;
import com.kiisoo.ic.generalize.entity.PrivilageOrganizational;
import com.kiisoo.ic.generalize.mapper.PoiCustomerContactDataStatMapper;
import com.kiisoo.ic.generalize.mapper.RetailCompanyMapper;
import com.kiisoo.ic.generalize.service.RetailCompanyService;
import com.kiisoo.ic.store.entity.PoiStore;
import com.kiisoo.ic.store.mapper.PoiStoreDOMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Description: 客户数据概览service
 * @Author: wangyinjia
 * @Date: 2020/4/9
 * @Company: kiisoo
 * @Version: 1.0
 */
@Slf4j
@Service
public class CustomerViewService {

    /**有效*/
    static final Integer VALID = 1;

    static final Integer TEN = 10;

    /**区域*/
    static final Integer LEVEL_REGION = 1;
    /**零售公司*/
    static final Integer LEVEL_COMPANY = 2;
    /**客户*/
    static final Integer LEVEL_CUSTOMER = 3;

    @Autowired
    private RetailCompanyService retailCompanyService;
    /**
     * 用户权限mapper
     */
    @Autowired
    private PrivilageDomainService privilageDomainService;

    /**
     * 店铺mapper
     */
    @Autowired
    private PoiStoreDOMapper poiStoreDOMapper;

    /**
     * 客户mapper
     */
    @Autowired
    private OpCustomerDOMapper opCustomerDOMapper;

    /**
     * 拉黑mapper
     */
    @Autowired
    private PoiCustomerContactDataStatMapper poiCustomerContactDataStatMapper;

    /**
     * vip mapper
     */
    @Autowired
    private OpVipDOMapper opVipDOMapper;

    /**
     * 组织mapper
     */
    @Autowired
    private RetailCompanyMapper retailCompanyMapper;

    /**
     * 客户概览main
     * @param userId 用户id
     * @param selectStartTime 选中开始时间
     * @param selectEndTime 选中结束时间
     * @param startTime 柱状图开始时间
     * @param endTime 柱状图结束时间
     * @return 客户概览VO
     */
    public CustomerViewVO selectCustomerViewMain(Long userId, String selectStartTime, String selectEndTime, String startTime, String endTime){
        CustomerViewVO customerViewVO = new CustomerViewVO();
        //shopIds
        List<Long> shopIds = getShopIds(userId);
        if(CollectionUtils.isEmpty(shopIds)){
            return customerViewVO;
        }
        //柱状图好友list
        List<OpCustomer> customerList = opCustomerDOMapper.selectCustomerList(shopIds, null, null, startTime, endTime);
        //好友总数
        Long customerCount = opCustomerDOMapper.selectCustomerCount(shopIds, null, null, null);
        //好友总数（去重）
        Long validCustomerCount = opCustomerDOMapper.selectCustomerCount(shopIds, VALID, null, null);
        //删除拉黑数
        Long validDeleteCustomerCount = poiCustomerContactDataStatMapper.selectDeleteCustomer(shopIds).stream()
                .filter(contactDO -> contactDO.getNegativeFeedbackCnt() != null)
                .map(PoiCustomerContactDataStat::getNegativeFeedbackCnt).mapToLong(a -> a).sum();
        //会员总数
        Long vipCount = opVipDOMapper.selectVipCount(shopIds, null, null);

        //设置柱状图list
        List<OpCustomer> validCustomerList = customerList.stream().filter(customerDO -> VALID.equals(customerDO.getValidType())).collect(Collectors.toList());
        customerViewVO.setCustomerList(customerList);
        customerViewVO.setValidCustomerList(validCustomerList);
        //设置新增好友，好友总数，拉黑数，vip人数，柱状图list等数据
        setCustomerViewData(customerViewVO, customerCount, validCustomerCount, validDeleteCustomerCount, vipCount, customerList, validCustomerList, selectStartTime, selectEndTime);
        //前十名排行list等
        List<OpCustomer> newCustimerList = customerList.stream().filter(customerDO -> filterCustomerByRegisterTime(customerDO, selectStartTime, selectEndTime)).collect(Collectors.toList());
        List<CustomerViewCompanyVO> orgNewCustomerList = getOrgNewCustomerList(newCustimerList);
        List<CustomerViewShopVO> shopNewCustomerList = getShopNewCustomerList(newCustimerList);
        List<CustomerViewZeroExtendVO> zeroExtendList = getZeroExtendList(newCustimerList, shopIds);
        customerViewVO.setOrgNewCustomerList(orgNewCustomerList);
        customerViewVO.setShopNewCustomerList(shopNewCustomerList);
        customerViewVO.setZeroExtendList(zeroExtendList);
        return customerViewVO;
    }

    /**
     * shopIds
     * @param userId 用户id
     * @return shopIds
     */
    List<Long> getShopIds(Long userId){
        List<Long> shopIds = privilageDomainService.listUserDatePermission(userId);
        return shopIds;
    }

    /**
     * 新增好友，好友总数，拉黑数，vip人数，柱状图list等数据
     * @param customerViewVO 客户概览VO
     * @param customerCount 好友总数
     * @param validCustomerCount 好友总数(去重)
     * @param validDeleteCustomerCount 删除来黑数（累计去重）
     * @param vipCount 会员总数
     * @param customerList 新增好友list
     * @param validCustomerList 新增好友（去重）list
     * @param selectStartTime 选中开始时间
     * @param selectEndTime 选中结束时间
     */
    public void setCustomerViewData(CustomerViewVO customerViewVO, Long customerCount, Long validCustomerCount, Long validDeleteCustomerCount, Long vipCount,
                                      List<OpCustomer> customerList, List<OpCustomer> validCustomerList, String selectStartTime, String selectEndTime){
        //新增好友
        Long newCustomerCount = customerList.stream().filter(customerDO -> filterCustomerByRegisterTime(customerDO, selectStartTime, selectEndTime)).count();
        customerViewVO.setNewCustomer(newCustomerCount);
        //新增好友(去重)
        Long newValidCustomerCount = validCustomerList.stream().filter(customerDO -> filterCustomerByRegisterTime(customerDO, selectStartTime, selectEndTime)).count();
        customerViewVO.setNewValidCustomer(newValidCustomerCount);
        //好友总数
        customerViewVO.setAllCustomer(customerCount);
        //好友总数(去重)
        customerViewVO.setAllValidCustomer(validCustomerCount);
        //删除拉黑数(累计去重)
        customerViewVO.setValidDeleteCustomer(validDeleteCustomerCount);
        //会员总数
        customerViewVO.setAllVipCount(vipCount);

    }

    /**
     * 选中时间过滤客户
     * @param customerDO 好友DO
     * @param selectStartTime 选中开始时间
     * @param selectEndTime 选中结束时间
     * @return true/false
     */
    boolean filterCustomerByRegisterTime(OpCustomer customerDO, String selectStartTime, String selectEndTime){
        Date registerDate = customerDO.getRegisterTime();
        if(registerDate == null){
            return false;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            long startTime = sdf.parse(selectStartTime).getTime();
            long endTime = sdf.parse(selectEndTime).getTime();
            long registerTime = registerDate.getTime();
            return startTime <= registerTime && endTime >= registerTime;
        }catch (Exception e){
            log.error("格式化时间出错", e);
            return false;
        }
    }

    /**
     * 店铺组织信息list
     * @param shopIds 店铺ids
     * @param companyFlag 零售公司
     * @param regionFlag 区域
     * @return 店铺组织信息list
     */
    public List<ShopOrgInfoVO> getOrgInfoByShopIds(List<Long> shopIds, Boolean companyFlag, Boolean regionFlag){
        //店铺-客户组织list
        List<ShopOrgInfoVO> shopOrgInfoList = opCustomerDOMapper.selectCustomerOrgByShopIds(shopIds, LEVEL_CUSTOMER);
        if(companyFlag == null || !companyFlag){
            return shopOrgInfoList;
        }
        //零售公司list
        List<Long> companyIds = shopOrgInfoList.stream().map(ShopOrgInfoVO::getCompanyId).collect(Collectors.toList());
        List<PrivilageOrganizational> companyList = new ArrayList<>();
        if(companyIds.size() > 0){
            QueryWrapper<PrivilageOrganizational> orgWrapper = new QueryWrapper<>();
            orgWrapper.eq("level", LEVEL_COMPANY);
            orgWrapper.in("id", companyIds);
            companyList = retailCompanyMapper.selectList(orgWrapper);
        }
        Map<Long, String> companyNameMap = companyList.stream().collect(Collectors.toMap(PrivilageOrganizational::getId, PrivilageOrganizational::getName));
        shopOrgInfoList.stream().filter(shopOrgDO -> shopOrgDO.getCompanyId() != null).forEach(shopOrgDO -> shopOrgDO.setCompanyName(companyNameMap.get(shopOrgDO.getCompanyId())));
        //区域list
        if(regionFlag == null || !regionFlag){
            return shopOrgInfoList;
        }

        return shopOrgInfoList;
    }

    /**
     * 零售公司新增排行list
     * @param newCustimerList 新增好友list
     * @return 零售公司新增排行list
     */
    List<CustomerViewCompanyVO> getOrgNewCustomerList(List<OpCustomer> newCustimerList){
        List<CustomerViewCompanyVO> orgNewCustomerList = new ArrayList<>();
        //店铺id-新增好友数map
        Map<Long, Long> shopIdCountMap = newCustimerList.stream().collect(Collectors.groupingBy(OpCustomer::getShopId, Collectors.counting()));
        //店铺id→零售公司名称
        List<Long> shopIds = newCustimerList.stream().map(OpCustomer::getShopId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(shopIds)){
            return orgNewCustomerList;
        }
        //零售公司id-公司店铺list map
        List<ShopOrgInfoVO> shopOrgInfoList = getOrgInfoByShopIds(shopIds, true, null);
        Map<Long, List<ShopOrgInfoVO>> companyShopListMap = shopOrgInfoList.stream().distinct().collect(Collectors.groupingBy(ShopOrgInfoVO::getCompanyId));
        //每个公司新增数
        List<CustomerViewCompanyVO> tmpList = new ArrayList<>();
        companyShopListMap.forEach((companyId,companyShopList) -> {
            CustomerViewCompanyVO orgViewDO = new CustomerViewCompanyVO();
            orgViewDO.setOrgId(companyId);
            orgViewDO.setOrgName(companyShopList.get(0).getCompanyName());
            AtomicInteger newCustomerCount = new AtomicInteger(0);
            companyShopList.forEach(companyShopVO -> {
                Long shopId = companyShopVO.getShopId();
                int tmpCount = shopIdCountMap.get(shopId) == null ? 0 : Math.toIntExact(shopIdCountMap.get(shopId));
                newCustomerCount.updateAndGet(v -> v + tmpCount);
            });
            //平均
            if(companyShopList.size() > 0){
                newCustomerCount.updateAndGet(v -> Math.round(v / (float)companyShopList.size()));
            }
            orgViewDO.setNewCustomerCount(newCustomerCount.get());
            tmpList.add(orgViewDO);
        });
        //排序
        orgNewCustomerList = tmpList.stream().sorted(Comparator.comparing(CustomerViewCompanyVO::getNewCustomerCount).reversed()).limit(TEN).collect(Collectors.toList());
        return orgNewCustomerList;
    }

    /**
     * 店铺新增排行list
     * @param newCustimerList 新增好友list
     * @return 店铺新增排行list
     */
    List<CustomerViewShopVO> getShopNewCustomerList(List<OpCustomer> newCustimerList){
        //店铺分组
        Map<Long, List<OpCustomer>> shopIdMap = newCustimerList.stream().collect(Collectors.groupingBy(OpCustomer::getShopId));
        List<CustomerViewShopVO> shopViewList = new ArrayList<>();
        shopIdMap.forEach((k,v) -> {
            CustomerViewShopVO shopVO = new CustomerViewShopVO();
            shopVO.setShopId(k);
            shopVO.setNewCustomerCount(v.size());
            PoiStore shopDO = poiStoreDOMapper.selectById(k);
            if(shopDO != null){
                shopVO.setShopName(shopDO.getName());
            }
            shopViewList.add(shopVO);
        });
        //排序
        List<CustomerViewShopVO> shopNewCustomerList = shopViewList.stream().sorted(Comparator.comparing(CustomerViewShopVO::getNewCustomerCount).reversed()).limit(TEN).collect(Collectors.toList());
        return shopNewCustomerList;
    }

    /**
     * 零推广list
     * @param newCustimerList 新增好友list
     * @param shopIds 管辖店铺ids
     * @return 零推广list
     */
    List<CustomerViewZeroExtendVO> getZeroExtendList(List<OpCustomer> newCustimerList, List<Long> shopIds){
        List<CustomerViewZeroExtendVO> zeroExtendList = new ArrayList<>();
        //有推广的店铺ids
        List<Long> notZeroShopIds = newCustimerList.stream().map(OpCustomer::getShopId).distinct().collect(Collectors.toList());
        //零售公司id-公司店铺list map
        List<ShopOrgInfoVO> shopOrgInfoList = getOrgInfoByShopIds(shopIds, true, null);
        Map<Long, List<ShopOrgInfoVO>> companyShopListMap = shopOrgInfoList.stream().distinct().collect(Collectors.groupingBy(ShopOrgInfoVO::getCompanyId));

        List<CustomerViewZeroExtendVO> tmpZeroExtendList = new ArrayList<>();
        companyShopListMap.forEach((companyId, companyShopList) -> {
            List<Long> tmpShopIds = companyShopList.stream().map(ShopOrgInfoVO::getShopId).distinct().collect(Collectors.toList());
            int tmpShopCount = tmpShopIds.size();
            CustomerViewZeroExtendVO zeroExtendVO = new CustomerViewZeroExtendVO();
            zeroExtendVO.setOrgId(companyId);
            zeroExtendVO.setOrgName(companyShopList.get(0).getCompanyName());
            zeroExtendVO.setAllShopCount(tmpShopCount);
            //推广的店铺
            tmpShopIds.retainAll(notZeroShopIds);
            zeroExtendVO.setZeroShopCount(tmpShopCount - tmpShopIds.size());
            tmpZeroExtendList.add(zeroExtendVO);
        });
        zeroExtendList = tmpZeroExtendList.stream()
                .filter(zeroExtendDO -> zeroExtendDO.getZeroShopCount() > 0)
                .sorted(Comparator.comparing(CustomerViewZeroExtendVO::getZeroShopCount).reversed())
                .limit(TEN).collect(Collectors.toList());
        return zeroExtendList;
    }

    /**
     * 零推广list
     * @param newCustimerList 新增好友list
     * @param shopIds 管辖店铺ids
     * @param regionId 区域
     * @param companyId 零售公司
     * @param customerId 客户组织
     * @return 零推广list
     */
    List<CustomerViewZeroExtendVO> getZeroExtendList2(List<OpCustomer> newCustimerList, List<Long> shopIds, int pageNum, int pageSize, Long regionId , Long companyId, Long customerId){
        //有推广的店铺ids
        List<Long> notZeroShopIds = newCustimerList.stream().map(OpCustomer::getShopId).distinct().collect(Collectors.toList());
        //无推广id
        shopIds.removeAll(notZeroShopIds);
        PageHelper.startPage(pageNum,pageSize);
        List<CustomerViewZeroExtendVO> list = opCustomerDOMapper.selectOrgInfoByShopIds(shopIds, regionId, companyId, customerId);
        AtomicInteger number = new AtomicInteger(1 + ((pageNum-1) * pageSize));
        //求分页总数
        Page<CustomerViewZeroExtendVO> pageList = (Page<CustomerViewZeroExtendVO>)list;
        Long totalSize = pageList.getTotal();
        list.forEach(item -> {
            item.setTotalSize(totalSize);
            item.setNumber(number.get());
            number.incrementAndGet();
        });

        return list;
    }

    /**
     * 找到推广为0
     * @param regionId 大区id
     * @param companyId 公司id
     * @param customerId 客户id
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public List<CustomerViewZeroExtendVO> zeroExtendList(long userId, Long regionId , Long companyId, Long customerId,
                                                         String startTime, String endTime, int pageNum, int pageSize){
        Set<Long> shopIds;
        //根据店铺查询所有扫码客户信息
        if(customerId != null){
            shopIds = getCompanyShop(customerId, userId);
        }else if(companyId != null){
            shopIds = getCompanyShop(companyId, userId);
        } else if(regionId != null){
            shopIds = getCompanyShop(regionId, userId);
        }else{
            //查询用户权限店铺
            shopIds = new HashSet<>(privilageDomainService.listUserDatePermission(userId));
        }
        if(CollectionUtils.isEmpty(shopIds)){
            return new ArrayList<>();
        }
        //柱状图好友list
        List<OpCustomer> customerList = opCustomerDOMapper.selectCustomerList(new ArrayList<>(shopIds), null, null, startTime, endTime);
        List<CustomerViewZeroExtendVO> zeroExtendList = getZeroExtendList2(customerList, new ArrayList<>(shopIds),pageNum,pageSize, regionId, companyId, customerId);
        return zeroExtendList;
    }

    public Set<Long> getCompanyShop(Long companyId, long userId){
        //找到最小公司
        Set<Long> param = new HashSet<>();
        param.add(companyId);
        Set<Long> minCompany = new HashSet<>();
        retailCompanyService.getMinCompany(param,minCompany);

        //找到公司店铺
        List<PoiStore> shops = new ArrayList<>();
        minCompany.forEach(item -> {
            shops.addAll(retailCompanyService.selectShopByCompany(item));
        });
        //公司店铺和权限做交集
        Set<Long> shopIds = shops.stream().map(p -> p.getId()).collect(Collectors.toSet());
        List<Long> userAllShops = privilageDomainService.listUserDatePermission(userId);
        shopIds.retainAll(userAllShops);
        return shopIds;
    }


}
