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

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.ibs.draw.domain.dto.grid.DrawGridAddDTO;
import com.ruoyi.ibs.draw.domain.entity.DrawShape;
import com.ruoyi.ibs.draw.mapper.DrawLayerMapper;
import com.ruoyi.ibs.draw.mapper.DrawShapeMapper;
import com.ruoyi.ibs.grid.domain.dto.RegionAdminDivisionDTO;
import com.ruoyi.ibs.grid.domain.dto.SecRegionGridDTO;
import com.ruoyi.ibs.grid.domain.dto.TopRegionGridDTO;
import com.ruoyi.ibs.grid.domain.dto.virtual.VirtualGridDTO;
import com.ruoyi.ibs.grid.domain.entity.RegionGrid;
import com.ruoyi.ibs.grid.domain.vo.AddressTreeVO;
import com.ruoyi.ibs.grid.domain.vo.GridRedisStateVO;
import com.ruoyi.ibs.grid.domain.vo.SecRegionGridRedisVO;
import com.ruoyi.ibs.grid.mapper.RegionGridMapper;
import com.ruoyi.ibs.grid.service.GridInfoRedisService;
import com.ruoyi.ibs.grid.service.RegionGridUtilsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Author 吴凯程
 * @Date 2024/11/1
 **/

@Service
public class GridInfoRedisServiceImpl implements GridInfoRedisService {

    @Resource
    private RedisCache redisCache;

    @Resource
    private RegionGridMapper regionGridMapper;

    @Resource
    private RegionGridUtilsService regionGridUtilsService;

    @Resource
    private DrawShapeMapper drawShapeMapper;

    @Resource
    private DrawLayerMapper drawLayerMapper;

    private final String topRegionRedisKey = "GRID_INFO_TOP_REGION_";

    private final String secRegionRedisKey = "GRID_INFO_SEC_REGION_";

    private final String virtualRedisKey = "GRID_INFO_VIRTUAL_";

    private final String drawRedisKey = "GRID_INFO_DRAW_";


    /**
     * @param topRegionGridDTO
     * @return
     */
    @Override
    public String saveTopRegionGridToRedis(TopRegionGridDTO topRegionGridDTO) {
        String username = SecurityUtils.getUsername();
        redisCache.setCacheObject(topRegionRedisKey + username, topRegionGridDTO);
        if (redisCache.hasKey(topRegionRedisKey + username)) {
            return "网格信息缓存成功！";
        } else {
            return "网格信息缓存失败！";
        }
    }

    /**
     * @return
     */
    @Override
    public TopRegionGridDTO getTopRegionGridFromRedis() {
        String username = SecurityUtils.getUsername();
        if (!redisCache.hasKey(topRegionRedisKey + username)) {
            throw new ServiceException("缓存中不存在暂存网格信息！");
        }
        TopRegionGridDTO topRegionGridDTO = redisCache.getCacheObject(topRegionRedisKey + username);
        if (Objects.nonNull(topRegionGridDTO.getAdminDivisionDTOList()) && !topRegionGridDTO.getAdminDivisionDTOList().isEmpty()) {
            List<RegionAdminDivisionDTO> adminDivisionDTOList = new ArrayList<>();
            List<String> selectedRegionCodes = regionGridMapper.getSelectedRegionCodes(SecurityUtils.getDeptId(), topRegionGridDTO.getOpsDept(), "1", null);
            topRegionGridDTO.getAdminDivisionDTOList().forEach(adminDivisionDTO -> {
                if (adminDivisionDTO.getCode().length() == 12 && !selectedRegionCodes.contains(adminDivisionDTO.getCode())) {
                    adminDivisionDTOList.add(adminDivisionDTO);
                }
            });
            topRegionGridDTO.setAdminDivisionDTOList(adminDivisionDTOList);
        }
        return topRegionGridDTO;
    }

    /**
     * @param secRegionGridDTO
     * @return
     */
    @Override
    public String saveSecRegionGridToRedis(SecRegionGridDTO secRegionGridDTO) {
        String username = SecurityUtils.getUsername();
        redisCache.setCacheObject(secRegionRedisKey + username, secRegionGridDTO);
        if (redisCache.hasKey(secRegionRedisKey + username)) {
            return "网格信息缓存成功！";
        } else {
            return "网格信息缓存成功！";
        }
    }

