package cn.palmte.work.service;

import cn.palmte.work.model.*;
import cn.palmte.work.pojo.PermissionNode;
import cn.palmte.work.pojo.PermissionTree;
import cn.palmte.work.utils.InterfaceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.jfunc.common.db.QueryHelper;
import top.jfunc.common.db.bean.Page;
import top.jfunc.common.db.utils.Pagination;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


@Service
public class SysRoleService {

    @Autowired
    private SysRoleRepository sysRoleRepository;
    @Autowired
    private SysPermissionRepository sysPermissionRepository;
    @Autowired
    private SysRolePermissionRepository sysRolePermissionRepository;
    @Autowired
    private SysRoleRepositoryImpl sysRoleRepositoryImpl;
    @Autowired
    private   SysRolePermissionService sysRolePermissionService;
    @Autowired
    private SysUserRoleRepository sysUserRoleRepository;

    @Autowired
    Pagination pagination;

    private static final Logger logger = LoggerFactory.getLogger(SysRoleService.class);
    private static final String SELECTED_PERMISSION_PREFIX = "rptList$ctl$cblActionType$";

    /**
     * 分页获取所有角色列表
     */
    public Page<SysRole> getAllRoleListByPage(ConcurrentHashMap<String, String> searchInfo, String pageNumber, int roleType){
        return sysRoleRepositoryImpl.getAllRoleListByPage(searchInfo,pageNumber,roleType);

    }

    public Page<SysRole> list(ConcurrentHashMap<String, String> searchInfo, int pageNumber, int pageSize){
        QueryHelper queryHelper = new QueryHelper("*", " FROM sys_role");
        queryHelper.addCondition("is_deleted=0");
        queryHelper.addCondition(searchInfo.containsKey("name"), "name like ?", "%" +
                searchInfo.get("name") + "%");
        queryHelper.addOrderProperty("created_time",false);
        return pagination.paginate(queryHelper.getSql(), SysRole.class, pageNumber, pageSize);
    }

    public List<SysRole> getAllRole(){
        return sysRoleRepository.findAll();
    }

    public List<SysRole> getAllEnableSysRole(){
        return sysRoleRepository.getAllEnableSysRole();
    }

    /**
     * 获取当前角色类型所有下级角色
     */
    public List<SysRole> geBelowRoleTypes(int roleType){
        return sysRoleRepositoryImpl.geBelowRoleTypes(roleType);
    }

    public List<SysRole> getBelowOneRoleTypes(int roleType){
        return sysRoleRepositoryImpl.getBelowTypes(roleType);
    }

    public SysRole fingSysRoleById(int id){
       return   sysRoleRepository.findSysRoleById(id);
    }

    /**
     * 查询 权限结构树(用于新增角色)
     * @param roleId 当前登录人角色id
     * @return
     */
    public PermissionNode getPermissionNodeTree(int roleId){
        //获取当前登录人角色所拥有的权限列表
        List<SysPermission> permList=sysPermissionRepository.findPermissionByRoleId(roleId);

        List<Integer> selectedPermIdList = new ArrayList<Integer>();
        PermissionNode root = PermissionTree.parsePermsNodeTree(permList, selectedPermIdList);

        return root;
    }

    /**
     * 查询 权限结构树(用于编辑角色)
     * @param adminRoleId 当前登录人角色id
     * @param roleId 待分配角色id
     * @return
     */
    public  PermissionNode getPermissionNodeTreeForEdit(int adminRoleId, int roleId){

        List<SysPermission> permList=sysPermissionRepository.findPermissionByRoleId(adminRoleId);
        //已分配的权限id
        List<Integer> selectedPermIdList =sysRolePermissionService.getPermissionIds(roleId);
        PermissionNode root = PermissionTree.parsePermsNodeTree(permList, selectedPermIdList);
        return root;
    }

