package com.huiju.estateagents.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huiju.estateagents.center.taUser.entity.TaUser;
import com.huiju.estateagents.center.taUser.entity.TaUserRole;
import com.huiju.estateagents.center.taUser.mapper.TaUserMapper;
import com.huiju.estateagents.center.taUser.mapper.TaUserRoleMapper;
import com.huiju.estateagents.common.CommConstant;
import com.huiju.estateagents.entity.SysMenu;
import com.huiju.estateagents.entity.TaRole;
import com.huiju.estateagents.entity.TaRoleButton;
import com.huiju.estateagents.entity.TaRoleMenu;
import com.huiju.estateagents.mapper.SysMenuMapper;
import com.huiju.estateagents.mapper.TaRoleMapper;
import com.huiju.estateagents.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 菜单表 不同系统,菜单不一致 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2019-09-11
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
    @Autowired
    SysMenuMapper sysMenuMapper;

    @Autowired
    TaRoleMapper taRoleMapper;

    @Autowired
    TaUserMapper taUserMapper;

    @Autowired
    TaUserRoleMapper taUserRoleMapper;

    @Override
    public List<SysMenu> getAllModules(Integer userId) {
        return sysMenuMapper.getUserModules(userId);
    }

    @Override
    public void authorizeModules(Integer userId, List<Integer> menuIds) throws Exception {
        // 人员
        TaUser taUser = taUserMapper.selectById(userId);
        if (null == taUser) {
            throw new Exception("授权人员不存在");
        }

        // 先更新角色, 如果没有就创建
        QueryWrapper<TaRole> queryRole = new QueryWrapper<>();
        queryRole.eq("org_id", taUser.getOrgId());
        queryRole.eq("is_admin", true);
        TaRole taRole = taRoleMapper.selectOne(queryRole);
        if (null == taRole) {
            taRole = new TaRole();
            taRole.setOrgId(taUser.getOrgId());
            taRole.setRoleName("管理员");
            taRole.setIsAdmin(true);
            taRole.setStatus(CommConstant.STATUS_NORMAL);
            taRole.setCreateDate(LocalDateTime.now());
            if (taRoleMapper.insert(taRole) < 1) {
                throw new Exception("生成管理员角色字典失败");
            }
        }

        QueryWrapper<TaUserRole> queryUserRole = new QueryWrapper<>();
        queryUserRole.eq("user_id", taUser.getUserId());
        queryUserRole.eq("role_id", taRole.getRoleId());
        if (taUserRoleMapper.selectCount(queryUserRole) < 1) {
            TaUserRole taUserRole = new TaUserRole();
            taUserRole.setRoleId(taRole.getRoleId());
            taUserRole.setUserId(taUser.getUserId());
            if (taUserRoleMapper.insert(taUserRole) < 1) {
                throw new Exception("生成管理员角色失败");
            }
        }

        // 再更新角色授权菜单
        // 处理菜单有个难点, 如果取消了某个模块. 那么需要把当前管理员所属 Org 的相关菜单，按钮都要取消
        // 但是, 如果新增了, 暂时不处理
        List<SysMenu> userModules = sysMenuMapper.getUserModules(taUser.getUserId());
        List<Integer> subMenus = minusMenu(userModules, menuIds);
        if (null != subMenus && subMenus.size() > 0) {
            sysMenuMapper.deleteAdminBtns(subMenus, taUser.getOrgId(), null);
            sysMenuMapper.deleteAdminMenus(subMenus, taUser.getOrgId(), null);
        }

        // 先删除授权模块, 再新增
        sysMenuMapper.deleteAdminMenus(menuIds, null, taRole.getRoleId());
        sysMenuMapper.insertAdminMenus(menuIds, taRole.getRoleId());

        // 先删除授权按钮, 再新增
        sysMenuMapper.deleteAdminBtns(menuIds, null, taRole.getRoleId());
        sysMenuMapper.insertAdminBtns(menuIds, taRole.getRoleId());
    }

    private List<Integer> minusMenu(List<SysMenu> origin, List<Integer> menuList) {
        List<Integer> notIn = new ArrayList<>();

        for(SysMenu menu : origin) {
            if (!menuList.contains(menu.getMenuId())) {
                notIn.add(menu.getMenuId());
            }
        }

        return notIn;
    }
}
