package com.energy.manage.service.service.system.impl;


import cn.hutool.core.bean.BeanUtil;
import com.energy.manage.common.base.BaseServiceImpl;
import com.energy.manage.common.constant.Constants;
import com.energy.manage.common.enums.TypeRelationEnum;
import com.energy.manage.common.po.system.SysOrganizationAuthPO;
import com.energy.manage.common.po.system.SysPermissionPO;
import com.energy.manage.common.po.system.SysRolePermissionPO;
import com.energy.manage.common.po.windrelation.WindRelationPO;
import com.energy.manage.service.domain.dto.system.RoleUpdateOrganizationDto;
import com.energy.manage.service.domain.dto.system.SystemPermissionListDto;
import com.energy.manage.service.domain.vo.company.WindCompanyPageVo;
import com.energy.manage.service.domain.vo.system.PermissionVo;
import com.energy.manage.service.domain.vo.system.SysRelationVo;
import com.energy.manage.service.domain.vo.system.SystemPermissionVo;
import com.energy.manage.service.domain.vo.windrelation.WindRelationVo;
import com.energy.manage.service.mappers.system.SysOrganizationAuthMapper;
import com.energy.manage.service.mappers.system.SysPermissionMapper;
import com.energy.manage.service.mappers.system.SysRolePermissionMapper;
import com.energy.manage.service.mappers.windrelation.WindRelationMapper;
import com.energy.manage.service.service.system.SysPermissionService;
import com.energy.manage.service.util.BeanMapUtils;
import com.energy.manage.service.util.SplitUtil;
import com.energy.manage.service.util.TreeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@Transactional
public class SysPermissionServiceImpl extends BaseServiceImpl<SysPermissionPO> implements SysPermissionService {

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    @Autowired
    private SysRolePermissionMapper rolePermissionMapper;

    @Autowired
    private SysOrganizationAuthMapper sysOrganizationAuthMapper;

    @Autowired
    private WindRelationMapper windRelationMapper;


    @Override
    public boolean addPermission(SysPermissionPO po) {
        SysPermissionPO parent = new SysPermissionPO();
        parent.setPermissionId(po.getParentId());
        parent = sysPermissionMapper.selectOne(parent);
        if (null == parent) {
            po.setPermissionDepth(1);
        } else {
            po.setPermissionDepth(parent.getPermissionDepth() + 1);
        }
        return sysPermissionMapper.insert(po) > 0 ? true : false;
    }

    @Override
    public boolean delPermission(SysPermissionPO po) {
        SysRolePermissionPO rolePermissionPO = new SysRolePermissionPO();
        rolePermissionPO.setPermissionId(po.getPermissionId());
        rolePermissionMapper.delete(rolePermissionPO);
        return sysPermissionMapper.delete(po) > 0;
    }

    @Override
    public boolean updatePermission(SysPermissionPO po) {
        return sysPermissionMapper.updatePermissionSelective(po) >= 0;
    }

    @Override
    public List<SystemPermissionVo> getAllPermission(SystemPermissionListDto systemPermissionListDto) {
        List<SystemPermissionVo> list = sysPermissionMapper.getAllPermission(systemPermissionListDto);
        return TreeUtil.newConvert2Tree(list);
    }

    @Override
    public List<SystemPermissionVo> getRolePermission(Integer roleId) {
        List<Integer> rolePermission = rolePermissionMapper.getRolePermission(roleId);
        List<SystemPermissionVo> list = sysPermissionMapper.getAllPermission(new SystemPermissionListDto());
        list = checkPermission(list, rolePermission);
        return TreeUtil.newConvert2Tree(list);
    }


