package com.cyksj.web.controller.manage.cms;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.manage.cms.CmsMenuMapper;
import com.cyksj.mapper.manage.cms.CmsRoleMenuMapper;
import com.cyksj.model.entity.CmsMenu;
import com.cyksj.model.entity.CmsRoleMenu;
import com.cyksj.model.entity.CmsUser;
import com.cyksj.model.views.CmsMenuVO;
import com.cyksj.service.mange.cms.CmsUserManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/*
 *项目名: netflix
 *文件名: CmsMenuController
 *创建者: JavaZou
 *创建时间:2023/1/11 14:26
 */
@RestController
@RequestMapping("/manage/menu")
@RequiredArgsConstructor
@Slf4j
public class CmsMenuController {
	private final CmsMenuMapper cmsMenuMapper;

	private final CmsUserManager cmsUserManager;

	private final CmsRoleMenuMapper cmsRoleMenuMapper;

	@PostMapping("/post")
	public Result<String> addMenu(@RequestBody @Validated CmsMenu cmsMenu) {
		cmsMenuMapper.insert(cmsMenu);
		return GatewayResponse.SUCCESS.newBuilder().toResult("新增菜单成功");
	}

	@PutMapping("/put")
	public Result<String> putMenu(@RequestBody CmsMenu cmsMenu) throws Exception {
		if (cmsMenu.getId() == null || cmsMenu.getId() < 1) {
			throw BusinessRuntimeException.getInstance("菜单不存在");
		}
		CmsMenu menu = cmsMenuMapper.selectById( cmsMenu.getId());
		BeanUtils.copyProperties(cmsMenu, menu);
		cmsMenuMapper.updateById(menu);
		//更新该菜单关联的权限
		List<CmsUser> cmsUserList = cmsMenuMapper.getAllCmsUserByMenuId(cmsMenu.getId());
		if (null != cmsUserList) {
			for (CmsUser cmsUser : cmsUserList) {
				cmsUserManager.loadUserRedisCache(cmsUser);
			}
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult("编辑菜单成功");
	}

	@DeleteMapping("/delete/{id}")
	public Result<String> deleteMenuById(@PathVariable("id") Long id) throws Exception {
		if (id == null || id < 1) {
			throw BusinessRuntimeException.getInstance("菜单不存在");
		}
		List<CmsUser> cmsUserList = cmsMenuMapper.getAllCmsUserByMenuId(id);
		if (null != cmsUserList) {
			for (CmsUser cmsUser : cmsUserList) {
				cmsUserManager.loadUserRedisCache(cmsUser);
			}
		}
		cmsRoleMenuMapper.delete(Wrappers.lambdaQuery(CmsRoleMenu.class).eq(CmsRoleMenu::getMenuId, id));
		cmsMenuMapper.deleteMenuAndChild(id);
		cmsMenuMapper.delete(Wrappers.lambdaQuery(CmsMenu.class).eq(CmsMenu::getId, id).or().eq(CmsMenu::getParentId, id));
		return GatewayResponse.SUCCESS.newBuilder().toResult("删除菜单成功");
	}

	@GetMapping("/get")
	public Result<List<CmsMenuVO>> getMenuList() {
		Map<Long, List<CmsMenuVO>> idMenusMap = cmsMenuMapper.getALlMenu().stream().collect(Collectors.groupingBy(CmsMenu::getParentId));
		List<CmsMenuVO> list = cmsMenuMapper.getCmsMenusList();
		for (CmsMenuVO cmsMenuVO : list) {
			findChildMenu(cmsMenuVO, idMenusMap);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(list);
	}

	@GetMapping("/get/noPerms")
	public Result<List<CmsMenuVO>> getNoPermsALLMenu() {
		Map<Long, List<CmsMenuVO>> idMenusMap = cmsMenuMapper.getALlMenu().stream().collect(Collectors.groupingBy(CmsMenu::getParentId));
		List<CmsMenuVO> list = cmsMenuMapper.getCmsMenusList();
		for (CmsMenuVO cmsMenuVO : list) {
			findChildMenu(cmsMenuVO, idMenusMap);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(list);
	}

	@GetMapping("/get/self/menu")
	public Result<List<CmsMenuVO>> getSelfMenuList() {
		List<CmsMenuVO> allSelf = cmsMenuMapper.getSelfCmsMenusList(StpUtil.getLoginIdAsLong());
		Map<Long, List<CmsMenuVO>> idMenusMap = allSelf.stream().collect(Collectors.groupingBy(CmsMenu::getParentId));
		List<CmsMenuVO> list = allSelf.stream().filter(vo -> vo.getParentId() == 0).collect(Collectors.toList());
		for (CmsMenuVO cmsMenuVO : list) {
			findChildMenu(cmsMenuVO, idMenusMap);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(list);
	}

	private void findChildMenu(CmsMenuVO cmsMenuVO, Map<Long, List<CmsMenuVO>> idMenusMap) {
		List<CmsMenuVO> list = idMenusMap.get(cmsMenuVO.getId());
		cmsMenuVO.setHasChildren(false);
		if (list != null && list.size() > 0) {
			cmsMenuVO.setChild(list);
			cmsMenuVO.setHasChildren(true);
			list.forEach(child -> findChildMenu(child, idMenusMap));
		}
	}
}
