package com.cm.plugin.map.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.cm.common.base.AbstractService;
import com.cm.common.exception.RemoveException;
import com.cm.common.exception.SearchException;
import com.cm.common.pojo.ListPage;
import com.cm.common.result.SuccessResultList;
import com.cm.common.utils.HashMapUtil;
import com.cm.common.utils.UUIDUtil;
import com.cm.plugin.map.dao.IGridDao;
import com.cm.plugin.map.pojo.dto.GridDTO;
import com.cm.plugin.map.pojo.dto.GridPointDTO;
import com.cm.plugin.map.pojo.dto.GridRelationDTO;
import com.cm.plugin.map.pojo.vo.GridPointVO;
import com.cm.plugin.map.pojo.vo.GridVO;
import com.cm.plugin.map.service.IGridService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: GridServiceImpl
 * @Description: 网格业务
 * @Author: WangGeng
 * @Date: 2020/10/21 11:14
 * @Version: 1.0
 **/
@Service
public class GridServiceImpl extends AbstractService implements IGridService {

    @Autowired
    private IGridDao gridDao;

    @Override
    public void saveGrid(GridVO gridVO) throws Exception {
        String gridId = UUIDUtil.getUUID();
        List<String> relationIdArray = gridVO.getRelationIdArray();
        List<GridPointVO> pointArray = gridVO.getPointArray();
        // 保存网格
        Map<String, Object> params = HashMapUtil.beanToMap(gridVO);
        params.put("gridId", gridId);
        params.remove("relationIdArray");
        params.remove("pointArray");
        setSaveInfo(params);
        gridDao.saveGrid(params);
        // 保存拓展属性
        saveRelationIdArray(gridId, relationIdArray);
        savePointArray(gridId, pointArray);
    }

    @Override
    public void updateGridPointArrayByGridId(String gridId, List<GridPointVO> pointArray) throws Exception {
        // 删除原有网格数组
        Map<String, Object> params = getHashMap(2);
        params.put("gridId", gridId);
        gridDao.deleteGridPoint(params);
        // 新增网格数组
        for (GridPointVO gridPointVO : pointArray) {
            params = HashMapUtil.beanToMap(gridPointVO);
            params.put("gridId", gridId);
            gridDao.saveGridPoint(params);
        }
    }

    @Override
    public void deleteGridByRelationId(String relationId) throws RemoveException {
        List<GridRelationDTO> gridRelationDTOs = listGridRelationByRelationId(relationId);
        if (gridRelationDTOs.isEmpty()) {
            return;
        }
        List<String> gridIds = new ArrayList<>();
        for (GridRelationDTO gridRelationDTO : gridRelationDTOs) {
            gridIds.add(gridRelationDTO.getGridId());
        }
        Map<String, Object> params = getHashMap(2);
        params.put("gridIds", gridIds);
        // 删除网格
        gridDao.deleteGrid(params);
        // 删除网格点
        gridDao.deleteGridPoint(params);
        // 删除关联关系
        params.clear();
        params.put("relationId", relationId);
        gridDao.deleteGridRelation(params);
    }

    @Override
    public void deleteGridByGridIds(List<String> gridIds) throws RemoveException {
        if (gridIds.isEmpty()) {
            return;
        }
        // 删除网格
        Map<String, Object> params = getHashMap(2);
        params.put("gridIds", gridIds);
        gridDao.deleteGrid(params);
        // 删除点数组
        gridDao.deleteGridPoint(params);
        // 删除关联
        gridDao.deleteGridRelation(params);
    }

