package com.gz.service.system.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gz.common.DataGlobalVariable;
import com.gz.dto.system.MenuDTO;
import com.gz.dto.system.MenuRoleDTO;
import com.gz.dto.system.RoleDTO;
import com.gz.mapper.system.MenuRoleMapper;
import com.gz.mapper.system.RoleMapper;
import com.gz.service.system.MenuService;
import com.gz.service.system.RoleService;
import com.gz.utils.JwtUtils;
import com.gz.vo.system.RoleMenuVO;
import com.gz.vo.system.RoleVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author LiuchangLan
 * @date 2020/9/4 14:42
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private MenuRoleMapper menuRoleMapper;

    @Resource
    private MenuService menuService;

    @Override
    public Integer insert(RoleDTO roleDTO) {
        // 创建人
        roleDTO.setCreated(JwtUtils.getCurrentUserJwtPayload().getId());
        // 执行入库
        return roleMapper.insertSelective(roleDTO);
    }

    @Override
    public Integer delete(Integer id) {
        return roleMapper.deleteByPrimaryKey(id);
    }

    @Override
    public Integer update(RoleDTO roleDTO) {
        // 修改人
        roleDTO.setUpdated(JwtUtils.getCurrentUserJwtPayload().getId());
//        // 修改时间
//        roleDTO.setUpdateTime(DateUtil.now());
        // 执行入库
        return roleMapper.updateByPrimaryKeySelective(roleDTO);
    }

    @Override
    public PageInfo<RoleDTO> select(RoleVO roleVO) {
        if (roleVO.getPageNum() != null && roleVO.getPageSize() != null) {
            PageHelper.startPage(roleVO.getPageNum(), roleVO.getPageSize());
        }
        // 查询条件转换
        RoleDTO roleDTO = BeanUtil.copyProperties(roleVO, RoleDTO.class);
        // 查询未删除的数据
        return new PageInfo<>(roleMapper.select(roleDTO));
    }

    @Override
    public RoleDTO selectByPrimaryKey(Integer id) {
        RoleDTO roleDTO = new RoleDTO();
        roleDTO.setId(id);
        return roleMapper.selectOne(roleDTO);
    }

    @Override
    @Transactional
    public Integer setRole(RoleMenuVO vo) {
        String[] menuIds = vo.getMenuIds().split(",");
        String[] archiveTreeIds = vo.getArchiveTrees().split(",");
        String[] mijiIds = vo.getMjCodes().split(",");
        String[] archiveShow = vo.getArchiveShow().split(",");
        // 删除已有的权限
        Integer i = menuRoleMapper.deleteByRoleId(vo.getRoleId());

        /** 菜单权限控制*/
        if (StrUtil.isNotEmpty(vo.getMenuIds())) {
            for (String menuId : menuIds) {
                MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
                menuRoleDTO.setRoleId(vo.getRoleId());
                menuRoleDTO.setMenuId(Integer.parseInt(menuId));
                menuRoleDTO.setRoleType(DataGlobalVariable.ROLE_TYPE_MENU);
                i = menuRoleMapper.insert(menuRoleDTO);
            }
        }
        /** 档案树权限控制*/
        if (StrUtil.isNotEmpty(vo.getArchiveTrees())) {
            for (String archiveTreeId : archiveTreeIds) {
                MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
                menuRoleDTO.setRoleId(vo.getRoleId());
                menuRoleDTO.setMenuId(Integer.parseInt(archiveTreeId));
                menuRoleDTO.setRoleType(DataGlobalVariable.ROLE_TYPE_ARCHIVE_TREE);
                i = menuRoleMapper.insert(menuRoleDTO);
            }
        }

        /** 密级权限控制*/
        if (StrUtil.isNotEmpty(vo.getMjCodes())) {
            for (String mijiId : mijiIds) {
                MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
                menuRoleDTO.setRoleId(vo.getRoleId());
                menuRoleDTO.setMenuId(Integer.parseInt(mijiId));
                menuRoleDTO.setRoleType(DataGlobalVariable.ROLE_TYPE_MIJI);
                i = menuRoleMapper.insert(menuRoleDTO);
            }
        }
        /** 档案详情和文件权限控制*/
        if (StrUtil.isNotEmpty(vo.getArchiveShow())) {
            for (String s : archiveShow) {
                MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
                menuRoleDTO.setRoleId(vo.getRoleId());
                menuRoleDTO.setMenuId(Integer.parseInt(s));
                menuRoleDTO.setRoleType(DataGlobalVariable.ARCHIVE_SHOW);
                i = menuRoleMapper.insert(menuRoleDTO);
            }
        }
        /** 查看所有部门权限控制  0:不能查看全部功能，1：可查看*/
        if (vo.getBmqxRole() != null) {
            MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
            menuRoleDTO.setRoleId(vo.getRoleId());
            menuRoleDTO.setMenuId(vo.getBmqxRole());
            menuRoleDTO.setRoleType(DataGlobalVariable.ARCHIVE_DEPT);
            i = menuRoleMapper.insert(menuRoleDTO);
        }
        return i;
    }

    @Override
    public List<Tree<String>> selectRoleList(Integer roleId) {
        List<MenuDTO> menuDTOS = menuService.selectByOrder();

        MenuRoleDTO dto = new MenuRoleDTO();
        dto.setRoleId(roleId);
        dto.setRoleType(DataGlobalVariable.ROLE_TYPE_MENU);
        List<MenuRoleDTO> select = menuRoleMapper.select(dto);
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        treeNodeConfig.setIdKey("id");
        // 最大递归深度
        treeNodeConfig.setDeep(3);

        //转换器
        List<Tree<String>> treeNodes = TreeUtil.build(menuDTOS, "-1", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId().toString());
                    tree.setParentId(treeNode.getParentId().toString());
                    tree.setName(treeNode.getTitle());
                    tree.putExtra("title", treeNode.getTitle());

                    for (MenuRoleDTO menuRoleDTO : select) {
                        boolean flag = false;
                        // 判断是否有子元素
                        for (MenuDTO menuDTO1 : menuDTOS) {
                            if (menuDTO1.getParentId().equals(treeNode.getId())) {
                                flag = true;
                                break;
                            }
                        }
                        // 有权限 并且没有子元素的默认选中
                        if (menuRoleDTO.getMenuId().equals(treeNode.getId()) && !flag) {
                            flag = true;
                            tree.putExtra("checked", true);
                            break;
                        }
                    }
                });
        return treeNodes;
    }

    @Override
    public List<RoleDTO> selectAllRole() {
        return roleMapper.selectAll();
    }

    @Override
    public List<JSONObject> selectShowArchive(Integer roleId) {
        List<JSONObject> result = new ArrayList<>();
        result.add(new JSONObject().put("title", "详情").put("id", 1));
        result.add(new JSONObject().put("title", "文件").put("id", 2));
        result.add(new JSONObject().put("title", "水印").put("id", 3));
        result.add(new JSONObject().put("title", "下载").put("id", 4));
        MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
        menuRoleDTO.setRoleType(DataGlobalVariable.ARCHIVE_SHOW);
        menuRoleDTO.setRoleId(roleId);
        List<MenuRoleDTO> select = menuRoleMapper.select(menuRoleDTO);
        a:
        for (int i = 0; i < result.size(); i++) {
            for (MenuRoleDTO roleDTO : select) {
                if (result.get(i).get("id", Integer.class).equals(roleDTO.getMenuId())) {
                    result.get(i).put("checked", true);
                    continue a;
                }
            }
        }

        return result;
    }

    @Override
    public Boolean selectArchiveRole(Integer roleId,Integer roleLabel) {
        MenuRoleDTO menuRoleDTO = new MenuRoleDTO();
        menuRoleDTO.setRoleId(roleId);
        menuRoleDTO.setRoleType(DataGlobalVariable.ARCHIVE_SHOW);
        menuRoleDTO.setMenuId(roleLabel);
        return menuRoleMapper.selectCount(menuRoleDTO) > 0;
    }
}
