package com.ruoyi.ibs.list.service.impl;

import com.ruoyi.ibs.draw.domain.dto.draw.LayerGridDTO;
import com.ruoyi.ibs.draw.domain.entity.DrawGrid;
import com.ruoyi.ibs.draw.mapper.DrawGridMapper;
import com.ruoyi.ibs.grid.domain.entity.VirtualCustUser;
import com.ruoyi.ibs.list.domain.*;
import com.ruoyi.ibs.list.mapper.SysCampaignGroupCustomerMapper;
import com.ruoyi.ibs.list.mapper.SysCampaignMapper;
import com.ruoyi.ibs.list.mapper.SysCustAppointSupplementMapper;
import com.ruoyi.ibs.list.service.ISysCustAppointSupplementService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.SecurityUtils.*;
import static com.ruoyi.ibs.list.domain.Constans.*;
import static com.ruoyi.ibs.list.domain.Constans.ROLE_HeadPrivate;
import static com.ruoyi.ibs.list.domain.ListUtil.splitList;

@Service
@Transactional(rollbackFor = Exception.class)
public class SysCustAppointSupplementServiceImpl implements ISysCustAppointSupplementService {



    @Autowired
    private SysCampaignMapper sysCampaignMapper;
    @Autowired
    private SysCampaignGroupCustomerMapper sysCampaignGroupCustomerMapper;

    @Autowired
    private SysCustAppointSupplementMapper sysCustAppointSupplementMapper;

    @Autowired
    private DrawGridMapper drawGridMapper;

    final String HEAD = "000";






    @Override
    public void custAppointSupplement(List<String> org3) {
//          给所有活动中，没有下发成功的、  没有下发到客户经理活动重跑分配规则
        List<SysCampaign> sysCampaignAll = sysCustAppointSupplementMapper.selectSysCampaignVoList(new SysCampaign());
        SysCampaignGroupCustomer sysCampaignGroupCustomerVo = new SysCampaignGroupCustomer();
        List<SysCampaignGroupCustomer> campaignGroupCustomersAns = new ArrayList<>();
        sysCampaignAll.forEach(e->{
            sysCampaignGroupCustomerVo.setCampaignId(e.getCampaignId());
            List<SysCampaignGroupCustomer> custs = sysCustAppointSupplementMapper.selectSysCampaignGroupCustomerList(sysCampaignGroupCustomerVo);
            if(custs.size()>0){
                List<SysCampaignGroupCustomer> unhandList = custs.stream().filter(f -> PushStatusEnum.pushFailed.getCode().equalsIgnoreCase(f.getPushStatus())
                        || PushStatusEnum.unPushed.getCode().equalsIgnoreCase(f.getPushStatus())).collect(Collectors.toList());
                if( unhandList != null &&  unhandList.size()>0) {
                    //  存在首次下发失败，没有到机构的数据
//                    log.info("活动id:{} 重跑", e.getCampaignId());
                    org3.add(e.getCampaignId());
                    List<String> unhandListCust = unhandList.stream().map(m->m.getCustId()).collect(Collectors.toList());
                    //设置layer
                    if( StringUtils.isNotEmpty(e.getDistributeType2())) {
                        //设置layer
                        e.setLayerIds(Arrays.stream(e.getDistributeType2().split(",")).map(Long :: valueOf)
                                .collect(Collectors.toList()));
                    }
                    //设置 虚拟网格
                    if( StringUtils.isNotEmpty(e.getDistributeType3())) {
                        //设置 虚拟网格
                        e.setVirtualGridIds(Arrays.stream(e.getDistributeType3().split(",")).map(Long :: valueOf)
                                .collect(Collectors.toList()));
                    }
                    List<String> distributeRules = Arrays.asList(e.getDistributeType().split(","));
                    //存放需要生成的清单数据，后续统一插入数据库

                    // 开始分配
                    distribute(e,distributeRules,unhandList,campaignGroupCustomersAns,String.valueOf(e.getDeptId()/1000));

                }
            }
        });
        sysCustAppointSupplementMapper.insertSysCampaignGroupCustomerBatch(campaignGroupCustomersAns);
    }


