package com.sunxung.factoring.service.sys.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.sunxung.factoring.component.util.ConstantConversionUtil;
import com.sunxung.factoring.service.sys.dto.PermissionDTO;
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 com.alibaba.fastjson.JSONArray;
import com.sunxung.factoring.component.cache.CacheKeyGenerator;
import com.sunxung.factoring.component.cache.RedisCache;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.CodeUtil;
import com.sunxung.factoring.component.util.ThreadLocalUtil;
import com.sunxung.factoring.component.util.ValidatorUtil;
import com.sunxung.factoring.entity.ValidatorEntity.ValidatorType;
import com.sunxung.factoring.entity.sys.Permission;
import com.sunxung.factoring.entity.sys.Role;
import com.sunxung.factoring.entity.sys.vo.PermissionTreeNode;
import com.sunxung.factoring.mapper.sys.PermissionMapper;
import com.sunxung.factoring.service.sys.PermissionService;
import com.sunxung.factoring.service.sys.RoleService;

/**
 * @Description:系统权限业务层
 * @Author:JingJiang
 * @E-mail:254702920@qq.com
 * @Date:2017年6月6日 下午5:19:48
 */
@Service
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private RoleService roleService;
//    @Autowired
//    RedisCache redisCache;

    @Transactional
    @Override
    public Permission add(Permission permission) {
        ValidatorUtil.validator(ValidatorType.ADD, permission);
        permissionMapper.add(permission);
        return get(permission.getId());
    }

    @Transactional
    @Override
    public Permission update(Permission permission) {
        ValidatorUtil.validator(ValidatorType.UPDATE, permission);
        permissionMapper.update(permission);
       // cachePermission(permissionMapper.get(permission.getId()));
        return get(permission.getId());
    }

    @Transactional
    @Override
    public void delete(Long id) {
        Permission permission = permissionMapper.get(id);
        if (permission != null) {
            permissionMapper.delete(id);
            //redisCache.remove(CacheKeyGenerator.generateCacheKeyFromId(Permission.class, id));
        }
    }

    @Override
    public Permission get(Long id) {
//        Permission permission = (Permission) redisCache
//                .get(CacheKeyGenerator.generateCacheKeyFromId(Permission.class, id));
//        if (permission == null) {
//            permission = permissionMapper.get(id);
//            cachePermission(permission);
//        }
        Permission permission = permissionMapper.get(id);
        return permission;
    }

    @Override
    public List<Permission> findAll() {
        return permissionMapper.findAll();
    }

    @Override
    public Permission getByEname(String ename) {
//        Permission permission = (Permission) redisCache
//                .get(CacheKeyGenerator.generateCacheKeyFromString(Permission.class, ename));
//        if (permission == null) {
//            permission = permissionMapper.getByEname(ename);
//        }
        Permission permission = permissionMapper.getByEname(ename);
        return permission;
    }

    /**
     * 获取根节点
     */
    @Transactional
    @Override
    public List<PermissionTreeNode> findRootByParentId(Long roleId) {
        List<Permission> list = permissionMapper.findByParentId(null);
        List<PermissionTreeNode> roleTree = new ArrayList<PermissionTreeNode>();
        if (list != null) {
            for (Permission per : list) {
                boolean ss = false;
                List<Long> permission = roleService.findPermissionIdByRoleId(roleId);
                for (int i = 0; i < permission.size(); i++) {
                    if (per.getId().equals(permission.get(i))) {
                        ss = true;
                    }
                }
                per.setCheck(ss);
                per.setCount(permissionMapper.findByParentId(per.getId()).size());
                roleTree.add(new PermissionTreeNode(per));
            }
        }
        return roleTree;
    }

    /**
     * 获取权限数信息
     */
    public List<PermissionTreeNode> findNodeByParentId(Long parentId, Long roleId) {
        List<Permission> list = permissionMapper.findByParentId(parentId);
        List<PermissionTreeNode> trees = new ArrayList<PermissionTreeNode>();
        if (list != null) {
            for (Permission per : list) {
                boolean ss = false;
                List<Long> permission = roleService.findPermissionIdByRoleId(roleId);
                for (int i = 0; i < permission.size(); i++) {
                    if (per.getId().equals(permission.get(i))) {
                        ss = true;
                    }
                }
                per.setCheck(ss);
                per.setCount(permissionMapper.findByParentId(per.getId()).size());
                trees.add(new PermissionTreeNode(per));
            }
        }
        return trees;
    }

    /**
     * 根据permissionId获取缓存中的permission信息
     * 
     * @param permissionId
     * @return
     */
