package cn.qinys.platform.upms.api.service.impl;

import cn.qinys.platform.base.exceptions.BizException;
import cn.qinys.platform.base.utils.RedisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.qinys.platform.entity.upms.UpmsMenuBase;
import cn.qinys.platform.entity.upms.UpmsMenuPermissionBase;
import cn.qinys.platform.upms.api.mapper.UpmsMenuBaseMapper;
import cn.qinys.platform.upms.api.mapper.UpmsMenuPermissionBaseMapper;
import cn.qinys.platform.upms.api.req.MenuCreateReq;
import cn.qinys.platform.upms.api.req.MenuRemoveReq;
import cn.qinys.platform.upms.api.req.MenuUpdateReq;
import cn.qinys.platform.upms.api.resp.MenuPageResp;
import cn.qinys.platform.upms.api.service.IMenuService;
import cn.qinys.platform.upms.constants.UpmsConstants;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Description:
 *
 * @author tanlie
 * Date: 2024/2/6 15:20
 */
@Service
@AllArgsConstructor
public class MenuServiceImpl extends MenuBaseService implements IMenuService {

    private final UpmsMenuBaseMapper menuBaseMapper;
    private final RedisUtils redisUtils;
    private final UpmsMenuPermissionBaseMapper permissionBaseMapper;



    @Override
    public List<MenuPageResp> getMenuPage() {
        QueryWrapper<UpmsMenuBase> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("ord", "id");
        List<UpmsMenuBase> menuList = menuBaseMapper.selectList(wrapper);
        return this.getPageTree(menuList);
    }

    @Override
    public void refreshMenu() {
        // 删除角色缓存
        String prefix = UpmsConstants.RedisKey.UPMS_AUTH_MENUS.getCode() + "*";
        redisUtils.deleteByPrefix(prefix);
    }

    @Transactional
    @Override
    public void createMenu(MenuCreateReq req) {
        UpmsMenuBase menu = new UpmsMenuBase();
        BeanUtils.copyProperties(req, menu);
        if (menu.getParentId() > 0) {
            UpmsMenuBase parent = menuBaseMapper.selectById(menu.getParentId());
            menu.setLevel(parent.getLevel() + 1);
        }
        menuBaseMapper.insert(menu);
        if (req.getPermissions() != null && !req.getPermissions().isEmpty()) {
            for (UpmsMenuPermissionBase item : req.getPermissions()) {
                UpmsMenuPermissionBase permission = new UpmsMenuPermissionBase();
                permission.setMenuId(menu.getId());
                permission.setPermissionName(item.getPermissionName());
                permission.setPermissionCode(item.getPermissionCode());
                permissionBaseMapper.insert(permission);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeMenu(MenuRemoveReq req) {
        QueryWrapper<UpmsMenuBase> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", req.getId());
        wrapper.last("LIMIT 1");
        UpmsMenuBase child = menuBaseMapper.selectOne(wrapper);
        if (child != null) {
            throw new BizException("该菜单还有子菜单，请先删除子菜单");
        }
        menuBaseMapper.deleteById(req.getId());
        permissionBaseMapper.deleteByMenuId(req.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateMenu(MenuUpdateReq req) {
        UpmsMenuBase menu = menuBaseMapper.selectById(req.getId());
        BeanUtils.copyProperties(req, menu);
        if (menu.getParentId() > 0) {
            UpmsMenuBase parent = menuBaseMapper.selectById(menu.getParentId());
            menu.setLevel(parent.getLevel() + 1);
        }
        menuBaseMapper.updateById(menu);
        if (req.getPermissions() == null || req.getPermissions().isEmpty()) {
            permissionBaseMapper.deleteByMenuId(menu.getId());
            return;
        }
        //没被删除的
        List<Integer> remainIds = new ArrayList<>();
        req.getPermissions().forEach(item -> {
            if (item.getId() != null) {
                remainIds.add(item.getId());
            }
        });
        // delete from not in remainIds
        if (remainIds.size() > 0) {
            QueryWrapper<UpmsMenuPermissionBase> wrapper = new QueryWrapper<>();
            wrapper.eq("menu_id", req.getId());
            wrapper.notIn("id", remainIds);
            permissionBaseMapper.delete(wrapper);
        }

        for (UpmsMenuPermissionBase item : req.getPermissions()) {
            if (item.getId() != null) {
                UpmsMenuPermissionBase permission = permissionBaseMapper.selectById(item.getId());
                permission.setPermissionName(item.getPermissionName());
                permission.setPermissionCode(item.getPermissionCode());
                permissionBaseMapper.updateById(permission);
            } else {
                UpmsMenuPermissionBase permission = new UpmsMenuPermissionBase();
                permission.setMenuId(menu.getId());
                permission.setPermissionName(item.getPermissionName());
                permission.setPermissionCode(item.getPermissionCode());
                permissionBaseMapper.insert(permission);
            }
        }
    }
}