    @Override    /**
     * 
     * @param sysCampaign   活动
     * @param distributeRules  分配方式
     * @param sysGroupCustomers  待分配客户
     * @param campaignGroupCustomers   分配结果
     */
    public void distribute(SysCampaign sysCampaign, List<String> distributeRules, List<SysCampaignGroupCustomer> sysGroupCustomers, List<SysCampaignGroupCustomer> campaignGroupCustomers,String log3){
        
        if (distributeRules != null&&distributeRules.size()>0) {
            int k = 0;//虚拟网格分配方式计数
            int l = 0;//特色网格分配方式计数

            for (int j = 0; j <distributeRules.size();j++){
                //按照行政网格
                if (distributeRules.get(j).length()==2&&'2'==distributeRules.get(j).charAt(0)) {
                    String opsDept = distributeRules.get(j).substring(1);
                    distributeDZ(sysCampaign,sysGroupCustomers,campaignGroupCustomers,opsDept, log3);
                }
                //按照特色网格
                if (distributeRules.get(j).length()==2&&'4'==distributeRules.get(j).charAt(0)) {
                    //todo 根据部室与特色网格类型查询特色网格列表
                    List<Long> layerIds = sysCampaign.getLayerIds();
                    String opsDept = String.valueOf(distributeRules.get(j).charAt(1));
                    if (layerIds.size()>l){
                        Long layerId = layerIds.get(l);
                        LayerGridDTO layerGridDTO = new LayerGridDTO();
                        layerGridDTO.setLayerId(layerId);
                        layerGridDTO.setOpsDept(opsDept);
                        layerGridDTO.setDeptId(sysCampaign.getDeptId());
                        List<DrawGrid> drawGrids = drawGridMapper.getGridListByOpsAndLayer(layerGridDTO);
                        List<Long> gridIds = drawGrids.stream().map(DrawGrid::getGridId).collect(Collectors.toList());
                        if (gridIds.size()>0){
                            distributeTs(sysCampaign,sysGroupCustomers,campaignGroupCustomers,gridIds,log3);
                        }
                        ++l;
                    }

                }
                //按照虚拟网格
                if (distributeRules.get(j).length()==2&&'5'==distributeRules.get(j).charAt(0)) {
                    //todo 根据部室与虚拟网格名称查询虚拟网格列表
                    List<Long> virtualGridIds = sysCampaign.getVirtualGridIds();
                    if (virtualGridIds.size()>k){
                        Long gridId = virtualGridIds.get(k);
                        distributeXN(sysCampaign,sysGroupCustomers,campaignGroupCustomers,gridId,log3);
                        ++k;
                    }

                }
                //按照管户关系分配
                if (distributeRules.get(j).length()>3){
                    distributeGH(sysCampaign,sysGroupCustomers,campaignGroupCustomers,distributeRules.get(j),log3);
                }
                //随机平均分配
//                if (sj_campaignDistributeType.equals(distributeRules.get(j))){
//                    distributeSJ(sysCampaign,sysGroupCustomers,groupId,campaignId,campaignGroupCustomers);
//                }
            }


            //各分配规则分配完后仍有未分配客户，则直接置为分配失败

        }

    }