    /**
     * @return
     */
    @Override
    public SecRegionGridRedisVO getSecRegionGridFromRedis() {
        String username = SecurityUtils.getUsername();
        if (!redisCache.hasKey(secRegionRedisKey + username)) {
            throw new ServiceException("缓存中不存在暂存网格信息！");
        }
        SecRegionGridDTO secRegionGridDTO = redisCache.getCacheObject(secRegionRedisKey + username);

        RegionGrid parentGrid = regionGridMapper.selectById(secRegionGridDTO.getParentGridId());
        if (Objects.isNull(parentGrid)) {
            redisCache.deleteObject(secRegionRedisKey + username);
            throw new ServiceException("当前网格缓存信息已过期！");
        }

        SecRegionGridRedisVO secRegionGridRedisVO = new SecRegionGridRedisVO();
        BeanUtils.copyProperties(secRegionGridDTO, secRegionGridRedisVO);
        List<String> selectedRegionCodes = regionGridMapper.getSelectedRegionCodes(SecurityUtils.getDeptId(), parentGrid.getOpsDept(), "2", null);
        List<AddressTreeVO> topGridAddressTree = regionGridUtilsService.getTopGridAddressTree(secRegionGridDTO.getParentGridId(), selectedRegionCodes);
        secRegionGridRedisVO.setAddressTree(topGridAddressTree);

        if (Objects.nonNull(secRegionGridDTO.getAdminDivisionCodeList()) && !secRegionGridDTO.getAdminDivisionCodeList().isEmpty()) {
            List<String> adminDivisionCodeList = new ArrayList<>();
            secRegionGridDTO.getAdminDivisionCodeList().forEach(code -> {
                if (code.length() == 12 && !selectedRegionCodes.contains(code)) {
                    adminDivisionCodeList.add(code);
                }
            });
            secRegionGridRedisVO.setAdminDivisionCodeList(adminDivisionCodeList);
        }
        return secRegionGridRedisVO;
    }

    /**
     * @param virtualGridDTO
     * @return
     */
    @Override
    public String saveVirtualGridToRedis(VirtualGridDTO virtualGridDTO) {
        String username = SecurityUtils.getUsername();
        redisCache.setCacheObject(virtualRedisKey + username, virtualGridDTO);
        if (redisCache.hasKey(virtualRedisKey + username)) {
            return "网格信息缓存成功！";
        } else {
            return "网格信息缓存成功！";
        }
    }

    /**
     * @return
     */
    @Override
    public VirtualGridDTO getVirtualGridFromRedis() {
        String username = SecurityUtils.getUsername();
        if (!redisCache.hasKey(virtualRedisKey + username)) {
            throw new ServiceException("缓存中不存在暂存网格信息！");
        }
        return redisCache.getCacheObject(virtualRedisKey + username);
    }

    /**
     * @param drawGridAddDTO
     * @return
     */
    @Override
    public String saveDrawGridToRedis(DrawGridAddDTO drawGridAddDTO) {
        String username = SecurityUtils.getUsername();
        redisCache.setCacheObject(drawRedisKey + username, drawGridAddDTO);
        if (redisCache.hasKey(drawRedisKey + username)) {
            return "网格信息缓存成功！";
        } else {
            return "网格信息缓存成功！";
        }
    }

    /**
     * @return
     */
    @Override
    public DrawGridAddDTO getDrawGridFromRedis() {
        String username = SecurityUtils.getUsername();
        if (!redisCache.hasKey(drawRedisKey + username)) {
            throw new ServiceException("缓存中不存在网格信息！");
        }
        DrawGridAddDTO drawGridAddDTO = redisCache.getCacheObject(drawRedisKey + username);
        if (Objects.isNull(drawGridAddDTO.getLayerId()) || Objects.isNull(drawLayerMapper.selectById(drawGridAddDTO.getLayerId()))) {
            drawGridAddDTO.setLayerId(null);
            drawGridAddDTO.setShapeIds(null);
            return drawGridAddDTO;
        }
        List<Long> shapeIds = new ArrayList<>();
        if (Objects.nonNull(drawGridAddDTO.getShapeIds()) && !drawGridAddDTO.getShapeIds().isEmpty()) {
            for (Long shapeId : drawGridAddDTO.getShapeIds()) {
                DrawShape drawShape = drawShapeMapper.selectById(shapeId);
                if (Objects.nonNull(drawShape) && !drawShape.getRelateFlag()) {
                    shapeIds.add(shapeId);
                }
            }
        }
        drawGridAddDTO.setShapeIds(shapeIds);
        return drawGridAddDTO;
    }

    /**
     * @param gridType
     * @return
     */
    @Override
    public String cleanGridInfo(String gridType) {
        String username = SecurityUtils.getUsername();
        if (gridType.equals("1")) {
            redisCache.deleteObject(topRegionRedisKey + username);
        } else if (gridType.equals("2")) {
            redisCache.deleteObject(secRegionRedisKey + username);
        } else if (gridType.equals("3")) {
            redisCache.deleteObject(virtualRedisKey + username);
        } else if (gridType.equals("4")) {
            redisCache.deleteObject(drawRedisKey + username);
        } else {
            throw new ServiceException("网格类型传参错误");
        }
        return "暂存信息清除成功！";
    }

    /**
     * @return
     */
    @Override
    public GridRedisStateVO getUserRedisState() {
        GridRedisStateVO gridRedisStateVO = new GridRedisStateVO();
        String username = SecurityUtils.getUsername();
        gridRedisStateVO.setHasTopRegion(redisCache.hasKey(topRegionRedisKey + username));
        gridRedisStateVO.setHasSecRegion(redisCache.hasKey(secRegionRedisKey + username));
        gridRedisStateVO.setHasVirtual(redisCache.hasKey(virtualRedisKey + username));
        gridRedisStateVO.setHasDraw(redisCache.hasKey(drawRedisKey + username));
        return gridRedisStateVO;
    }
}