    @Override
    public void deleteEmptyGrid(List<String> gridIds) {
        if (gridIds.isEmpty()) {
            return;
        }
        // 所有的网格和人员关联关系列表
        List<GridRelationDTO> gridRelationDTOs = listGridRelationByGridIds(gridIds);
        // 得到为空的网格
        List<String> emptyGridIds = new ArrayList<>();
        for (String gridId : gridIds) {
            boolean isEmpty = true;
            for (GridRelationDTO gridRelationDTO : gridRelationDTOs) {
                if (StringUtils.equals(gridId, gridRelationDTO.getGridId())) {
                    isEmpty = false;
                    break;
                }
            }
            if (isEmpty) {
                emptyGridIds.add(gridId);
            }
        }
        // 删除空网格
        deleteGridByGridIds(emptyGridIds);
    }

    @Override
    public void deleteGridRelation(String gridId, String relationId) throws RemoveException {
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        params.put("relationId", relationId);
        gridDao.deleteGridRelation(params);
    }

    @Override
    public List<GridRelationDTO> listGridRelationByRelationId(String relationId) throws SearchException {
        Map<String, Object> params = getHashMap(2);
        params.put("relationId", relationId);
        return gridDao.listGridRelation(params);
    }

    @Override
    public List<GridRelationDTO> listGridRelationByRelationIds(List<String> relationIds) throws SearchException {
        Map<String, Object> params = getHashMap(2);
        params.put("relationIds", relationIds);
        return gridDao.listGridRelation(params);
    }

    @Override
    public List<GridRelationDTO> listGridRelationByGridId(String gridId) throws SearchException {
        Map<String, Object> params = getHashMap(2);
        params.put("gridId", gridId);
        return gridDao.listGridRelation(params);
    }

    @Override
    public List<GridRelationDTO> listGridRelationByGridIds(List<String> gridIds) throws SearchException {
        Map<String, Object> params = getHashMap(2);
        params.put("gridIds", gridIds);
        return gridDao.listGridRelation(params);
    }

    @Override
    public List<GridDTO> listGridByRelationId(String relationId) throws SearchException {
        List<GridDTO> gridDTOs = gridDao.listGridByRelationId(relationId);
        if (gridDTOs.isEmpty()) {
            return gridDTOs;
        }
        for (GridDTO gridDTO : gridDTOs) {
            List<GridPointDTO> gridPointDTOs = gridDao.listPointByGridId(gridDTO.getGridId());
            gridDTO.setPointArray(gridPointDTOs);
        }
        return gridDTOs;
    }

    @Override
    public List<GridDTO> listGridGroupByRelationIds(List<String> relationIds) throws SearchException {
        if (relationIds == null || relationIds.size() == 0) {
            return new ArrayList<>();
        }
        List<GridDTO> gridDTOs = gridDao.listGridByRelationIds(relationIds);
        if (gridDTOs.isEmpty()) {
            return gridDTOs;
        }
        // 聚合后的网格
        List<GridDTO> gridGroupDTOs = listGridGroup(gridDTOs);
        // 只能展示包含关联人员列表的网格，比如：查询AB，那么可以展示的应该是AB...而不能是A
        for (int i = 0; i < gridGroupDTOs.size(); i++) {
            GridDTO gridDTO = gridGroupDTOs.get(i);
            // 关联人数多于片区人数，排除
            if (relationIds.size() > gridDTO.getRelationIdArray().size()) {
                gridGroupDTOs.remove(i);
                i--;
                continue;
            }
            // 判断关联人是否全部被片区包含
            boolean isAllExist = true;
            for (String relationId : relationIds) {
                if (!gridDTO.getRelationId().contains(relationId)) {
                    isAllExist = false;
                    break;
                }
            }
            // 不是全部包含，就删除
            if (!isAllExist) {
                gridGroupDTOs.remove(i);
                i--;
                continue;
            }
        }
        setGridPoints(gridGroupDTOs);
        return gridGroupDTOs;
    }

    @Override
    public List<GridDTO> listGridByRelationIds(List<String> relationIds) throws SearchException {
        if (relationIds == null || relationIds.size() == 0) {
            return new ArrayList<>();
        }
        List<GridDTO> gridDTOs = gridDao.listGridByRelationIds(relationIds);
        if (gridDTOs.isEmpty()) {
            return gridDTOs;
        }
        setGridPoints(gridDTOs);
        return gridDTOs;
    }