   @Override
    public void distributeDZ(SysCampaign sysCampaign,List<SysCampaignGroupCustomer> sysGroupCustomers,List<SysCampaignGroupCustomer> campaignGroupCustomersInsert,String opsDept,String log3){


        sysGroupCustomers.forEach(groupCustomer -> {
                    CustDeptUserGrid custDeptUserGrid = new CustDeptUserGrid();
                    String custId = groupCustomer.getCustId();
                    //根据匹配表中关联关系查询到对应的客户归属
                    custDeptUserGrid.setCustId(custId);
                    custDeptUserGrid.setOpsDept(opsDept);
                    custDeptUserGrid.setLog3(log3);
                    if (!String.valueOf(sysCampaign.getDeptId()).endsWith(HEAD)) {
                        // 支行的活动
                        custDeptUserGrid.setDeptId(sysCampaign.getDeptId());
                    }
                    List<CustDeptUserGrid> custDeptUserGrids = sysCustAppointSupplementMapper.selectCustDeptUserGridListTab(custDeptUserGrid);
                    custDeptUserGrids = custDeptUserGrids.stream().filter(c -> c.getDeptId() != null).collect(Collectors.toList());
                    //归属用户不为空，则分配成功
                    if (custDeptUserGrids.size() > 0) {
                        //能找到归属关系，则直接去除该客户，避免二次分配
//                        log.info(groupCustomer.getCustId() + "客户归属关系情况" + custDeptUserGrids);
                        Map<Long, List<CustDeptUserGrid>> custDeptMaps = custDeptUserGrids.stream().collect(Collectors.groupingBy(CustDeptUserGrid::getDeptId));
                        //执行人为机构的情况下，即使有多条管户关系，也只需要推送到同一个客户到同一个机构下一条
                        for (Long l : custDeptMaps.keySet()) {
                            if(l == null ){
                                continue;
                            }
                            List<CustDeptUserGrid> custDeptUserGridList = custDeptMaps.get(l);
                            SysCampaignGroupCustomer sc = new SysCampaignGroupCustomer();
                            BeanUtils.copyProperties(groupCustomer, sc);

                            if (gr_executer.equals(sysCampaign.getExecuter()) ) {
                                Map<Long, List<CustDeptUserGrid>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(CustDeptUserGrid::getUserId));
                                custUserMaps.forEach((userId, userList) -> {
                                    if(userId != null) {
                                        if (custUserMaps.get(userId).size() > 0) {
                                            SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                            BeanUtils.copyProperties(sc, scUser);
                                            sc.setUserId(userId);
                                            sc.setDeptId(l);
                                            campaignGroupCustomersInsert.add(sc);
                                        }
                                    }
                                });
                            }else if (hh_executer.equals(sysCampaign.getExecuter())){
                                Map<Long, List<CustDeptUserGrid>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(CustDeptUserGrid::getUserId));
                                custUserMaps.forEach((userId, userList) -> {
                                    if (custUserMaps.get(userId).size() > 0) {
                                            SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                            BeanUtils.copyProperties(sc, scUser);
                                            sc.setUserId(userId);
                                            sc.setDeptId(l);
                                            campaignGroupCustomersInsert.add(sc);
                                        }

                                });
                            }else{
                                sc.setDeptId(l);
                                campaignGroupCustomersInsert.add(sc);
                            }

                        }
                    }
                });
                sysGroupCustomers.removeAll(campaignGroupCustomersInsert);
    }


    @Override
