package cn.com.countrygarden.bi.main.service.impl;

import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.core.Result;
import cn.com.countrygarden.bi.main.dao.sys.MenuMapper;
import cn.com.countrygarden.bi.main.dao.sys.RoleMapper;
import cn.com.countrygarden.bi.main.dao.sys.RoleMenusMapper;
import cn.com.countrygarden.bi.main.dto.TreeDataDTO;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.AccessToken;
import cn.com.countrygarden.bi.main.model.sys.Menu;
import cn.com.countrygarden.bi.main.model.sys.RoleMenus;
import cn.com.countrygarden.bi.main.service.MenuService;
import org.apache.commons.collections4.MultiMapUtils;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Condition;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

@Service
@Transactional
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenusMapper roleMenusMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Override
    public List<Menu> findByUserCode(String userCode) {
        List<Menu> result = new ArrayList<Menu>();
        List<Menu> menuList = menuMapper.findByUserCode(userCode);
        MultiValuedMap<String,Menu> menuMap = new ArrayListValuedHashMap<String,Menu>();
        for(Menu menu: menuList){
            if(StringUtils.isEmpty(menu.getParentCode())){
                result.add(menu);
            } else {
                menuMap.put(menu.getParentCode(),menu);
            }
        }
        fillSubMenus(result, menuMap);
        return result;
    }


    public List<Menu> fillSubMenus(List<Menu> menus, MultiValuedMap<String,Menu> menuMap){
        for(Menu menu:menus){
            List<Menu> subMenus = getSubMenus(menu, menuMap);
            if(subMenus!=null && subMenus.size()>0){
                fillSubMenus(subMenus, menuMap);
            } else {
                subMenus = new ArrayList<Menu>();
            }
            menu.setSubMenus(subMenus);
        }

        return menus;
    }

    public List<Menu> getSubMenus(Menu menu, MultiValuedMap<String,Menu> menuMap){
        List<Menu> subMenus =MultiMapUtils.getValuesAsList(menuMap,menu.getCode());
        return subMenus;
    }


    @Override
    public Result queryMenuTreeData(String roleCode) {
        List<Menu> result = new ArrayList<Menu>();
        List<Menu> menus = menuMapper.selectAllMenus();
        MultiValuedMap<String,Menu> menuMap = new ArrayListValuedHashMap<String,Menu>();
        for(Menu menu: menus){
            if(StringUtils.isEmpty(menu.getParentCode())){
                result.add(menu);
            } else {
                menuMap.put(menu.getParentCode(),menu);
            }
        }
        fillSubMenus(result, menuMap);
        List<String> existRoleCodeList=new ArrayList<>();
        //新增情况
        if(StringUtils.isNotEmpty(roleCode)){
            existRoleCodeList = roleMenusMapper.selectExistMenuCodeByRoleCode(roleCode);
        }
        return Response.response(new TreeDataDTO(result,existRoleCodeList));
    }

    @Override
    public Result queryMenuTreeDataByRole(String roleCode,String userCode) {
    	List<Menu> result = new ArrayList<Menu>();
    	List<Menu> menus;
    	MultiValuedMap<String,Menu> menuMap = new ArrayListValuedHashMap<String,Menu>();
    	Integer isAdmin = roleMapper.checkIsAdmin(userCode);
    	if(isAdmin>0) {
    		menus = menuMapper.selectTreeMenuByRole(null);
    	}else {
    		menus = menuMapper.selectTreeMenuByRole(userCode);
    	}
        for(Menu menu: menus){
            if(StringUtils.isEmpty(menu.getParentCode())){
                result.add(menu);
            } else {
                menuMap.put(menu.getParentCode(),menu);
            }
        }
        fillSubMenus(result, menuMap);
        List<String> existRoleCodeList=new ArrayList<>();
        //新增情况
        if(StringUtils.isNotEmpty(roleCode)){
            existRoleCodeList = roleMenusMapper.selectExistMenuCodeByRoleCode(roleCode);
        }
        return Response.response(new TreeDataDTO(result,existRoleCodeList));
    }
    
    @Override
    public Result editRolesMenus(String roleCode, String menuCodes, String userCode) {
        List<RoleMenus> roleMenusList=new LinkedList<>();
        String[] menusCodeAry = menuCodes.split(",");
//      清除历史角色菜单授权
        roleMenusMapper.deleteByRoleCodes(roleCode);
//      授权角色菜单
        for (String menusCode : menusCodeAry) {
                RoleMenus roleMenus=new RoleMenus();
                roleMenus.setRoleCode(roleCode);
                roleMenus.setMenuCode(menusCode);
                roleMenus.setCreatedBy(userCode);
                roleMenus.setCreatedDate(new Date());
                roleMenusList.add(roleMenus);
        }
        int i = roleMenusMapper.insertList(roleMenusList);
        if(i!=roleMenusList.size()){
            throw new ServiceException("授权菜单异常！");
        }
        return Response.response();
    }

    @Override
    public Result queryById(Integer id) {
        return Response.response(menuMapper.selectByPrimaryKey(id));
    }

    @Override
    public Result add(Menu menu, AccessToken accessToken) {
        Condition condition = new Condition(Menu.class);
        condition.createCriteria().andEqualTo("code", menu.getCode());
        int count = menuMapper.selectCountByCondition(condition);
        if(count>0){
            throw new ServiceException("系统异常，菜单编码已存在！");
        }
        menu.setEnable(true);
        menu.setUpdatedBy(accessToken.getUserCode());
        menu.setUpdatedDate(new Date());
        menuMapper.insert(menu);
        return Response.response();
    }

    @Override
    public Result edit(Menu menu, AccessToken accessToken) {
        menu.setUpdatedBy(accessToken.getUserCode());
        menu.setUpdatedDate(new Date());
        menuMapper.updateByPrimaryKey(menu);
        return Response.response();
    }

    @Override
    public Result del(Integer id) {
//      关联授权数据不做任何处理，在用户重新授权时，该脏数据会自动处理

//      判断是否存在子节点
        int count=menuMapper.checkExistChildNodes(id);
        if(count>0){
            throw new ServiceException("系统异常，该节点下存在子节点!");
        }
        menuMapper.deleteByPrimaryKey(id);
        return Response.response();
    }

    @Override
    public Result queryDataById(Integer id) {
        return Response.response(menuMapper.queryDataById(id));
    }


}