    /**
     *  新增角色或编辑角色
     */
    @Transactional(rollbackFor = Exception.class)
    public  void addOrUpdatePermission(Map<String, Object> reqMap,int roleId){
        int updateRoleId=0;
        if(-1 == roleId){
            // 新增角色
            updateRoleId=addToRoleTable(reqMap);
        } else{
            // 修改角色
            updateRoleId=updateToRoleTable(reqMap, roleId);
            // 删除原"角色-权限"映射关系
            sysRolePermissionRepository.deleteSysRolePermissionByRoleId(roleId);
        }
        // 获取权限选中PermissionID，写入tcm_sys_role_permission
        saveRolePermission(reqMap,updateRoleId);
    }



    private int addToRoleTable(Map<String, Object> reqMap){

        SysRole role=new SysRole();
        role.setName(reqMap.get("roleName")!=null?reqMap.get("roleName").toString():null);
        role.setLevel(Integer.parseInt(reqMap.get("level").toString()));
        role.setIsEnable(Integer.parseInt(reqMap.get("isActive").toString()));
        //role.setType(Integer.parseInt(reqMap.get("roleType").toString()));
        role.setCreatedBy(InterfaceUtil.getAdminId());//当前登录人
        role.setCreatedTime(new Date());
        role.setLastUpdatedBy(InterfaceUtil.getAdminId());
        role.setLastUpdatedTime(new Date());
        role.setType(1);
        role=sysRoleRepository.saveAndFlush(role);
        return role.getId();
    }

    /**
     * 保存角色权限到关联表tcm_sys_role_permission
     */
    private void saveRolePermission(Map<String, Object> reqMap,int roleId){
        /* 从数据库获取所有权限ID-ParentID映射集合 */
        Map<String, String> allPermissionMap = getAllPermissionMap();
        /* 从参数中获取选中权限ID列表 */
        List<String> selectPermissinoIdList = getSelectPermissionIdFromParams(reqMap, allPermissionMap);
        /* 保存选中权限ID---->sys_role_permission表 */
        saveSelectedPermissionIdList(roleId, selectPermissinoIdList);
    }


    /**
     * @Title: 从数据库获取所有权限ID-ParentID映射集合
     * @return Map<String,String>
     */
    private Map<String, String> getAllPermissionMap(){
        List<SysPermission> allPermission = sysPermissionRepository.findAllPermission();

        Map<String, String> permIdMaps = new HashMap<String, String>();
        for(SysPermission perm : allPermission){
            permIdMaps.put(String.valueOf(perm.getId()), String.valueOf(perm.getParentId()));
        }
        return permIdMaps;
    }


    /**
     * @Title: 从参数中获取选中permission
     * @param allPermissionIDMap  DB中所有权限ID集合
     * @return Map<String,String> 选中PermissionID以及其父节点集合
     */
    private List<String> getSelectPermissionIdFromParams(Map<String, Object> paraMap,
                                                         Map<String, String> allPermissionIDMap){
        List<String> selectPermissinoIDList = new ArrayList<String>();
        for(Map.Entry<String, Object> entry : paraMap.entrySet()){
            if(entry.getKey().startsWith(SELECTED_PERMISSION_PREFIX)){
                Object value = entry.getValue();
                putParentPermissionIntoMap(allPermissionIDMap, selectPermissinoIDList, value.toString());
            }
        }
        return selectPermissinoIDList;
    }

    /**
     * @Title: 保存选中权限ID---->tcm_sys_role_permission表
     * @param roleId 角色ID
     * @param selectPermissinoIdList 选中权限ID列表
     *
     */
    private void saveSelectedPermissionIdList(int roleId, List<String> selectPermissinoIdList){
        for(String pId : selectPermissinoIdList){
            save2RolePermission(roleId, pId);
        }
    }

    private void save2RolePermission(int roleId, String permissionId){
        SysRolePermission rolePerm = new SysRolePermission();
        rolePerm.setRoleId(roleId);
        rolePerm.setPermissionId(Integer.parseInt(permissionId));
        rolePerm.setCreatedBy(InterfaceUtil.getAdminId());
        rolePerm.setCreatedTime(new Date());
        rolePerm.setLastUpdatedBy(InterfaceUtil.getAdminId());
        rolePerm.setLastUpdatedTime(new Date());
        sysRolePermissionRepository.saveAndFlush(rolePerm);
    }



