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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.ibs.grid.domain.dto.GridUserDTO;
import com.ruoyi.ibs.grid.domain.entity.*;
import com.ruoyi.ibs.grid.domain.vo.CustVO;
import com.ruoyi.ibs.grid.mapper.*;
import com.ruoyi.ibs.grid.service.RegionGridUpdateService;
import com.ruoyi.ibs.grid.service.SysAddressService;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author 吴凯程
 * @Date 2025/2/8
 **/
@Service
@Slf4j
@EnableAsync
public class RegionGridUpdateServiceImpl implements RegionGridUpdateService {

    @Resource
    private RegionCustUserMapper regionCustUserMapper;

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private RegionGridMapper regionGridMapper;

    @Resource
    private RegionAdminDivisionRelateMapper regionAdminDivisionRelateMapper;

    @Resource
    private RegionUserRelateMapper regionUserRelateMapper;

    @Resource
    private RegionGridTransferMapper regionGridTransferMapper;

    @Resource
    private SysAddressService sysAddressService;


    /**
     * @param gridId
     */
    @Override
    @Async
    public void updateTopGrid(Long gridId) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("开始更新网格：{}", gridId);
        RegionGrid regionGrid = regionGridMapper.selectById(gridId);
        SysUser creator = sysUserMapper.selectUserByUserName(regionGrid.getCreateBy());
        SysDept createDept = sysDeptMapper.selectDeptById(regionGrid.getDeptId());
        String deptCode = String.valueOf(regionGrid.getDeptId()).substring(0, 3);

        regionCustUserMapper.batchDeleteTopGrid(gridId, deptCode);

