package ink.wgink.module.map.service.grid.impl;

import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.RemoveException;
import ink.wgink.interfaces.map.IGridRelationDeleteAfterHandler;
import ink.wgink.interfaces.map.IGridRelationSaveAfterHandler;
import ink.wgink.module.map.dao.grid.IGridRelationDao;
import ink.wgink.module.map.pojo.dtos.grid.GridRelationDTO;
import ink.wgink.module.map.service.grid.IGridRelationService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @ClassName: GridRelationServiceImpl
 * @Description: 网格关联业务
 * @Author: wanggeng
 * @Date: 2021/8/30 10:08 下午
 * @Version: 1.0
 */
@Service
public class GridRelationServiceImpl extends DefaultBaseService implements IGridRelationService {

    @Autowired
    private IGridRelationDao gridRelationDao;
    @Autowired(required = false)
    private IGridRelationSaveAfterHandler gridRelationSaveAfterHandler;
    @Autowired(required = false)
    private IGridRelationDeleteAfterHandler gridRelationDeleteAfterHandler;

    @Override
    public void save(String gridId, List<String> relationIdArray) {
        save(null, gridId, relationIdArray);
    }

    @Override
    public void save(String token, String gridId, List<String> relationIdArray) {
        if (relationIdArray == null || relationIdArray.isEmpty()) {
            return;
        }
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        if (StringUtils.isBlank(token)) {
            setSaveInfo(params);
        } else {
            setAppSaveInfo(token, params);
        }
        for (String relationId : relationIdArray) {
            params.put("relationId", relationId);
            gridRelationDao.save(params);
        }
        if (gridRelationSaveAfterHandler != null) {
            gridRelationSaveAfterHandler.handle(relationIdArray);
        }
    }

    @Override
    public void delete(String gridId) {
        List<String> relationIds = listRelationId(gridId);
        Map<String, Object> params = getHashMap(2);
        params.put("gridId", gridId);
        gridRelationDao.delete(params);
        if (gridRelationDeleteAfterHandler != null) {
            gridRelationDeleteAfterHandler.handle(relationIds);
        }
    }

    @Override
    public void delete(String gridId, String relationId) throws RemoveException {
        List<String> existRelationIds = listRelationIdByGridIdAndRelationIds(gridId, Arrays.asList(relationId));
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        params.put("relationId", relationId);
        gridRelationDao.delete(params);
        if (gridRelationDeleteAfterHandler != null) {
            gridRelationDeleteAfterHandler.handle(existRelationIds);
        }
    }


    @Override
    public void delete(String gridId, List<String> relationIds) {
        List<String> existRelationIds = listRelationIdByGridIdAndRelationIds(gridId, relationIds);
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        params.put("relationIds", relationIds);
        gridRelationDao.delete(params);
        if (gridRelationDeleteAfterHandler != null) {
            gridRelationDeleteAfterHandler.handle(existRelationIds);
        }
    }

    @Override
    public void deleteByGridIds(List<String> gridIds) {
        List<String> existRelationIds = listRelationId(gridIds);
        Map<String, Object> params = getHashMap(2);
        params.put("gridIds", gridIds);
        gridRelationDao.delete(params);
        if (gridRelationDeleteAfterHandler != null) {
            gridRelationDeleteAfterHandler.handle(existRelationIds);
        }
    }

    @Override
    public void deleteByRelationId(String relationId) {
        Map<String, Object> params = getHashMap(2);
        params.put("relationId", relationId);
        gridRelationDao.delete(params);
        if (gridRelationDeleteAfterHandler != null) {
            gridRelationDeleteAfterHandler.handle(Arrays.asList(relationId));
        }
    }

    @Override
    public List<GridRelationDTO> listByRelationId(String relationId) {
        Map<String, Object> params = getHashMap(2);
        params.put("relationId", relationId);
        return gridRelationDao.list(params);
    }

    @Override
    public List<GridRelationDTO> list(Map<String, Object> params) {
        return gridRelationDao.list(params);
    }

    @Override
    public List<GridRelationDTO> listByRelationIds(List<String> relationIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("relationIds", relationIds);
        return list(params);
    }

    @Override
    public List<GridRelationDTO> listByGridId(String gridId) {
        Map<String, Object> params = getHashMap(2);
        params.put("gridId", gridId);
        return list(params);
    }

    @Override
    public List<GridRelationDTO> listByGridIds(List<String> gridIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("gridIds", gridIds);
        return list(params);
    }

    @Override
    public List<String> listGridId(String relationId) {
        List<GridRelationDTO> gridRelationDTOs = listByRelationId(relationId);
        return listGridIdByGridRelation(gridRelationDTOs);
    }

    @Override
    public List<String> listGridId(List<String> relationIds) {
        List<GridRelationDTO> gridRelationDTOs = listByRelationIds(relationIds);
        return listGridIdByGridRelation(gridRelationDTOs);
    }

    @Override
    public List<String> listRelationId(String gridId) {
        List<GridRelationDTO> gridRelationDTOs = listByGridId(gridId);
        return listRelationIdByGridRelation(gridRelationDTOs);
    }

    @Override
    public List<String> listRelationId(List<String> gridIds) {
        List<GridRelationDTO> gridRelationDTOs = listByGridIds(gridIds);
        return listRelationIdByGridRelation(gridRelationDTOs);
    }

    @Override
    public GridRelationDTO getByGridIdAndRelationId(String gridId, String relationId) {
        Map<String, Object> params = getHashMap(4);
        params.put("gridId", gridId);
        params.put("relationId", relationId);
        return gridRelationDao.get(params);
    }

    /**
     * 获取网格ID列表
     *
     * @param gridRelationDTOs
     * @return
     */
    private List<String> listGridIdByGridRelation(List<GridRelationDTO> gridRelationDTOs) {
        if (gridRelationDTOs.isEmpty()) {
            return new ArrayList<>();
        }
        Set<String> gridIdSet = new HashSet<>();
        gridRelationDTOs.forEach(gridRelationDTO -> {
            gridIdSet.add(gridRelationDTO.getGridId());
        });
        return new ArrayList<>(gridIdSet);
    }

    /**
     * 获取网格ID列表
     *
     * @param gridId
     * @param relationIds
     * @return
     */
    private List<String> listRelationIdByGridIdAndRelationIds(String gridId, List<String> relationIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("gridId", gridId);
        params.put("relationIds", relationIds);
        List<GridRelationDTO> gridRelationDTOs = list(params);
        return listGridIdByGridRelation(gridRelationDTOs);
    }

    /**
     * 获取网格ID列表
     *
     * @param gridRelationDTOs
     * @return
     */
    private List<String> listRelationIdByGridRelation(List<GridRelationDTO> gridRelationDTOs) {
        if (gridRelationDTOs.isEmpty()) {
            return new ArrayList<>();
        }
        Set<String> relationIdSet = new HashSet<>();
        gridRelationDTOs.forEach(gridRelationDTO -> {
            relationIdSet.add(gridRelationDTO.getRelationId());
        });
        return new ArrayList<>(relationIdSet);
    }

}
