package com.xy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.collections.list.JArrayList;
import com.xy.collections.list.JList;
import com.xy.consts.CommConsts;
import com.xy.dto.SysMenuDto;
import com.xy.entity.SysMenu;
import com.xy.entity.SysMenuJoinSysRoleMenu;
import com.xy.entity.SysRole;
import com.xy.entity.SysRoleMenu;
import com.xy.mapper.SysMenuMapper;
import com.xy.mapper.SysRoleMapper;
import com.xy.mapper.SysRoleMenuMapper;
import com.xy.redis.RedisCache;
import com.xy.service.SysMenuService;
import com.xy.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

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

import static com.xy.utils.Beans.copy;
import static com.xy.utils.Beans.tree;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author lijin
 * @since 2022-12-09
 */
@Service
@AllArgsConstructor
@Api(tags = "菜单接口")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    private SysRoleMenuMapper sysRoleMenuMapper;

    private SysRoleMapper sysRoleMapper;

    @PostMapping("workMenu")
    @ApiOperation("用户菜单树")
    public R<List<SysMenuDto.Vo>> workMenu(@RequestBody @Validated SysMenuDto.WorkMenu workMenu) {
        List<SysMenuDto.Vo> list = new ArrayList<>();
        List<SysMenuJoinSysRoleMenu> menus = RedisCache.getMenuTree(workMenu.getSystemId());
        menus.forEach(sysMenuJoinSysRoleMenu -> {
            SysMenuDto.Vo vo = copy(SysMenuDto.Vo.class, sysMenuJoinSysRoleMenu);
            List<SysMenuDto.Vo> sonVos = copy(SysMenuDto.Vo.class, sysMenuJoinSysRoleMenu.getSonSysMenu());
            list.add(vo.setSonSysMenu(sonVos));
        });
        return R.ok(list);
    }

    @PostMapping("workMenuList")
    @ApiOperation("用户菜单集合")
    public R<List<SysMenuDto.Vo>> workMenuList(@RequestBody @Validated SysMenuDto.WorkMenu workMenu) {
        List<SysMenuDto.Vo> list = new ArrayList<>();
        List<SysMenuJoinSysRoleMenu> menus = RedisCache.getMenu(workMenu.getSystemId());
        menus.forEach(sysMenuJoinSysRoleMenu -> list.add(copy(SysMenuDto.Vo.class, sysMenuJoinSysRoleMenu)));
        return R.ok(list);
    }

    @PostMapping("menu")
    @ApiOperation("全部菜单树")
    public R<List<SysMenuDto.Vo>> menu(@RequestBody @Validated SysMenuDto.WorkMenu workMenu) {
        List<SysMenuDto.Vo> vos = copy(SysMenuDto.Vo.class, list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getSysId, workMenu.getSystemId())));
        JList<SysMenuDto.Vo> list = new JArrayList<>(vos).filter().isNull(SysMenuDto.Vo::getPaterId).list();
        for (SysMenuDto.Vo vo : list) {
            List<SysMenuDto.Vo> tree = tree(vo, vos, SysMenuDto.Vo::getId, SysMenuDto.Vo::getPaterId, SysMenuDto.Vo::getSonSysMenu);
            vo.setSonSysMenu(tree);
        }
        return R.ok(list);
    }

    @PostMapping("save")
    @ApiOperation("添加菜单")
    public R save(@RequestBody @Validated SysMenuDto.Save save) {
        //校验重复
        long count = count(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getCode, save.getCode())
                .eq(SysMenu::getSysId, save.getSysId())
        );
        if (count > 0) {
            return R.fail("标识已存在");
        }
        //添加菜单
        SysMenu sysMenu = copy(SysMenu.class, save)
                .create(RedisCache.getLoginId(Long.class));
        save(sysMenu);
        //赋予管理员角色菜单
        SysRole sysRole = sysRoleMapper.selectOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getSysId, save.getSysId()).eq(SysRole::getCode, CommConsts.ADMIN_ROLE_CODE));
        SysRoleMenu sysRoleMenu = new SysRoleMenu()
                .createId()
                .setMenuId(sysMenu.getId())
                .setRoleId(sysRole.getId())
                .setSelectIsAdmin(true);
        sysRoleMenuMapper.insert(sysRoleMenu);
        return R.ok();
    }

    @PostMapping("update")
    @ApiOperation("修改菜单")
    public R update(@RequestBody @Validated SysMenuDto.Update update) {
        SysMenu sysMenu = copy(SysMenu.class, update)
                .update(RedisCache.getLoginId(Long.class));
        updateById(sysMenu);
        return R.ok();
    }

    @PostMapping("del")
    @ApiOperation("删除菜单")
    public R del(@RequestBody @Validated SysMenuDto.Del del) {
        //删除角色菜单
        sysRoleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getMenuId, del.getId()));
        //删除菜单
        removeBatchByIds(del.getId());
        return R.ok();
    }
}
