package ink.wgink.service.permission.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.SearchException;
import ink.wgink.service.permission.pojo.vos.SystemApiVO;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.permission.PermissionDTO;
import ink.wgink.pojo.dtos.permission.PermissionGroupDTO;
import ink.wgink.pojo.result.SuccessResultData;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.service.permission.dao.IPermissionDao;
import ink.wgink.service.permission.pojo.vos.PermissionVO;
import ink.wgink.service.permission.service.IPermissionService;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.map.HashMapUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: PermissionServiceImpl
 * @Description: 权限
 * @Author: WenG
 * @Date: 2020-05-27 15:58
 * @Version: 1.0
 **/
@Service
public class PermissionServiceImpl extends DefaultBaseService implements IPermissionService {

    @Autowired
    private IPermissionDao permissionDao;

    @Override
    public void save(PermissionVO permissionVO) {
        Map<String, Object> params = getHashMap(4);
        params.put("permissionUrl", permissionVO.getPermissionUrl());
        params.put("permissionType", permissionVO.getPermissionType());
        params.put("apiTag", permissionVO.getApiTag());
        params.put("systemTag", permissionVO.getSystemTag());
        List<PermissionDTO> permissionDTOs = list(params);
        if (!permissionDTOs.isEmpty()) {
            throw new SearchException("权限已经存在");
        }
        savePermissionReturnId(permissionVO);
    }

    @Override
    public void saveQuick(String permissionType, SystemApiVO systemApiVO) {
        List<PermissionDTO> permissionDTOs = list(permissionType, systemApiVO.getSystemTag());
        List<SystemApiVO.ApiVO> apiVOs = systemApiVO.getApis();
        for (PermissionDTO permissionDTO : permissionDTOs) {
            for (int i = 0; i < apiVOs.size(); i++) {
                SystemApiVO.ApiVO apiVO = apiVOs.get(i);
                if (StringUtils.equalsIgnoreCase(permissionDTO.getApiTag(), apiVO.getApiTag()) &&
                        StringUtils.equalsIgnoreCase(permissionDTO.getPermissionUrl(), apiVO.getApi())) {
                    // 相同不进行添加
                    apiVOs.remove(i);
                    i--;
                }
            }
        }
        for (SystemApiVO.ApiVO apiVO : apiVOs) {
            PermissionVO permissionVO = new PermissionVO();
            permissionVO.setPermissionTitle(apiVO.getApiName());
            permissionVO.setPermissionUrl(apiVO.getApi());
            permissionVO.setPermissionType(permissionType);
            permissionVO.setApiTag(apiVO.getApiTag());
            permissionVO.setSystemTag(systemApiVO.getSystemTag());
            permissionVO.setIsPublic(0);
            savePermissionReturnId(permissionVO);
        }
    }

    @Override
    public String savePermissionReturnId(PermissionVO permissionVO) {
        String permissionId = UUIDUtil.getUUID();
        Map<String, Object> params = HashMapUtil.beanToMap(permissionVO);
        params.put("permissionId", permissionId);
        setSaveInfo(params);
        permissionDao.save(params);
        return permissionId;
    }

    @Override
    public void remove(List<String> ids) {
        Map<String, Object> params = getHashMap(3);
        params.put("permissionIds", ids);
        setUpdateInfo(params);
        permissionDao.remove(params);
    }

    @Override
    public void deletePermission(List<String> ids) {
        Map<String, Object> params = getHashMap(3);
        params.put("permissionIds", ids);
        permissionDao.delete(params);
    }

    @Override
    public void update(String permissionId, PermissionVO permissionVO) {
        Map<String, Object> params = HashMapUtil.beanToMap(permissionVO);
        params.put("permissionId", permissionId);
        setUpdateInfo(params);
        permissionDao.update(params);
    }

    @Override
    public PermissionDTO get(String permissionId) {
        Map<String, Object> params = super.getHashMap(1);
        params.put("permissionId", permissionId);
        return permissionDao.get(params);
    }

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

    @Override
    public SuccessResultList<List<PermissionDTO>> listPage(ListPage page) {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<PermissionDTO> permissionDTOs = permissionDao.list(page.getParams());
        PageInfo<PermissionDTO> pageInfo = new PageInfo<>(permissionDTOs);
        return new SuccessResultList<>(permissionDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public List<PermissionGroupDTO> listGroup(Map<String, Object> params) {
        List<PermissionDTO> permissionDTOs = list(params);
        // 聚合 group
        Map<String, PermissionGroupDTO> permissionGroupDTOMap = new HashMap<>(16);
        for (PermissionDTO permissionDTO : permissionDTOs) {
            PermissionGroupDTO permissionGroupDTO = permissionGroupDTOMap.get(permissionDTO.getSystemTag());
            if (permissionGroupDTO == null) {
                permissionGroupDTO = new PermissionGroupDTO();
                permissionGroupDTO.setSystemTag(permissionDTO.getSystemTag());
                permissionGroupDTO.setPermissionApis(new ArrayList<>());
                permissionGroupDTOMap.put(permissionDTO.getSystemTag(), permissionGroupDTO);
            }
        }
        if (permissionGroupDTOMap.isEmpty()) {
            return new ArrayList<>();
        }
        // 聚合 api
        Map<String, PermissionGroupDTO.PermissionApiDTO> permissionApiDTOMap = new HashMap<>(16);
        for (PermissionDTO permissionDTO : permissionDTOs) {
            PermissionGroupDTO.PermissionApiDTO permissionApiDTO = permissionApiDTOMap.get(permissionDTO.getApiTag());
            if (permissionApiDTO == null) {
                permissionApiDTO = new PermissionGroupDTO.PermissionApiDTO();
                permissionApiDTO.setSystemTag(permissionDTO.getSystemTag());
                permissionApiDTO.setApiTag(permissionDTO.getApiTag());
                permissionApiDTO.setPermissions(new ArrayList<>());
                permissionApiDTOMap.put(permissionDTO.getApiTag(), permissionApiDTO);
            }
            permissionApiDTO.getPermissions().add(permissionDTO);
        }
        List<PermissionGroupDTO> permissionGroupDTOs = new ArrayList<>();
        for (Map.Entry<String, PermissionGroupDTO> groupKV : permissionGroupDTOMap.entrySet()) {
            List<PermissionGroupDTO.PermissionApiDTO> permissionApis = new ArrayList<>();
            for (Map.Entry<String, PermissionGroupDTO.PermissionApiDTO> apiKV : permissionApiDTOMap.entrySet()) {
                if (StringUtils.equals(groupKV.getKey(), apiKV.getValue().getSystemTag())) {
                    permissionApis.add(apiKV.getValue());
                }
            }
            groupKV.getValue().setPermissionApis(permissionApis);
            permissionGroupDTOs.add(groupKV.getValue());
        }
        return permissionGroupDTOs;
    }

    @Override
    public Integer countNumberPermission(Map<String, Object> params) {
        Integer count = permissionDao.count(params);
        return count == null ? 0 : count;
    }

    @Override
    public SuccessResultData<Integer> count(Map<String, Object> params) {
        return new SuccessResultData<>(countNumberPermission(params));
    }

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

    @Override
    public List<PermissionDTO> list(String permissionType, String systemTag) {
        Map<String, Object> params = getHashMap(4);
        params.put("permissionType", permissionType);
        params.put("systemTag", StringUtils.isBlank(systemTag) ? DEFAULT_SYSTEM_TAG : systemTag);
        return list(params);
    }

}