    @Override
    public List<Map<String, Object>> getRoleOrganization(Integer roleId) {

        List<String> roleOrganizationCode = rolePermissionMapper.getRoleOrganization(roleId);
        SysRelationVo sysRelationVo = null;
        List<SysRelationVo> sysRelationVos = Lists.newArrayList();
        List<WindRelationPO> list = windRelationMapper.selectAll();
        for (WindRelationPO po : list) {
            sysRelationVo = new SysRelationVo();
            BeanUtil.copyProperties(po, sysRelationVo);
            sysRelationVos.add(sysRelationVo);
        }
        sysRelationVos = checkOrganization(sysRelationVos, roleOrganizationCode);


        // 转化为Map集合
        List<Map<String, Object>> mapList = BeanMapUtils.listBeanToListMap(sysRelationVos);
        // 获取树形结构
        List<Map<String, Object>> java8ResultTree = TreeUtil.getJava8ResultTree(mapList);
        // map转list
//        List<SysRelationVo> voList = BeanMapUtils.convertListMapToJavaBean(java8ResultTree, SysRelationVo.class);

        return java8ResultTree;
    }


    @Override
    public List<PermissionVo> getRolePermissionByUserId(Integer userId) {
        List<PermissionVo> list = sysPermissionMapper.getRolePermissionByUserId(userId);
//    int depth = permissionMapper.getRolePermissionMaxDepth(userId);
//    return TreeUtil.convert2Tree(list, depth);
        return TreeUtil.convert2Tree(list);
    }

    @Override
    public boolean updateRolePermission(Integer roleId, String permissionIds) {
        List<Integer> list = SplitUtil.split2List(permissionIds, Integer.class);
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }
        SysRolePermissionPO po = new SysRolePermissionPO();
        po.setRoleId(roleId);
        rolePermissionMapper.delete(po);
        List<SysRolePermissionPO> dataList = new ArrayList<>(list.size());
        for (Integer item : list) {
            SysRolePermissionPO rolePermissionPO = new SysRolePermissionPO();
            rolePermissionPO.setRoleId(roleId);
            rolePermissionPO.setPermissionId(item);
            dataList.add(rolePermissionPO);
        }
        return rolePermissionMapper.insertList(dataList) > 0;
    }


    @Override
    public boolean updateRoleOrganization(Integer roleId, List<RoleUpdateOrganizationDto.OrganizationCode> organizationCodes, Integer userId, int type) {
        if (CollectionUtils.isEmpty(organizationCodes)) {
            return true;
        }
        SysOrganizationAuthPO po = new SysOrganizationAuthPO();
        po.setRoleId(roleId);
        if (type > 0) {
            sysOrganizationAuthMapper.delete(po);
        }
        List<SysOrganizationAuthPO> dataList = new ArrayList<>(organizationCodes.size());
        for (RoleUpdateOrganizationDto.OrganizationCode item : organizationCodes) {
            SysOrganizationAuthPO sysOrganizationAuthPO = new SysOrganizationAuthPO();
            sysOrganizationAuthPO.setRoleId(roleId);
            sysOrganizationAuthPO.setCodeNumber(item.getCodeNumber());
            sysOrganizationAuthPO.setCodeType(item.getCodeType());
            sysOrganizationAuthPO.setCreateTime(new Date());
            sysOrganizationAuthPO.setUpdateTime(new Date());
            sysOrganizationAuthPO.setCreateBy(userId);
            dataList.add(sysOrganizationAuthPO);
        }
        return sysOrganizationAuthMapper.insertList(dataList) > 0;
    }

    /**
     * 内部方法，验证用户权限
     *
     * @param list
     * @param pIdList
     * @return
     */
    private List<SystemPermissionVo> checkPermission(List<SystemPermissionVo> list, final List<Integer> pIdList) {
        if (CollectionUtils.isEmpty(pIdList)) {
            return list;
        }
        list.stream().forEach(item -> {
            if (pIdList.contains(item.getPermissionId().intValue())) {
                item.setChecked(Constants.GLOBAL_IN_USE);
            }
        });
        return list;
    }

    /**
     * 内部方法，验证用户权限
     *
     * @param sysRelationVos
     * @param roleOrganizationCode
     * @return
     */
    private List<SysRelationVo> checkOrganization(List<SysRelationVo> sysRelationVos, final List<String> roleOrganizationCode) {
        if (CollectionUtils.isEmpty(roleOrganizationCode)) {
            return sysRelationVos;
        }
        sysRelationVos.stream().forEach(item -> {
            if (roleOrganizationCode.contains(item.getCodeNumber().toString())) {
                item.setChecked(Constants.GLOBAL_IN_USE);
            }
        });
        return sysRelationVos;
    }
}
