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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.ibs.dashboard.service.NotificationService;
import com.ruoyi.ibs.grid.domain.dto.GridRegionTransferDTO;
import com.ruoyi.ibs.grid.domain.dto.GridUserDTO;
import com.ruoyi.ibs.grid.domain.dto.TransferApproveDTO;
import com.ruoyi.ibs.grid.domain.entity.GridRegionTransfer;
import com.ruoyi.ibs.grid.domain.entity.RegionCustUser;
import com.ruoyi.ibs.grid.domain.entity.RegionGrid;
import com.ruoyi.ibs.grid.domain.entity.RegionUserRelate;
import com.ruoyi.ibs.grid.mapper.RegionCustUserMapper;
import com.ruoyi.ibs.grid.mapper.RegionGridMapper;
import com.ruoyi.ibs.grid.mapper.RegionGridTransferMapper;
import com.ruoyi.ibs.grid.mapper.RegionUserRelateMapper;
import com.ruoyi.ibs.grid.service.RegionGridTransferService;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author 吴凯程
 * @Date 2025/6/23
 **/
@Service
@Slf4j
public class RegionGridTransferServiceImpl implements RegionGridTransferService {
    @Resource
    private RegionGridTransferMapper regionGridTransferMapper;

    @Resource
    private RegionGridMapper regionGridMapper;

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private RegionUserRelateMapper regionUserRelateMapper;

    @Resource
    private RegionCustUserMapper regionCustUserMapper;

    @Resource
    private NotificationService notificationService;

