package cn.com.ty.lift.system.user.service.impl;

import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.ty.lift.common.utils.TreeUtil;
import cn.com.ty.lift.system.user.dao.entity.CompanyMenu;
import cn.com.ty.lift.system.user.dao.entity.Menu;
import cn.com.ty.lift.system.user.dao.entity.RoleMenu;
import cn.com.ty.lift.system.user.dao.entity.model.MenuRequest;
import cn.com.ty.lift.system.user.dao.mapper.MenuMapper;
import cn.com.ty.lift.system.user.service.ICompanyMenuService;
import cn.com.ty.lift.system.user.service.IMenuService;
import cn.com.ty.lift.system.user.service.IRoleMenuService;
import cn.com.xwy.boot.web.dto.RestResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

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

/**
 * @author huangyuan
 * @date 2019-12-01
 * @description 菜单接口实现类
 */
@Service
public class MenuService extends ServiceImpl<MenuMapper, Menu> implements IMenuService {


    @Resource
    private ICompanyMenuService companyMenuService;

    @Resource
    private IRoleMenuService roleMenuService;

    @Override
    public List<Menu> getByRoleId(Long roleId) {
        List<RoleMenu> roleMenuList = roleMenuService.list(new QueryWrapper<RoleMenu>()
                .eq("role_id", roleId)
        );
        List<Long> menuIdList = ProjectUtils.getAttrList(roleMenuList, "menuId", null);
        if(menuIdList != null && menuIdList.size() > 0){
            return (List<Menu>) this.listByIds(menuIdList);
        }
        return null;
    }

    @Override
    public String menuToUrl(List<Menu> menuList) {
        //将菜单转化为菜单树
        List<Menu> menuTree = TreeUtil.listToTree(menuList, ApiConstants.MENU_PARENT_ATTR, ApiConstants.ROOT_MENU_PARENT_ID, "id");
        //递归组合菜单路径
        StringBuilder sb = new StringBuilder();
        menuTreeToUrl(menuTree,  sb);
        return sb.toString().replace("\n","");
    }

    @Override
    public RestResponse all(MenuRequest menuRequest) {
        List<Menu> allMenus = this.list();
        if (menuRequest.getCompanyId() != null) {
            //如果公司id不为空，获取当前公司已有的菜单信息
            List<Menu> companyMenus = this.getCompanyMenuList(menuRequest.getCompanyId());
            //在全部订单中设置选中
            setMenuChecked(allMenus, companyMenus);
        }

        return RestResponse.success(getMenuTree(allMenus), ApiConstants.RESULT_SUCCESS, "获取所有菜单信息");
    }

    @Override
    public RestResponse list(MenuRequest menuRequest) {
        List<Menu> menuList = this.getCompanyMenuList(menuRequest.getCompanyId());
        if (menuRequest.getRoleId() != null) {
            //如果传递了角色，获取角色下的所有菜单
            List<Menu> roleMenuList = getByRoleId(menuRequest.getRoleId());
            //设置角色有的菜单为选中
            setMenuChecked(menuList, roleMenuList);
        }
        return RestResponse.success(getMenuTree(menuList), ApiConstants.RESULT_SUCCESS, "获取企业所有菜单信息");
    }

    @Override
    public List<Menu> getCompanyMenuList(Long companyId) {
        List<CompanyMenu> companyMenuList = companyMenuService.list(new QueryWrapper<CompanyMenu>()
                .eq("company_id", companyId)
        );
        List<Long> menuIdList = ProjectUtils.getAttrList(companyMenuList, "menuId", null);
        if(menuIdList !=  null && menuIdList.size() > 0){
            return (List<Menu>) this.listByIds(menuIdList);
        }
        return null;
    }

    @Override
    @Transactional
    public RestResponse companyMenu(MenuRequest menuRequest) {
        Long companyId = menuRequest.getCompanyId();
        //删除企业原来关联的菜单
        List<CompanyMenu> needDeleteCompanyMenuList = companyMenuService.list(new QueryWrapper<CompanyMenu>()
                .eq("company_id", companyId)
        );
        List<Long> companyMenuIds = ProjectUtils.getAttrList(needDeleteCompanyMenuList, "id", null);
        if (companyMenuIds.size() > 0) {
            if(!companyMenuService.removeByIds(companyMenuIds)){
               return RestResponse.fail(ApiConstants.RESULT_ERROR, "删除公司菜单关联关系失败");
            }
        }
        //获取菜单id列表
        List<Long> menuIdList = ProjectUtils.getLongIdFromIds(menuRequest.getMenuIds());
        List<CompanyMenu> needSaveCompanyMenuList = new ArrayList<>();
        if (menuIdList.size() > 0) {
            for (Long menuId : menuIdList) {
                CompanyMenu companyMenu = new CompanyMenu();
                companyMenu.setCompanyId(companyId);
                companyMenu.setMenuId(menuId);
                needSaveCompanyMenuList.add(companyMenu);
            }
        }
        //保存公司菜单关联关系
        if (needSaveCompanyMenuList.size() > 0) {
            if(!companyMenuService.saveBatch(needSaveCompanyMenuList)){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return RestResponse.fail(ApiConstants.RESULT_ERROR, "保存公司菜单关系失败");
            }
        }
        return null;
    }

    @Override
    public List<Menu> getMenuTree(List<Menu> menuList) {
        return TreeUtil.listToTree(menuList, ApiConstants.MENU_PARENT_ATTR, ApiConstants.ROOT_MENU_PARENT_ID, "id");
    }

    /**
     * @param menuTree 菜单树，
     * @return
     * @description 菜单树转化为路径字符串
     * @date 2019/11/27 10:03 AM
     */
    private void menuTreeToUrl(List<Menu> menuTree, StringBuilder sb) {
        if (menuTree != null && menuTree.size() > 0) {
            for (Menu menu : menuTree) {
                if (StringUtils.isNotBlank(menu.getUrl())) {
                    sb.append(menu.getUrl()).append(",");
                }
                menuTreeToUrl(menu.getChildren(), sb);
            }
        }
    }

    /**
     * @param moreMenuList 大的菜单列表
     * @param lessMenuList 小的菜单列表
     * @return
     * @description 设置菜单选中
     * @date 2019-12-20 16:33
     */
    private void setMenuChecked(List<Menu> moreMenuList, List<Menu> lessMenuList) {
        if ((moreMenuList != null && moreMenuList.size() > 0)
                && (lessMenuList != null && lessMenuList.size() > 0)) {
            for (Menu moreMenu : moreMenuList) {
                for (Menu lessMenu : lessMenuList) {
                    if (moreMenu.getId().equals(lessMenu.getId())) {
                        //设置菜单信息为选中
                        moreMenu.setChecked(true);
                    }
                }
            }
        }
    }
}
