package com.sptg.permissions.biz.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.util.CommonUtil;
import com.sptg.permissions.api.dto.RoleDto;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.RoleMenu;
import com.sptg.permissions.biz.mapper.RoleMenuMapper;
import com.sptg.permissions.biz.service.RoleMenuServiceInterface;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * title: RoleMenuServiceImpl
 * package: com.sptg.permissions.biz.security.impl
 * description: 角色菜单关联-服务层实现类
 *
 *                  
 *                
 */
@Setter
@Service
@RequiredArgsConstructor
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuServiceInterface {

    @Override
    public List<RoleMenu> selectListByRoleId(Serializable roleId) {
        Wrapper<RoleMenu> wrapper = new EntityWrapper<>();
        wrapper.eq("l_role_id",roleId);
        return this.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean insert(RoleMenu entity) {
        entity.setCreateDate(new Date());
        return super.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void insertBatch(RoleDto dto) {
        List<Long> menuIdList = CommonUtil.stringToLongList(dto.getMenuIds());
        if (menuIdList.size() == 0){
            return;
        }
        List<RoleMenu> list = new ArrayList<>(menuIdList.size());
        menuIdList.forEach((menuId) -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(dto.getId());
            roleMenu.setMenuId(menuId);
            roleMenu.setCreateAccountId(dto.getCreateAccountId());
            roleMenu.setCreateDate(dto.getCreateDate());
            list.add(roleMenu);
        });
        this.insertBatch(list);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateRoleMenu(RoleDto dto) {
        List<Long> menuIdList = CommonUtil.stringToLongList(dto.getMenuIds());
        if (menuIdList.size() == 0){
            //  删除此角色的所有关联数据
            Wrapper<RoleMenu> wrapper = new EntityWrapper<>();
            wrapper.eq("l_role_id",dto.getId());
            this.delete(wrapper);
            return;
        }
        //  获取角色与菜单的关联列表
        List<RoleMenu> roleMenuList = this.selectListByRoleId(dto.getId());
        //  需要新增的关联列表
        List<RoleMenu> addList = new ArrayList<>();
        //  筛选出需要新增的数据与需要删除的数据
        Date nowTime = new Date();
        Account onLineUser = dto.getOnLineUser();
        skip:
        for (int i = 0; i < menuIdList.size(); i++){
            Long menuId = menuIdList.get(i);
            for (int j = 0; j < roleMenuList.size(); j++){
                RoleMenu roleMenu = roleMenuList.get(j);
                //  过滤已经拥有
                if (roleMenu.getMenuId().equals(menuId)){
                    menuIdList.remove(i);
                    roleMenuList.remove(j);
                    --i;
                    continue skip;
                }
            }
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(dto.getId());
            roleMenu.setMenuId(menuId);
            roleMenu.setCreateAccountId(onLineUser.getId());
            roleMenu.setCreateDate(nowTime);
            addList.add(roleMenu);
        }
        //  删除多余的关联
        if (roleMenuList.size() > OperationConstant.ZERO){
            List<Long> deleteList = new ArrayList<>(roleMenuList.size());
            roleMenuList.forEach(entity -> deleteList.add(entity.getId()));
            this.deleteBatchIds(deleteList);
        }
        //  新增关联
        if (addList.size() > OperationConstant.ZERO) {
            this.insertBatch(addList);
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void deleteByRoleId(Long roleId) {
        Wrapper<RoleMenu> wrapper = new EntityWrapper<>();
        wrapper.eq("l_role_id",roleId);
        this.delete(wrapper);
    }
}