    /**
     * @param gridRegionTransferDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGridTransfer(GridRegionTransferDTO gridRegionTransferDTO) {
        if (gridRegionTransferDTO.getPrevGridId() == gridRegionTransferDTO.getNextGridId()) {
            throw new ServiceException("原网格和移交网格不能相同");
        }
        LambdaQueryWrapper<GridRegionTransfer> exQW = new LambdaQueryWrapper<>();
        exQW.eq(GridRegionTransfer::getPrevGridId, gridRegionTransferDTO.getPrevGridId())
                .eq(GridRegionTransfer::getCustId, gridRegionTransferDTO.getCustId());
        GridRegionTransfer gridRegionTransfer = regionGridTransferMapper.selectOne(exQW);
        boolean existFlag = Objects.nonNull(gridRegionTransfer);
        if (!existFlag) {
            gridRegionTransfer = new GridRegionTransfer();

        }
        BeanUtils.copyProperties(gridRegionTransferDTO, gridRegionTransfer);
        RegionGrid prevGrid = regionGridMapper.selectById(gridRegionTransferDTO.getPrevGridId());
        if (Objects.isNull(prevGrid)) {
            throw new ServiceException("原网格不存在");
        }
        gridRegionTransfer.setOpsDept(prevGrid.getOpsDept());
        gridRegionTransfer.setPrevGridName(prevGrid.getGridName());
        LambdaQueryWrapper<RegionUserRelate> userQW = new LambdaQueryWrapper<>();
        userQW.eq(RegionUserRelate::getGridId, gridRegionTransferDTO.getPrevGridId());
        List<RegionUserRelate> prevUserRelates = regionUserRelateMapper.selectList(userQW);
        String prevUsers = prevUserRelates.stream().map(regionUserRelate -> regionUserRelate.getNickName().trim() + '-' + regionUserRelate.getUserName().trim())
                .collect(Collectors.joining(","));
        gridRegionTransfer.setPrevUser(prevUsers);
        SysDept sysDept = sysDeptMapper.selectDeptById(SecurityUtils.getDeptId());
        if (sysDept.getDeptType().equals("outlet")) {
            gridRegionTransfer.setPrevBranchId(sysDept.getParentId());
            gridRegionTransfer.setPrevBranchName(sysDept.getParentName());
        } else {
            gridRegionTransfer.setPrevBranchId(sysDept.getDeptId());
            gridRegionTransfer.setPrevBranchName(sysDept.getDeptName());
        }
        RegionGrid nextGrid = regionGridMapper.selectById(gridRegionTransferDTO.getNextGridId());
        if (Objects.isNull(nextGrid)) {
            throw new ServiceException("移交网格不存在");
        }
        gridRegionTransfer.setNextGridName(nextGrid.getGridName());

        LambdaQueryWrapper<RegionUserRelate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionUserRelate::getGridId, gridRegionTransferDTO.getNextGridId());
        List<RegionUserRelate> regionUserRelates = regionUserRelateMapper.selectList(queryWrapper);
        List<String> branchIds = new ArrayList<>();
        List<String> branchNames = new ArrayList<>();
        List<String> userNames = new ArrayList<>();
        for (RegionUserRelate regionUserRelate : regionUserRelates) {
            if (regionUserRelate.getRelateDeptType().equals("outlet")) {
                SysDept dept = sysDeptMapper.selectDeptById(regionUserRelate.getRelateDeptId());
                branchIds.add(dept.getParentId().toString());
                branchNames.add(dept.getParentName());
            } else {
                branchIds.add(regionUserRelate.getRelateDeptId().toString());
                branchNames.add(regionUserRelate.getRelateDeptName());
            }
            userNames.add(regionUserRelate.getNickName() + '-' + regionUserRelate.getUserName());
        }
        gridRegionTransfer.setNextBranchIds(String.join(",", branchIds));
        gridRegionTransfer.setNextBranchName(String.join(",", branchNames));
        gridRegionTransfer.setNextUsers(String.join(",", userNames));
        gridRegionTransfer.setStatus("0");
        if (existFlag) {
            gridRegionTransfer.setCreateTime(new Date());
            gridRegionTransfer.setCreateBy(SecurityUtils.getUsername());
            regionGridTransferMapper.updateById(gridRegionTransfer);
        } else {
            regionGridTransferMapper.insert(gridRegionTransfer);
        }
        return "移交审批流程提交成功";

    }

    /**
     * @param id
     * @param approveResult
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String branchApprove(TransferApproveDTO transferApproveDTO) {
        GridRegionTransfer gridRegionTransfer = regionGridTransferMapper.selectById(transferApproveDTO.getId());
        if (Objects.isNull(gridRegionTransfer) || !gridRegionTransfer.getStatus().equals("0")) {
            throw new ServiceException("审批流程不存在或已审批");
        }
        gridRegionTransfer.setApproveBranchResult(transferApproveDTO.getApproveResult());
        gridRegionTransfer.setApproveBranchUser(SecurityUtils.getUsername());
        if (transferApproveDTO.getApproveResult()) {
            List<String> nextBranchIds = Arrays.stream(gridRegionTransfer.getNextBranchIds().split(",")).collect(Collectors.toList());
            // 同支行下网格转交
            if (nextBranchIds.contains(gridRegionTransfer.getPrevBranchId().toString())) {
                gridRegionTransfer.setStatus("2");
                if (regionGridTransferMapper.updateById(gridRegionTransfer) > 0) {
                    updateGridTransfer(gridRegionTransfer);
                    List<String> nextUserName = getNextUserName(gridRegionTransfer.getNextUsers());
                    nextUserName.add(SecurityUtils.getUsername());
                    sendNotification(nextUserName, gridRegionTransfer.getNextGridName());
                }
            } else {
                // 跨支行转交 总行部室审批
                gridRegionTransfer.setStatus("1");
                regionGridTransferMapper.updateById(gridRegionTransfer);
            }
        } else {
            gridRegionTransfer.setStatus("-1");
            regionGridTransferMapper.updateById(gridRegionTransfer);
        }
        return "审批成功";
    }

    /**
     * @param id
     * @param approveResult
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String headApprove(TransferApproveDTO transferApproveDTO) {
        GridRegionTransfer gridRegionTransfer = regionGridTransferMapper.selectById(transferApproveDTO.getId());
        if (Objects.isNull(gridRegionTransfer) || !gridRegionTransfer.getStatus().equals("1")) {
            throw new ServiceException("审批流程不存在或已审批");
        }
        gridRegionTransfer.setApproveHeadResult(transferApproveDTO.getApproveResult());
        gridRegionTransfer.setApproveHeadUser(SecurityUtils.getUsername());
        if (transferApproveDTO.getApproveResult()) {
            gridRegionTransfer.setStatus("2");
            if (regionGridTransferMapper.updateById(gridRegionTransfer) > 0) {
                updateGridTransfer(gridRegionTransfer);
                List<String> nextUserName = getNextUserName(gridRegionTransfer.getNextUsers());
                RegionGrid regionGrid = regionGridMapper.selectById(gridRegionTransfer.getNextGridId());
                nextUserName.add(regionGrid.getCreateBy());
                sendNotification(nextUserName, gridRegionTransfer.getNextGridName());
            }
        } else {
            gridRegionTransfer.setStatus("-1");
            regionGridTransferMapper.updateById(gridRegionTransfer);
        }
        return "审批成功";
    }

    private void sendNotification(List<String> userNames, String gridName) {
        userNames.forEach(userName -> {
            String content = "您的网格：" + gridName + "有新移交的客户，请及时查看";
            notificationService.sendNotification(userName, content);
        });
    }

    private List<String> getNextUserName(String userNames) {
        String[] split = userNames.split(",");
        return Arrays.stream(split).map(userName -> {
            String[] split1 = userName.split("-");
            return split1[1];
        }).collect(Collectors.toList());

    }

    /**
     * @param gridRegionTransfer
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGridTransfer(GridRegionTransfer gridRegionTransfer) {
        LambdaQueryWrapper<RegionCustUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RegionCustUser::getSecGridId, gridRegionTransfer.getPrevGridId())
                .eq(RegionCustUser::getCustId, gridRegionTransfer.getCustId());
        RegionCustUser prevRegionCustUser = regionCustUserMapper.selectOne(queryWrapper);
        regionCustUserMapper.deleteById(prevRegionCustUser);

        LambdaQueryWrapper<RegionCustUser> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RegionCustUser::getSecGridId, gridRegionTransfer.getNextGridId()).last("LIMIT 1");
        RegionCustUser regionCustUser = regionCustUserMapper.selectOne(queryWrapper1);
        RegionCustUser nextRegionCustUser = new RegionCustUser();
        if (Objects.isNull(regionCustUser)) {
            nextRegionCustUser = getRegionCustUser(gridRegionTransfer);
        } else {
            BeanUtils.copyProperties(regionCustUser, nextRegionCustUser);
            nextRegionCustUser.setId(null);
        }
        nextRegionCustUser.setIsTransfer(Boolean.TRUE);
        nextRegionCustUser.setCode(null);
        nextRegionCustUser.setCustId(gridRegionTransfer.getCustId());
        nextRegionCustUser.setCustName(gridRegionTransfer.getCustName());
        nextRegionCustUser.setCustType(gridRegionTransfer.getCustType());
        regionCustUserMapper.insert(nextRegionCustUser);
        log.info("客户号：{} 网格转交成功", gridRegionTransfer.getCustId());
    }

    @Override
    public 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;
    }

    /**
     * @return
     */
    @Override
    public List<GridRegionTransfer> getGridRegionTransferList() {
        LambdaQueryWrapper<GridRegionTransfer> queryWrapper = new LambdaQueryWrapper<>();
        if (SecurityUtils.isHead()) {
            queryWrapper.eq(GridRegionTransfer::getStatus, "1").like(GridRegionTransfer::getCreateBy, SecurityUtils.getHeadId());
        } else if (SecurityUtils.userRole().equals("branch")) {
            queryWrapper.eq(GridRegionTransfer::getStatus, "0").eq(GridRegionTransfer::getPrevBranchId, SecurityUtils.getDeptId());
        } else if (SecurityUtils.userRole().equals("manager")) {
            queryWrapper.like(GridRegionTransfer::getCreateBy, SecurityUtils.getUsername());
        } else {
            return null;
        }
        return regionGridTransferMapper.selectList(queryWrapper);
    }

    @Override
    public List<RegionGrid> getSecGridList() {
        String deptCode = SecurityUtils.getHeadId();
        LambdaQueryWrapper<RegionGrid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(RegionGrid::getDeptId, deptCode).eq(RegionGrid::getGridLevel, "2");
        return regionGridMapper.selectList(queryWrapper);
    }
}