        LambdaQueryWrapper<RegionAdminDivisionRelate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionAdminDivisionRelate::getGridId, gridId);
        List<String> codeList = regionAdminDivisionRelateMapper.selectList(queryWrapper).stream().map(RegionAdminDivisionRelate::getCode).collect(Collectors.toList());

        LambdaQueryWrapper<RegionUserRelate> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RegionUserRelate::getGridId, gridId);
        List<RegionUserRelate> deptList = regionUserRelateMapper.selectList(queryWrapper1);
        String branchIds = deptList.stream().map(regionUserRelate -> regionUserRelate.getRelateDeptId().toString()).collect(Collectors.joining(","));
        String branchNames = deptList.stream().map(regionUserRelate -> regionUserRelate.getRelateDeptName()).collect(Collectors.joining(","));

        int pageNum = 1;
        int pageSize = 10000;
        PageInfo<CustVO> pageInfo;
        do {
            PageHelper.startPage(pageNum, pageSize);
            List<CustVO> custVOS = new ArrayList<>();
            if(regionGrid.getOpsDept().equals("0")){
                custVOS = regionCustUserMapper.selectPrivateCustByCode(codeList, deptCode);
            }else if(regionGrid.getOpsDept().equals("1")){
                custVOS = regionCustUserMapper.selectPublicCustByCode(codeList, deptCode);
            }else if(regionGrid.getOpsDept().equals("2")){
                custVOS = regionCustUserMapper.selectCustByCode(codeList, deptCode);
            }
            pageInfo = new PageInfo<>(custVOS);
            if (pageInfo.getList().isEmpty()) {
                continue;
            }
            List<RegionCustUser> custUserList = new ArrayList<>();
            for (CustVO custVO : pageInfo.getList()) {
                RegionCustUser regionCustUser = new RegionCustUser();
                regionCustUser.setTopGridId(regionGrid.getGridId());
                regionCustUser.setTopGridName(regionGrid.getGridName());
                regionCustUser.setOpsDept(regionGrid.getOpsDept());
                regionCustUser.setTopGridDutyType(regionGrid.getGridDutyType());
                BeanUtils.copyProperties(custVO, regionCustUser);
                AdminDivision adminDivisionByCode = sysAddressService.getAdminDivisionByCode(custVO.getCode());
                regionCustUser.setRegionName(adminDivisionByCode.getTown() + '-' + adminDivisionByCode.getVillage());
                regionCustUser.setCreator(creator.getNickName() + '-' + regionGrid.getCreateBy());
                regionCustUser.setCreatorId(creator.getUserId());
                regionCustUser.setCreatorName(creator.getNickName());
                regionCustUser.setCreateDeptId(regionGrid.getDeptId());
                regionCustUser.setCreateDeptName(createDept.getDeptName());
                regionCustUser.setBranchIds(branchIds);
                regionCustUser.setBranchNames(branchNames);
                custUserList.add(regionCustUser);
            }
            regionCustUserMapper.batchInsert(custUserList, deptCode);
            pageNum++;
        } while (pageNum <= pageInfo.getPages());
        log.info("开始更新归属二级网格：{}", gridId);
        List<Long> secGridIdByTopGridId = regionGridMapper.getSecGridIdByTopGridId(gridId);
        if(!secGridIdByTopGridId.isEmpty()){
            for (Long secGridId : secGridIdByTopGridId) {
                updateSecGrid(secGridId);
            }
        }
        log.info("更新网格：{}成功", gridId);
    }

    /**
     * @param gridId
     */
    @Override
    @Async
    public void updateSecGrid(Long gridId) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("开始更新二级网格：{}", gridId);
        RegionGrid regionGrid = regionGridMapper.selectById(gridId);
        if (Objects.isNull(regionGrid)){
            log.error("二级网格不存在：{}", gridId);
            return;
        }
        String deptCode = String.valueOf(regionGrid.getDeptId()).substring(0, 3);
        RegionGrid parentGrid = regionGridMapper.selectById(regionGrid.getParentGridId());

        LambdaQueryWrapper<RegionAdminDivisionRelate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionAdminDivisionRelate::getGridId, gridId);
        List<String> code = regionAdminDivisionRelateMapper.selectList(queryWrapper).stream().map(RegionAdminDivisionRelate::getCode).collect(Collectors.toList());

        LambdaQueryWrapper<RegionUserRelate> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RegionUserRelate::getGridId, gridId);
        List<RegionUserRelate> regionUserRelates = regionUserRelateMapper.selectList(queryWrapper1);
        List<GridUserDTO> userList = regionUserRelates.stream().map(regionUserRelate -> {
            GridUserDTO gridUserDTO = new GridUserDTO();
            gridUserDTO.setUserName(regionUserRelate.getUserName());
            gridUserDTO.setNickName(regionUserRelate.getNickName() + "-" + regionUserRelate.getUserName());
            if (regionUserRelate.getRelateDeptType().equals("outlet")) {
                gridUserDTO.setOutletId(regionUserRelate.getRelateDeptId());
                gridUserDTO.setOutletName(regionUserRelate.getRelateDeptName());
            }
            return gridUserDTO;
        }).collect(Collectors.toList());
        List<Long> collect = userList.stream().filter(gridUserDTO -> Objects.nonNull(gridUserDTO.getOutletId())).map(gridUserDTO -> gridUserDTO.getOutletId()).distinct().collect(Collectors.toList());
        String outletIds = null;
        String outletNames = null;
        if (collect.size() > 0) {
            outletIds = collect.stream().map(String::valueOf).collect(Collectors.joining(","));
            outletNames = userList.stream().filter(gridUserDTO -> Objects.nonNull(gridUserDTO.getOutletName()))
                    .map(gridUserDTO -> gridUserDTO.getOutletName()).distinct().collect(Collectors.joining(","));
        }
        String userNames = userList.stream().map(gridUserDTO -> gridUserDTO.getUserName()).distinct().collect(Collectors.joining(","));
        String nickNames = userList.stream().map(gridUserDTO -> gridUserDTO.getNickName()).distinct().collect(Collectors.joining(","));
        regionCustUserMapper.batchUpdate(deptCode, code, parentGrid.getGridId(), regionGrid.getGridId(), regionGrid.getGridName(), regionGrid.getGridDutyType(),
                outletIds, outletNames, userNames, nickNames);

        // 固定处理移交出去
        LambdaQueryWrapper<GridRegionTransfer> ignoreQW = new LambdaQueryWrapper<>();
        ignoreQW.eq(GridRegionTransfer::getPrevGridId, gridId)
                .eq(GridRegionTransfer::getStatus, "2");
        List<GridRegionTransfer> ignoreList = regionGridTransferMapper.selectList(ignoreQW);
        if (!ignoreList.isEmpty()) {
            List<String> deleteList = ignoreList.stream().map(GridRegionTransfer::getCustId).collect(Collectors.toList());
            regionCustUserMapper.deleteByCustIdInSecGrid(deleteList, gridId, deptCode);
        }
        // 处理移交进来
        LambdaQueryWrapper<GridRegionTransfer> transferQW = new LambdaQueryWrapper<>();
        transferQW.eq(GridRegionTransfer::getNextGridId, gridId).eq(GridRegionTransfer::getStatus, "2");
        List<GridRegionTransfer> transferList = regionGridTransferMapper.selectList(transferQW);
        if (!transferList.isEmpty()) {
            RegionCustUser regionCustUser = getRegionCustUser(transferList.get(0));
            List<RegionCustUser> custUserList = new ArrayList<>();
            for (GridRegionTransfer gridRegionTransfer : transferList) {
                if (regionCustUserMapper.checkCustInSecGrid(gridRegionTransfer.getCustId(), gridId, deptCode) > 0) {
                    continue;
                }
                RegionCustUser transfer = new RegionCustUser();
                BeanUtils.copyProperties(regionCustUser, transfer);
                transfer.setIsTransfer(Boolean.TRUE);
                transfer.setCustId(gridRegionTransfer.getCustId());
                transfer.setCustName(gridRegionTransfer.getCustName());
                transfer.setCustType(gridRegionTransfer.getCustType());
                custUserList.add(transfer);
            }
            regionCustUserMapper.batchInsert(custUserList, deptCode);
        }
        log.info("更新二级网格：{}成功", gridId);
    }

    /**
     * @param gridId
     */
    @Override
    @Async
    public void deleteTopGrid(String dept,Long gridId) {
        log.info("开始删除一级网格：{}", gridId);
        regionCustUserMapper.batchDeleteTopGrid(gridId, dept);
        log.info("删除一级网格：{}成功", gridId);
    }

    /**
     * @param gridId
     */
    @Override
    @Async
    public void deleteSecGrid(String dept, Long gridId) {
        log.info("开始删除二级网格：{}", gridId);
        regionCustUserMapper.batchDeleteSecGrid(gridId, dept);
        log.info("删除二级网格：{}成功", gridId);
    }

    /**
     *
     */
    @Override
    @Async
    public void updateCurrentGrid() {
        log.info("开始全量更新行政网格");
        LambdaQueryWrapper<RegionGrid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionGrid::getGridLevel, "1");
        List<RegionGrid> regionGrids = regionGridMapper.selectList(queryWrapper);
        regionGrids.forEach(regionGrid -> {
            updateTopGrid(regionGrid.getGridId());
        });
    }

    @Override
    public void updateCurrentGrid(String[] depts) {
        log.info("开始更新行政网格:" + Arrays.toString(depts));
        LambdaQueryWrapper<RegionGrid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionGrid::getGridLevel, "1");
        queryWrapper.in(RegionGrid::getDeptId, depts);
        List<RegionGrid> regionGrids = regionGridMapper.selectList(queryWrapper);
        regionGrids.forEach(regionGrid -> {
            updateTopGrid(regionGrid.getGridId());
        });
    }

    @Override
    @Async
    public void updateCurrentGrid(String dept) {
        log.info("开始更新行政网格");
        LambdaQueryWrapper<RegionGrid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionGrid::getGridLevel, "1");
        queryWrapper.like(RegionGrid::getDeptId, dept);
        List<RegionGrid> regionGrids = regionGridMapper.selectList(queryWrapper);
        regionGrids.forEach(regionGrid -> {
            updateTopGrid(regionGrid.getGridId());
        });
    }

    private RegionCustUser getRegionCustUser(GridRegionTransfer gridRegionTransfer) {
        RegionGrid secGrid = regionGridMapper.selectById(gridRegionTransfer.getNextGridId());
        RegionGrid regionGrid = regionGridMapper.selectById(secGrid.getParentGridId());
        SysUser creator = sysUserMapper.selectUserByUserName(regionGrid.getCreateBy());
        SysDept createDept = sysDeptMapper.selectDeptById(regionGrid.getDeptId());

        LambdaQueryWrapper<RegionUserRelate> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RegionUserRelate::getGridId, regionGrid.getGridId());
        List<RegionUserRelate> deptList = regionUserRelateMapper.selectList(queryWrapper1);
        String branchIds = deptList.stream().map(regionUserRelate -> regionUserRelate.getRelateDeptId().toString()).collect(Collectors.joining(","));
        String branchNames = deptList.stream().map(regionUserRelate -> regionUserRelate.getRelateDeptName()).collect(Collectors.joining(","));

        RegionCustUser regionCustUser = new RegionCustUser();
        regionCustUser.setTopGridId(regionGrid.getGridId());
        regionCustUser.setTopGridName(regionGrid.getGridName());
        regionCustUser.setOpsDept(regionGrid.getOpsDept());
        regionCustUser.setCreator(regionGrid.getCreateBy());
        regionCustUser.setCreatorId(creator.getUserId());
        regionCustUser.setCreatorName(creator.getNickName());
        regionCustUser.setCreateDeptId(regionGrid.getDeptId());
        regionCustUser.setCreateDeptName(createDept.getDeptName());
        regionCustUser.setBranchIds(branchIds);
        regionCustUser.setBranchNames(branchNames);

        LambdaQueryWrapper<RegionUserRelate> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(RegionUserRelate::getGridId, secGrid.getGridId());
        List<RegionUserRelate> regionUserRelates = regionUserRelateMapper.selectList(queryWrapper2);
        List<GridUserDTO> userList = regionUserRelates.stream().map(regionUserRelate -> {
            GridUserDTO gridUserDTO = new GridUserDTO();
            gridUserDTO.setUserName(regionUserRelate.getUserName());
            gridUserDTO.setNickName(regionUserRelate.getNickName() + "-" + regionUserRelate.getUserName());
            if (regionUserRelate.getRelateDeptType().equals("outlet")) {
                gridUserDTO.setOutletId(regionUserRelate.getRelateDeptId());
                gridUserDTO.setOutletName(regionUserRelate.getRelateDeptName());
            }
            return gridUserDTO;
        }).collect(Collectors.toList());
        List<Long> collect = userList.stream().filter(gridUserDTO -> Objects.nonNull(gridUserDTO.getOutletId())).map(gridUserDTO -> gridUserDTO.getOutletId()).distinct().collect(Collectors.toList());
        String outletIds = null;
        String outletNames = null;
        if (collect.size() > 0) {
            outletIds = collect.stream().map(String::valueOf).collect(Collectors.joining(","));
            outletNames = userList.stream().filter(gridUserDTO -> Objects.nonNull(gridUserDTO.getOutletName()))
                    .map(gridUserDTO -> gridUserDTO.getOutletName()).distinct().collect(Collectors.joining(","));
        }
        String userNames = userList.stream().map(gridUserDTO -> gridUserDTO.getUserName()).distinct().collect(Collectors.joining(","));
        String nickNames = userList.stream().map(gridUserDTO -> gridUserDTO.getNickName()).distinct().collect(Collectors.joining(","));
        regionCustUser.setSecGridId(secGrid.getGridId());
        regionCustUser.setSecGridName(secGrid.getGridName());
        regionCustUser.setUserNames(userNames);
        regionCustUser.setNickNames(nickNames);
        regionCustUser.setOutletIds(outletIds);
        regionCustUser.setOutletNames(outletNames);

        return regionCustUser;
    }
}