    /**
     * 设置网格点
     *
     * @param gridDTOs
     */
    private void setGridPoints(List<GridDTO> gridDTOs) {
        if (gridDTOs.isEmpty()) {
            return;
        }
        List<String> gridIds = new ArrayList<>();
        for (GridDTO gridDTO : gridDTOs) {
            gridIds.add(gridDTO.getGridId());
        }
        // 获取所有点
        List<GridPointDTO> gridPointDTOs = gridDao.listPointByGridIds(gridIds);
        if (gridPointDTOs.isEmpty()) {
            return;
        }
        // 构建所有点
        for (GridDTO gridDTO : gridDTOs) {
            List<GridPointDTO> pointArray = new ArrayList<>();
            for (GridPointDTO gridPointDTO : gridPointDTOs) {
                if (StringUtils.equals(gridDTO.getGridId(), gridPointDTO.getGridId())) {
                    pointArray.add(gridPointDTO);
                }
            }
            gridDTO.setPointArray(pointArray);
        }
    }

    /**
     * 得到聚合后的列表
     *
     * @param gridDTOs
     * @return
     */
    private List<GridDTO> listGridGroup(List<GridDTO> gridDTOs) {
        Map<String, GridDTO> gridMap = new HashMap<>(16);
        for (GridDTO gridDTO : gridDTOs) {
            GridDTO grid = gridMap.get(gridDTO.getGridId());
            if (grid == null) {
                grid = gridDTO;
                List<String> getRelationIdArray = new ArrayList<>();
                getRelationIdArray.add(gridDTO.getRelationId());
                gridDTO.setRelationIdArray(getRelationIdArray);
                gridMap.put(gridDTO.getGridId(), gridDTO);
            }
            // 合并relationId
            grid.getRelationIdArray().add(gridDTO.getRelationId());
        }
        List<GridDTO> gridGroups = new ArrayList<>();
        for (Map.Entry<String, GridDTO> kv : gridMap.entrySet()) {
            GridDTO gridDTO = kv.getValue();
            Collections.sort(gridDTO.getRelationIdArray());
            gridDTO.setRelationId(gridDTO.getRelationIdArray().toString());
            gridGroups.add(gridDTO);
        }
        return gridGroups;
    }

    @Override
    public SuccessResultList<List<GridDTO>> listPageGridByRelationIds(ListPage page, List<String> relationIds) {
        if (relationIds == null || relationIds.size() == 0) {
            return new SuccessResultList<>(new ArrayList<>(), 1, 0L);
        }
        PageHelper.startPage(page.getPage(), page.getRows());
        List<GridDTO> gridDTOs = gridDao.listGridByRelationIds(relationIds);
        PageInfo<GridDTO> pageInfo = new PageInfo<>(gridDTOs);
        return new SuccessResultList<>(gridDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    /**
     * 保存关联关系
     *
     * @param gridId
     * @param relationIdArray
     */
    private void saveRelationIdArray(String gridId, List<String> relationIdArray) {
        if (relationIdArray == null || relationIdArray.isEmpty()) {
            return;
        }
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        for (String relationId : relationIdArray) {
            params.put("relationId", relationId);
            gridDao.saveGridRelation(params);
        }
    }

    /**
     * 保存网格点
     *
     * @param gridId
     * @param pointArray
     */
    private void savePointArray(String gridId, List<GridPointVO> pointArray) {
        if (pointArray == null || pointArray.isEmpty()) {
            return;
        }
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        for (GridPointVO gridPointVO : pointArray) {
            params.put("lng", gridPointVO.getLng());
            params.put("lat", gridPointVO.getLat());
            gridDao.saveGridPoint(params);
        }
    }

}