/**
     * 特色分配
     * @param sysCampaign  活动
     * @param sysGroupCustomers  待处理客户
     * @param campaignGroupCustomersInsert  处理结果
     * @param gridIds
     * @param log3
     */
    public void distributeTs(SysCampaign sysCampaign,List<SysCampaignGroupCustomer> sysGroupCustomers,List<SysCampaignGroupCustomer> campaignGroupCustomersInsert,List<Long> gridIds,String log3){
        List<SysGroupCustomer> distributeDzList = new ArrayList<>();
        List<GridInfoTs> gridInfos = sysCustAppointSupplementMapper.selectGridInfoTsByGridIds(gridIds,log3);
        sysGroupCustomers.forEach(groupCustomer -> {
            List<GridInfoTs> gridInfoTsList = gridInfos.stream().filter(c -> c.getCustId().equals(groupCustomer.getCustId())).collect(Collectors.toList());
            if (gridInfoTsList.size() > 0) {
                //能找到归属关系，则直接去除该客户，避免二次分配
//                log.info(groupCustomer.getCustId() + "客户归属关系情况" + gridInfoTsList);

                Map<Long, List<GridInfoTs>> custDeptUserGrids = gridInfoTsList.stream().collect(Collectors.groupingBy(GridInfoTs::getRelateDeptId));
                //归属用户不为空，则分配成功
                if (custDeptUserGrids.size() > 0) {
                    //能找到归属关系，则直接去除该客户，避免二次分配
//                    log.info(groupCustomer.getCustId() + "客户归属关系情况" + custDeptUserGrids);
                    //执行人为机构的情况下，即使有多条管户关系，也只需要推送到同一个客户到同一个机构下一条
                    for (Long l : custDeptUserGrids.keySet()) {
                        if (l == null) {
                            continue;
                        }
                        List<GridInfoTs> custDeptUserGridList = custDeptUserGrids.get(l);
                        SysCampaignGroupCustomer sc = new SysCampaignGroupCustomer();
                        BeanUtils.copyProperties(groupCustomer, sc);

                        if (gr_executer.equals(sysCampaign.getExecuter())) {
                            Map<Long, List<GridInfoTs>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(GridInfoTs::getUserId));
                            custUserMaps.forEach((userId, userList) -> {
                                if (userId != null) {
                                    if (custUserMaps.get(userId).size() > 0) {
                                        SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                        BeanUtils.copyProperties(sc, scUser);
                                        sc.setUserId(userId);
                                        sc.setDeptId(l);
                                        campaignGroupCustomersInsert.add(sc);
                                    }
                                }
                            });
                        } else if (hh_executer.equals(sysCampaign.getExecuter())) {
                            Map<Long, List<GridInfoTs>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(GridInfoTs::getUserId));
                            custUserMaps.forEach((userId, userList) -> {
                                if (custUserMaps.get(userId).size() > 0) {
                                    SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                    BeanUtils.copyProperties(sc, scUser);
                                    sc.setUserId(userId);
                                    sc.setDeptId(l);
                                    campaignGroupCustomersInsert.add(sc);
                                }

                            });
                        } else {
                            sc.setDeptId(l);
                            campaignGroupCustomersInsert.add(sc);
                        }

                    }
                }
            }
            });
        sysGroupCustomers.removeAll(campaignGroupCustomersInsert);

    }

    @Override
    //虚拟网格分配方式
    public void distributeXN(SysCampaign sysCampaign,List<SysCampaignGroupCustomer> sysGroupCustomers,List<SysCampaignGroupCustomer> campaignGroupCustomersInsert,Long gridId,String log3){
        sysGroupCustomers.forEach(groupCustomer -> {
            SysCampaignGroupCustomer sysCampaignGroupCustomer = new SysCampaignGroupCustomer();
            BeanUtils.copyProperties(groupCustomer, sysCampaignGroupCustomer);
            //  查询虚拟网格归属
            VirtualCustUser virtualCustUser  = new VirtualCustUser();
            String custId = groupCustomer.getCustId();
            //根据匹配表中关联关系查询到对应的客户归属
            virtualCustUser.setCustId(custId);
            virtualCustUser.setGridId(gridId);
            virtualCustUser.setLog3(log3);
            if (!String.valueOf(sysCampaign.getDeptId()).endsWith(HEAD)) {
                // 支行的活动
                virtualCustUser.setRelateDeptId(sysCampaign.getDeptId());
            }
            List<VirtualCustUser> virtualCustUsers = sysCustAppointSupplementMapper.selectVirtualCustUserList(virtualCustUser);
            virtualCustUsers = virtualCustUsers.stream().filter(c->c.getRelateDeptId()!=null).collect(Collectors.toList());

            //归属用户不为空，则分配成功
            if (virtualCustUsers.size()>0) {
                //能找到归属关系，则直接去除该客户，避免二次分配

//                log.info(groupCustomer.getCustId() + "客户归属关系情况" + virtualCustUsers);

                Map<Long, List<VirtualCustUser>> custDeptUserGrids = virtualCustUsers.stream().collect(Collectors.groupingBy(VirtualCustUser::getRelateDeptId));

                if (custDeptUserGrids.size() > 0) {
                    //能找到归属关系，则直接去除该客户，避免二次分配
//                    log.info(groupCustomer.getCustId() + "客户归属关系情况" + custDeptUserGrids);
                    //执行人为机构的情况下，即使有多条管户关系，也只需要推送到同一个客户到同一个机构下一条
                    for (Long l : custDeptUserGrids.keySet()) {
                        if (l == null) {
                            continue;
                        }
                        List<VirtualCustUser> custDeptUserGridList = custDeptUserGrids.get(l);
                        SysCampaignGroupCustomer sc = new SysCampaignGroupCustomer();
                        BeanUtils.copyProperties(groupCustomer, sc);

                        if (gr_executer.equals(sysCampaign.getExecuter())) {
                            Map<Long, List<VirtualCustUser>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(VirtualCustUser::getUserId));
                            custUserMaps.forEach((userId, userList) -> {
                                if (userId != null) {
                                    if (custUserMaps.get(userId).size() > 0) {
                                        SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                        BeanUtils.copyProperties(sc, scUser);
                                        sc.setUserId(userId);
                                        sc.setDeptId(l);
                                        campaignGroupCustomersInsert.add(sc);
                                    }
                                }
                            });
                        } else if (hh_executer.equals(sysCampaign.getExecuter())) {
                            Map<Long, List<VirtualCustUser>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(VirtualCustUser::getUserId));
                            custUserMaps.forEach((userId, userList) -> {
                                if (custUserMaps.get(userId).size() > 0) {
                                    SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                    BeanUtils.copyProperties(sc, scUser);
                                    sc.setUserId(userId);
                                    sc.setDeptId(l);
                                    campaignGroupCustomersInsert.add(sc);
                                }

                            });
                        } else {
                            sc.setDeptId(l);
                            campaignGroupCustomersInsert.add(sc);
                        }

                    }
                }
            }
        sysGroupCustomers.removeAll(campaignGroupCustomersInsert);
        });
    }

    @Override
    //管户分配方式
    public void distributeGH(SysCampaign sysCampaign,List<SysCampaignGroupCustomer> sysGroupCustomers,List<SysCampaignGroupCustomer> campaignGroupCustomersInsert,String distributeRule,String log3){
        String codeLevel1 = distributeRule.substring(0, 3);
        String codeLevel2 = distributeRule.substring(3,6);
        List<SysGroupCustomer> distributeGHList = new ArrayList<>();
        sysGroupCustomers.forEach(groupCustomer -> {
            SysCampaignGroupCustomer sysCampaignGroupCustomer = new SysCampaignGroupCustomer();
            BeanUtils.copyProperties(groupCustomer, sysCampaignGroupCustomer);
            CustDeptUserCmpm custDeptUserCmpm= new CustDeptUserCmpm();
            String custId = groupCustomer.getCustId();
            custDeptUserCmpm.setCodeNoLevel1(codeLevel1);
            custDeptUserCmpm.setCodeNoLevel2(codeLevel2);
            //根据匹配表中关联关系查询到对应的客户归属
            custDeptUserCmpm.setCustId(custId);
            if (!String.valueOf(sysCampaign.getDeptId()).endsWith(HEAD)) {
                custDeptUserCmpm.setDeptId(sysCampaign.getDeptId());
            }
            custDeptUserCmpm.setLog3(log3);
            List<CustDeptUserCmpm> custDeptUserCmpms = sysCustAppointSupplementMapper.selectCustDeptUserCmpmList(custDeptUserCmpm);
            custDeptUserCmpms = custDeptUserCmpms.stream().filter(c->c.getDeptId()!=null).collect(Collectors.toList());
            //归属用户不为空，则分配成功
            if (custDeptUserCmpms.size()>0) {
                //能找到归属关系，则直接去除该客户，避免二次分配

//                log.info(groupCustomer.getCustId() + "客户归属关系情况" + custDeptUserCmpms);
                Map<Long, List<CustDeptUserCmpm>> custMapsDept = custDeptUserCmpms.stream().collect(Collectors.groupingBy(CustDeptUserCmpm::getDeptId));
                if (custMapsDept.size() > 0) {
                    //能找到归属关系，则直接去除该客户，避免二次分配
//                    log.info(groupCustomer.getCustId() + "客户归属关系情况" + custMapsDept);
                    //执行人为机构的情况下，即使有多条管户关系，也只需要推送到同一个客户到同一个机构下一条
                    for (Long l : custMapsDept.keySet()) {
                        if (l == null) {
                            continue;
                        }
                        List<CustDeptUserCmpm> custDeptUserGridList = custMapsDept.get(l);
                        SysCampaignGroupCustomer sc = new SysCampaignGroupCustomer();
                        BeanUtils.copyProperties(groupCustomer, sc);

                        if (gr_executer.equals(sysCampaign.getExecuter())) {
                            Map<Long, List<CustDeptUserCmpm>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(CustDeptUserCmpm::getUserId));
                            custUserMaps.forEach((userId, userList) -> {
                                if (userId != null) {
                                    if (custUserMaps.get(userId).size() > 0) {
                                        SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                        BeanUtils.copyProperties(sc, scUser);
                                        sc.setUserId(userId);
                                        sc.setDeptId(l);
                                        campaignGroupCustomersInsert.add(sc);
                                    }
                                }
                            });
                        } else if (hh_executer.equals(sysCampaign.getExecuter())) {
                            Map<Long, List<CustDeptUserCmpm>> custUserMaps = custDeptUserGridList.stream().collect(Collectors.groupingBy(CustDeptUserCmpm::getUserId));
                            custUserMaps.forEach((userId, userList) -> {
                                if (custUserMaps.get(userId).size() > 0) {
                                    SysCampaignGroupCustomer scUser = new SysCampaignGroupCustomer();
                                    BeanUtils.copyProperties(sc, scUser);
                                    sc.setUserId(userId);
                                    sc.setDeptId(l);
                                    campaignGroupCustomersInsert.add(sc);
                                }

                            });
                        } else {
                            sc.setDeptId(l);
                            campaignGroupCustomersInsert.add(sc);
                        }

                    }
                }
            }
        });
        sysGroupCustomers.removeAll(distributeGHList);
    }

}