//    public Permission getRedisByPermissionId(String permissionId) {
//        Permission permission = (Permission) redisCache
//                .get(CacheKeyGenerator.generateCacheKeyFromString(Permission.class, permissionId));
//        return permission;
//    }

    /**
     * 缓存permission
     * 
     */
//    private void cachePermission(Permission permission) {
//        if (permission != null) {
//            String cacheKey = CacheKeyGenerator.generateCacheKeyFromId(Permission.class, permission.getId());
//            redisCache.set(cacheKey, permission);
//            String cacheKey2 = CacheKeyGenerator.generateCacheKeyFromString(Permission.class, permission.getEname());
//            redisCache.set(cacheKey2, permission);
//        }
//    }

    @Override
    public boolean deleteRolePermissionRel(Long permissionId, Long roleId) {
        return permissionMapper.deleteRolePermissionRel(permissionId, roleId) > 0;
    }

    @Override
    public List<Long> findNodesByRoleIdPermissionId(Long parentId, Long roleId) {
        return permissionMapper.findNodesByRoleIdPermissionId(parentId, roleId);
    }

    /** 保存已拥有根权限 */
    public List<Permission> haveRootPermission(Long userId, List<Permission> list) {
        List<Permission> delRole = new ArrayList<Permission>();
        List<Long> haveRootRole = permissionMapper.getPermissionIdByUserId(userId);
        for (int i = 0; i < list.size(); i++) {
            if (delRole.contains(list.get(i).getId())) {
                continue;
            }
            if (haveRootRole.contains(list.get(i).getId())) {
                delRole.add(list.get(i));
            }
        }
        return delRole;
    }

    /** 添加时判断展示根节点树时 是否只显示已拥有权限 */
    private List<Permission> getHaveRootPermission() {
        List<Permission> delRole = null;
        if (!ThreadLocalUtil.getUser().getAdmin()) {
            List<Permission> list = permissionMapper.findByParentId(null);
            delRole = haveRootPermission(ThreadLocalUtil.getUserId(), list);
        } else {
            delRole = permissionMapper.findByParentId(null);
        }
        return delRole;
    }

    /** 保存已拥有子权限 */
    public List<Permission> haveNodePermission(Long userId, List<Permission> list) {
        List<Permission> delRole = new ArrayList<Permission>();
        List<Long> haveRootRole = permissionMapper.getPermissionIdByUserId(userId);
        for (int i = 0; i < list.size(); i++) {
            if (delRole.contains(list.get(i).getId())) {
                continue;
            }
            if (haveRootRole.contains(list.get(i).getId())) {
                delRole.add(list.get(i));
            }
        }
        return delRole;
    }

    /** 添加时判断展示子节点树时 是否只显示已拥有权限 */
    private List<Permission> getHaveNodePermission(List<Permission> listNodes) {
        List<Permission> delRole = new ArrayList<Permission>();
        if (!ThreadLocalUtil.getUser().getAdmin()) {
            delRole = haveNodePermission(ThreadLocalUtil.getUserId(), listNodes);
        } else {
            delRole = listNodes;
        }
        return delRole;
    }

    /**
     * 添加时获取根节点
     */
    @Transactional
    @Override
    public List<PermissionTreeNode> findRootByParentId() {
        List<Permission> delRole = getHaveRootPermission();
        List<PermissionTreeNode> roleTree = new ArrayList<PermissionTreeNode>();
        if (delRole != null) {
            for (Permission per : delRole) {
                List<Permission> nodes = null;
                nodes = permissionMapper.findByParentId(per.getId());
                if (!ThreadLocalUtil.getUser().getAdmin()) {
                    nodes = getHaveNodePermission(nodes);
                }
                per.setCheck(false);
                per.setCount(nodes.size());
                roleTree.add(new PermissionTreeNode(per));
            }
        }
        return roleTree;
    }

    /** 判断是否默认选中 */
    private boolean isChecked(Long roleId, Long parentId) {
        boolean ss = false;
        List<Long> permission = roleService.findPermissionIdByRoleId(roleId);
        for (int i = 0; i < permission.size(); i++) {
            if (parentId.equals(permission.get(i))) {
                ss = true;
            }
        }
        return ss;
    }

    private boolean isSelfRole(Long roleId) {
        Role role = roleService.get(roleId);
        if (role == null) {
            throw new ValidatorException(CodeUtil.FAIL, "当前角色没有组织机构");
        }
        return false;
    }

    /** 修改时判断展示根节点树时 是否只显示已拥有权限 */
    private List<Permission> getHaveRootPermission(Long roleId) {
        List<Permission> delRole = null;
        if (!ThreadLocalUtil.getUser().getAdmin() && isSelfRole(roleId)) {
            List<Permission> list = permissionMapper.findByParentId(null);
            delRole = haveRootPermission(ThreadLocalUtil.getUserId(), list);
        } else {
            delRole = permissionMapper.findByParentId(null);
        }
        return delRole;
    }

    /** 修改时判断展示子节点树时 是否只显示已拥有权限 */
    private List<Permission> getHaveNodePermission(List<Permission> listNodes, Long roleId) {
        List<Permission> delRole = new ArrayList<Permission>();
        if (!ThreadLocalUtil.getUser().getAdmin() && isSelfRole(roleId)) {
            delRole = haveNodePermission(ThreadLocalUtil.getUserId(), listNodes);
        } else {
            delRole = listNodes;
        }
        return delRole;
    }

    /**
     * 修改时获取根节点
     */
    @Override
    public List<PermissionTreeNode> findUpdateRootByParentId(Long roleId) {
        List<Permission> delRole = getHaveRootPermission(roleId);
        List<PermissionTreeNode> roleTree = new ArrayList<PermissionTreeNode>();
        if (delRole != null) {
            for (Permission per : delRole) {
                List<Permission> nodes = getHaveNodePermission(permissionMapper.findByParentId(per.getId()), roleId);
                per.setCount(nodes.size());
                per.setCheck(isChecked(roleId, per.getId()));
                roleTree.add(new PermissionTreeNode(per));
            }
        }
        return roleTree;
    }

    @Override
    public List<PermissionTreeNode> findNodeByParentId(Long parentId) {
        List<Permission> listPermission = getHaveNodePermission(permissionMapper.findByParentId(parentId));
        List<PermissionTreeNode> trees = new ArrayList<PermissionTreeNode>();
        if (listPermission != null) {
            for (Permission per : listPermission) {
                per.setCheck(false);
                List<Permission> nodes = getHaveNodePermission(permissionMapper.findByParentId(per.getId()));
                per.setCount(nodes.size());
                trees.add(new PermissionTreeNode(per));
            }
        }
        return trees;
    }

    @Override
    public List<Permission> findPermisionTree() {
        // 原始数据，所有的菜单
        List<Permission> root = permissionMapper.findAll();
        List<Permission> permissionList = new ArrayList<Permission>();
        for (int i = 0; i < root.size(); i++) {
            // 一级菜单没有parentId。查找所有的一级菜单
            if (root.get(i).getParentId() == null) {
                permissionList.add(root.get(i));
            }
        }
        // 为一级菜单设置子菜单，getChild是递归调用的
        for (Permission per : permissionList) {
            per.setChildPermission(getChild(per.getId(), root));
        }
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("menu", permissionList);
        String json = JSONArray.toJSONString(jsonMap);
        System.out.println(json);
        return permissionList;
    }

    private List<Permission> getChild(Long id, List<Permission> root) {
        // 子菜单
        List<Permission> childList = new ArrayList<>();
        for (Permission permission : root) {
            // 遍历所有的节点，将父菜单的ID与传过来的ID进行比较
            if (permission.getParentId() != null) {
                if (permission.getParentId().equals(id)) {
                    childList.add(permission);
                }
            }
        }
        for (Permission permission : childList) {
            // 递归
            permission.setChildPermission(getChild(permission.getId(), root));
        }
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }

    @Override
    public List<PermissionTreeNode> findUpdateNodeByParentId(Long parentId, Long roleId) {
        List<Permission> listPermission = getHaveNodePermission(permissionMapper.findByParentId(parentId), roleId);
        List<PermissionTreeNode> trees = new ArrayList<PermissionTreeNode>();
        if (listPermission != null) {
            for (Permission per : listPermission) {
                Long pId = roleService.isChecked(roleId, parentId);
                if (pId != null) {
                    per.setCheck(isChecked(roleId, per.getId()));
                } else {
                    per.setCheck(false);
                }
                List<Permission> nodes = getHaveNodePermission(permissionMapper.findByParentId(per.getId()), roleId);
                per.setCount(nodes.size());
                trees.add(new PermissionTreeNode(per));
            }
        }
        return trees;
    }

    @Override
    public List<Long> getPermissionIdByRoleId(Long roleId) {
        List<Long> list = permissionMapper.getPermissionIdByRoleId(roleId);
        return list;
    }

    @Override
    public List<Long> getPermissionIdByUserId(Long userId) {
        return permissionMapper.getPermissionIdByUserId(userId);
    }

    @Override
    public List<Permission> findAllByUserId(Long userId) {
        List<Permission> permissionList = new ArrayList<Permission>();
        if (null != userId) {
            // 原始数据，所有的菜单
            List<Permission> root = permissionMapper.findAllByUserId(userId);
            for (int i = 0; i < root.size(); i++) {
                // 一级菜单没有parentId。查找所有的一级菜单
                if (root.get(i).getParentId() == null) {
                    permissionList.add(root.get(i));
                }
            }
            // 为一级菜单设置子菜单，getChild是递归调用的
            for (Permission per : permissionList) {
                per.setChildPermission(getChild(per.getId(), root));
            }
        }
        return permissionList;
    }

    @Override
    public PermissionDTO getAllPermissionEname(Long userId) {

        List<Role> roleList = roleService.getRoleListByUseId();
        List<String> menuList = new ArrayList<>();
        List<String> buttonList = new ArrayList<>();
        List<Permission>   permissionList = Lists.newArrayList();
        boolean isAdmin = false;
        for (Role role : roleList) {
            if (ConstantConversionUtil.ADMINISTORIES_DISPLAYNAME.equals(role.getName())
                    || ConstantConversionUtil.CHILD_ADMINISTORIES_DISPLAYNAME.equals(role.getName())) {
                //如果是超级管理员或子管理员角色，默认返回所有
                permissionList = permissionMapper.findAll();
                isAdmin = true;
               // result = permissionAllList.stream().map(Permission::getEname).collect(Collectors.toList());

            }
        }
        if(!isAdmin){
            permissionList = permissionMapper.findAllByUserId(userId);
           // permissionList.removeAll(Collections.singleton(null));
        }
        menuList = permissionList.stream().filter(x->"menu".equals(x.getType())).map(Permission::getEname).collect(Collectors.toList());
        buttonList =  permissionList.stream().filter(x->"button".equals(x.getType())).map(Permission::getEname).collect(Collectors.toList());
        PermissionDTO permissionDTO = new PermissionDTO();
        permissionDTO.setButtons(buttonList);
        permissionDTO.setMenus(menuList);
        return permissionDTO;
    }
}