    /**
     * @Title: 找出当前节点的父节点，并放入Map中
     *
     * @param allPermissionMap 所有权限节点Map
     * @param selectPermissinoIDList 新增角色权限Map
     * @param permID 权限节点ID void
     *
     */
    private void putParentPermissionIntoMap(Map<String, String> allPermissionMap, List<String> selectPermissinoIDList,
                                            String permID){
        /* 找出父节点，添加到待插入PermissionMaps中 */
        String pid = permID;
        while(true){
            String parentID = allPermissionMap.get(pid);
            if(pid.equals("0")){
                break;
            } else{
                logger.info("pid=" + pid + ",parentID=" + parentID);
                if(!selectPermissinoIDList.contains(pid)){
                    selectPermissinoIDList.add(pid);
                }
                pid = parentID;
            }
        }
    }




    private int updateToRoleTable(Map<String, Object> reqMap, int roleId){

        SysRole role =sysRoleRepository.findSysRoleById(roleId);
        role.setName(reqMap.get("roleName").toString());
        role.setLevel(Integer.parseInt(reqMap.get("level").toString()));
        //role.setType(Integer.parseInt(reqMap.get("roleType").toString()));
        role.setIsEnable(Integer.parseInt(reqMap.get("isActive").toString()));
        role.setLastUpdatedBy(InterfaceUtil.getAdminId());
        role.setLastUpdatedTime(new Date());
        role=sysRoleRepository.saveAndFlush(role);
        return role.getId();
    }


    /**
     * 校验该角色名是否存在
     */
    public int cheakRoleName(int id,String name){
        return sysRoleRepository.cheakRoleName(id, name);
    }

    @Transactional()
    public String deleteSelectedPermission(String[] ids){

        StringBuffer success=new StringBuffer();
        StringBuffer fail=new StringBuffer();
        int successCount=0;
        int failCount=0;
        for(String id : ids){
            List<SysUserRole> userRoleList = sysUserRoleRepository.findRoleByRoleId(Integer.parseInt(id));
            SysRole role = sysRoleRepository.findSysRoleById(Integer.parseInt(id));
            if(userRoleList != null && userRoleList.size() > 0){
                failCount++;
                logger.info("角色[" + role.getName() + "]下存在用户，删除失败！");
                fail.append("[" + role.getName() + "]");
            }else {
                role.setDeleted(1);
                role.setLastUpdatedTime(new Date());
                role.setLastUpdatedBy(InterfaceUtil.getAdminId());
                sysRoleRepository.saveAndFlush(role);
                deleteRolePermissionMap(id);
                successCount++;
                logger.info("角色[" + role.getName() + "]，删除成功！");
                success.append("[" + role.getName() + "]");
            }
        }
        String allMsg="";
        if (successCount==0&&failCount!=0){
            allMsg=failCount+"个删除失败："+fail.toString()+"下存在用户，删除失败!";
        }else if (failCount==0&&successCount!=0) {
            allMsg=successCount+"个删除成功："+success.toString()+"。";
        }else if (failCount!=0&&successCount!=0){
            allMsg=successCount+"个删除成功："+success.toString()+"。         "+failCount+"个删除失败："+fail.toString()+"下存在用户，删除失败！";
        }
        return allMsg;
    }



    /**
     * 删除角色对应的权限 关联表
     */
    private void deleteRolePermissionMap(String roleId){
        sysRolePermissionRepository.deleteSysRolePermissionByRoleId(Integer.parseInt(roleId));
    }

    /**
     * 启用、禁用
     * @param status
     * @param id
     * @return
     */
    public boolean enableOrDisable(int status, int id){
        SysRole one = sysRoleRepository.findOne(id);
        one.setIsEnable(status);
        SysRole sysRole = sysRoleRepository.saveAndFlush(one);

        if(null != sysRole){
            return true;
        }

        return false;
    }

}
