package com.gxwebsoft.common.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.system.entity.*;
import com.gxwebsoft.common.system.mapper.MenuMapper;
import com.gxwebsoft.common.system.mapper.RoleMapper;
import com.gxwebsoft.common.system.param.MenuParam;
import com.gxwebsoft.common.system.param.RoleParam;
import com.gxwebsoft.common.system.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * 菜单Service实现
 *
 * @author WebSoft
 * @since 2018-12-24 16:10:10
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    private Integer plugMenuId;
    @Resource
    private RoleService roleService;
    @Resource
    private RoleMenuService roleMenuService;
    @Resource
    private UserService userService;
    @Resource
    private UserRoleService userRoleService;

    @Override
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
    public Boolean cloneMenu(MenuParam param) {
      System.out.println("准备待克隆的菜单数据 = " + param);
      LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
      wrapper.eq(Menu::getDeleted,0);
      if(ObjectUtil.isNotEmpty(param.getMenuId())) {
        wrapper.eq(Menu::getMenuId,param.getMenuId());
      }
      // 删除本项目菜单
      baseMapper.delete(wrapper);
      // 顶级栏目
      param.setParentId(0);
      // 工单系统
      if (param.getTenantId().equals(10125)) {
        // 初始化数据
        initializedData();
      }
      // 开始克隆
      doCloneMenu(baseMapper.getMenuByClone(param));
      return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
    public Boolean install(Integer id) {
      // 1.插件绑定的菜单ID
      final MenuParam param = new MenuParam();
      param.setMenuId(id);
      final List<Menu> list = baseMapper.getMenuByClone(param);
      // TODO 克隆当前插件到顶级菜单
      doCloneMenu(list);

      // 2.查找当前租户的超管权限的roleId
      final Role superAdmin = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "superAdmin"));
      final Integer roleId = superAdmin.getRoleId();
      final Integer tenantId = superAdmin.getTenantId();
      // 3.勾选菜单根权限
      final RoleMenu roleMenu0 = new RoleMenu();
      roleMenu0.setRoleId(roleId);
      roleMenu0.setMenuId(this.plugMenuId);
      roleMenuService.save(roleMenu0);

      // 4.勾选根节点下的子菜单权限
      final MenuParam menuParam = new MenuParam();
      menuParam.setParentId(this.plugMenuId);
      menuParam.setTenantId(tenantId);
      final List<Menu> menuList = baseMapper.getMenuByClone(menuParam);
      menuList.forEach(d->{
        RoleMenu roleMenu = new RoleMenu();
        roleMenu.setRoleId(roleId);
        roleMenu.setMenuId(d.getMenuId());
        roleMenuService.save(roleMenu);
      });
      // 5.调整新插件的排序
      final Menu menu = baseMapper.selectById(this.plugMenuId);
      menu.setSortNumber(100);
      baseMapper.updateById(menu);
      return true;
    }

    // 克隆菜单
    private void doCloneMenu(List<Menu> list) {
      final MenuParam param = new MenuParam();
      list.forEach(d -> {
        Menu menu = new Menu();
        menu.setParentId(0);
        menu.setTitle(d.getTitle());
        menu.setPath(d.getPath());
        menu.setComponent(d.getComponent());
        menu.setMenuType(d.getMenuType());
        menu.setSortNumber(d.getSortNumber());
        menu.setAuthority(d.getAuthority());
        menu.setIcon(d.getIcon());
        menu.setHide(d.getHide());
        menu.setMeta(d.getMeta());
        menu.setModules(d.getModules());
        menu.setModulesUrl(d.getModulesUrl());
        save(menu);
        this.plugMenuId = menu.getMenuId();
        // 二级菜单
        param.setParentId(d.getMenuId());
        final List<Menu> list1 = baseMapper.getMenuByClone(param);
        list1.forEach(d1 -> {
          final Menu menu1 = new Menu();
          menu1.setParentId(menu.getMenuId());
          menu1.setTitle(d1.getTitle());
          menu1.setPath(d1.getPath());
          menu1.setComponent(d1.getComponent());
          menu1.setMenuType(d1.getMenuType());
          menu1.setSortNumber(d1.getSortNumber());
          menu1.setAuthority(d1.getAuthority());
          menu1.setIcon(d1.getIcon());
          menu1.setHide(d1.getHide());
          menu1.setMeta(d1.getMeta());
          menu1.setModules(d1.getModules());
          menu1.setModulesUrl(d1.getModulesUrl());
          save(menu1);
          // 三级菜单
          param.setParentId(d1.getMenuId());
          final List<Menu> list2 = baseMapper.getMenuByClone(param);
          list2.forEach(d2 -> {
            final Menu menu2 = new Menu();
            menu2.setParentId(menu1.getMenuId());
            menu2.setTitle(d2.getTitle());
            menu2.setPath(d2.getPath());
            menu2.setComponent(d2.getComponent());
            menu2.setMenuType(d2.getMenuType());
            menu2.setSortNumber(d2.getSortNumber());
            menu2.setAuthority(d2.getAuthority());
            menu2.setIcon(d2.getIcon());
            menu2.setHide(d2.getHide());
            menu2.setMeta(d2.getMeta());
            menu2.setModules(d2.getModules());
            menu2.setModulesUrl(d2.getModulesUrl());
            save(menu2);
            // 四级菜单
            param.setParentId(d2.getMenuId());
            final List<Menu> list3 = baseMapper.getMenuByClone(param);
            list3.forEach(d3 -> {
              final Menu menu3 = new Menu();
              menu3.setParentId(menu2.getMenuId());
              menu3.setTitle(d3.getTitle());
              menu3.setPath(d3.getPath());
              menu3.setComponent(d3.getComponent());
              menu3.setMenuType(d3.getMenuType());
              menu3.setSortNumber(d3.getSortNumber());
              menu3.setAuthority(d3.getAuthority());
              menu3.setIcon(d3.getIcon());
              menu3.setHide(d3.getHide());
              menu3.setMeta(d3.getMeta());
              menu3.setModules(d3.getModules());
              menu3.setModulesUrl(d3.getModulesUrl());
              save(menu3);
            });
          });
        });
      });
    }

    // 初始化数据
    private void initializedData(){
      Role role = new Role();
      User user = new User();
      UserRole userRole = new UserRole();
      if(roleService.count(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "admin")) == 0){
        role.setRoleCode("admin");
        role.setRoleName("管理人员");
        role.setComments("工单分派管理专员");
        roleService.save(role);
        if(userService.count(new LambdaQueryWrapper<User>().eq(User::getUsername, "管理人员")) == 0){
          user.setUsername("刘备");
          user.setNickname("刘备");
          user.setPhone("13800138001");
          user.setPassword(userService.encodePassword("123456"));
          user.setSex("1");
          userService.save(user);
          // 添加用户角色
          userRole.setRoleId(role.getRoleId());
          userRole.setUserId(user.getUserId());
          userRoleService.save(userRole);
          // 添加统计表

        }
      }
      if(roleService.count(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "commander")) == 0){
        role.setRoleCode("commander");
        role.setRoleName("受理人员");
        role.setComments("负责解决问题的处理人员");
        roleService.save(role);
        if(userService.count(new LambdaQueryWrapper<User>().eq(User::getUsername, "commander")) == 0){
          user.setUsername("关羽");
          user.setNickname("关羽");
          user.setPhone("13800138002");
          user.setPassword(userService.encodePassword("123456"));
          user.setSex("1");
          userService.save(user);
          // 添加用户角色
          userRole.setRoleId(role.getRoleId());
          userRole.setUserId(user.getUserId());
          userRoleService.save(userRole);
        }
      }
      if(roleService.count(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "promoter")) == 0){
        role.setRoleCode("promoter");
        role.setRoleName("工单发起人");
        role.setComments("问题及需求的发起人");
        roleService.save(role);
        if(userService.count(new LambdaQueryWrapper<User>().eq(User::getUsername, "promoter")) == 0){
          user.setUsername("张飞");
          user.setNickname("张飞");
          user.setPassword(userService.encodePassword("123456"));
          user.setSex("1");
          userService.save(user);
          // 添加用户角色
          userRole.setRoleId(role.getRoleId());
          userRole.setUserId(user.getUserId());
          userRoleService.save(userRole);
        }
      }
    }

    @Override
    public List<Menu> getMenuByClone(MenuParam param) {
        return baseMapper.getMenuByClone(param);
    }
}
