package com.qmth.distributed.print.api;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.distributed.print.business.bean.params.TSchoolPrivilegeParam;
import com.qmth.teachcloud.common.bean.dto.PrivilegeDto;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.*;
import com.qmth.teachcloud.common.enums.PrivilegeEnum;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 菜单权限修改
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/10/29
 */
@Api(tags = "菜单权限修改Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.menu}")
//@Aac(auth = BOOL.FALSE, strict = BOOL.FALSE)
public class MenuCustomController {

    @Resource
    SysPrivilegeService sysPrivilegeService;

    @Resource
    TSchoolPrivilegeService tSchoolPrivilegeService;

    @Resource
    SysRolePrivilegeService sysRolePrivilegeService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    TeachcloudCommonService commonService;

    @ApiOperation(value = "查询自定义菜单权限")
    @ApiResponses({@ApiResponse(code = 200, message = "菜单权限信息", response = SysPrivilege.class)})
    @RequestMapping(value = "/custom/list", method = RequestMethod.POST)
    public Result rolePrivilegeCountSync() {
        QueryWrapper<SysPrivilege> sysPrivilegeQueryWrapper = new QueryWrapper<>();
        sysPrivilegeQueryWrapper.lambda()
                .eq(SysPrivilege::getEnable, true)
                .eq(SysPrivilege::getDefaultAuth, false)
                .ne(SysPrivilege::getType, PrivilegeEnum.URL)
                .notIn(SysPrivilege::getId, SystemConstant.MENU_MANAGE);
        List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.list(sysPrivilegeQueryWrapper);
        List<PrivilegeDto> privilegeDtoList = null;
        if (Objects.nonNull(sysPrivilegeList) && sysPrivilegeList.size() > 0) {
            Set<Long> privilegeIds = new HashSet<>();
            Map<Long, SysPrivilege> sysPrivilegeMap = new HashMap<>();
            for (SysPrivilege s : sysPrivilegeList) {
                if (!Objects.equals(s.getType(), PrivilegeEnum.MENU)) {
                    privilegeIds.add(s.getId());
                }
                sysPrivilegeMap.put(s.getId(), s);
            }
            for (Long l : privilegeIds) {
                List<SysPrivilege> sysPrivileges = sysPrivilegeService.findByConnectByParentId(l);
                for (SysPrivilege s : sysPrivileges) {
                    sysPrivilegeMap.put(s.getId(), s);
                }
            }
            privilegeDtoList = (List<PrivilegeDto>) sysPrivilegeService.getMenuTreeCommon(sysPrivilegeMap.values());
        }
        return ResultUtil.ok(privilegeDtoList);
    }

    @ApiOperation(value = "学校新增/修改自定义菜单权限")
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = ResultUtil.class)})
    @RequestMapping(value = "/custom/save", method = RequestMethod.POST)
    @Transactional
    public Result getRolePrivileges(@Valid @RequestBody TSchoolPrivilegeParam tSchoolPrivilegeParam, BindingResult bindingResult) throws NoSuchAlgorithmException {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        Set<Long> roleSetIds = null;
        QueryWrapper<TSchoolPrivilege> tSchoolPrivilegeQueryWrapper = new QueryWrapper<>();
        tSchoolPrivilegeQueryWrapper.lambda().eq(TSchoolPrivilege::getSchoolId, tSchoolPrivilegeParam.getSchoolId());
        List<TSchoolPrivilege> tSchoolPrivileges = tSchoolPrivilegeService.list(tSchoolPrivilegeQueryWrapper);
        if (Objects.nonNull(tSchoolPrivileges) && tSchoolPrivileges.size() > 0) {//编辑
            Set<Long> changePrivilegeSetIds = tSchoolPrivileges.stream().filter(s -> !Arrays.asList(tSchoolPrivilegeParam.getPrivilegeIds()).contains(s.getPrivilegeId()))
                    .collect(Collectors.toList())
                    .stream().map(s -> s.getPrivilegeId())
                    .collect(Collectors.toSet());
            //数据发生改变
            if (changePrivilegeSetIds.size() > 0) {
                List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.listByIds(changePrivilegeSetIds);
                sysPrivilegeList = sysPrivilegeList.stream().filter(s -> !Objects.equals(s.getType(), PrivilegeEnum.MENU)).collect(Collectors.toList());
                changePrivilegeSetIds = sysPrivilegeList.stream().map(s -> s.getId()).collect(Collectors.toSet());

                if (changePrivilegeSetIds.size() > 0) {
                    //查询该菜单下所有角色，删除该角色所发生改变的菜单数据
                    QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
                    sysRoleQueryWrapper.lambda().eq(SysRole::getSchoolId, tSchoolPrivilegeParam.getSchoolId());
                    List<SysRole> sysRoleList = sysRoleService.list(sysRoleQueryWrapper);

                    if (Objects.nonNull(sysRoleList) && sysRoleList.size() > 0) {
                        QueryWrapper<SysRolePrivilege> sysRolePrivilegeQueryWrapper = new QueryWrapper<>();
                        sysRolePrivilegeQueryWrapper.lambda()
                                .in(SysRolePrivilege::getRoleId, sysRoleList.stream().map(s -> s.getId()).collect(Collectors.toList()))
                                .in(SysRolePrivilege::getPrivilegeId, changePrivilegeSetIds);
                        List<SysRolePrivilege> sysRolePrivilegeList = sysRolePrivilegeService.list(sysRolePrivilegeQueryWrapper);
                        //仅删除绑定了该权限的角色用户缓存
                        roleSetIds = sysRolePrivilegeList.stream().map(s -> s.getRoleId()).collect(Collectors.toSet());
                        sysRolePrivilegeService.remove(sysRolePrivilegeQueryWrapper);
                    }
                }
            }
            tSchoolPrivilegeService.remove(tSchoolPrivilegeQueryWrapper);
        }
        Long[] privilegeIds = tSchoolPrivilegeParam.getPrivilegeIds();
        if (Objects.nonNull(privilegeIds) && privilegeIds.length > 0) {
            List<TSchoolPrivilege> tSchoolPrivilegeList = new ArrayList<>();
            for (int i = 0; i < privilegeIds.length; i++) {
                tSchoolPrivilegeList.add(new TSchoolPrivilege(tSchoolPrivilegeParam.getSchoolId(), privilegeIds[i]));
            }
            tSchoolPrivilegeService.saveBatch(tSchoolPrivilegeList);
        }

        //清缓存
        if (Objects.nonNull(roleSetIds) && roleSetIds.size() > 0) {
            for (Long l : roleSetIds) {
                commonCacheService.updateRoleCache(l);
                commonCacheService.updateRolePrivilegeCache(l);
                //绑定该角色的用户都需要清除鉴权缓存
                List<SysUserRole> sysUserRoleList = sysUserRoleService.listByRoleId(l);
                for (SysUserRole s : sysUserRoleList) {
                    SysUser user = commonCacheService.userCache(s.getUserId());
                    if (Objects.nonNull(user)) {
                        commonService.removeUserInfo(s.getUserId(), true);
                    } else {
                        sysUserRoleService.removeById(s);
                    }
                }
            }
        }
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "学校已绑定自定义菜单权限列表")
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = ResultUtil.class)})
    @RequestMapping(value = "/custom/get_school_custom_privileges", method = RequestMethod.POST)
    public Result getRolePrivileges(@RequestParam(value = "schoolId", required = true) Long schoolId) {
        List<TSchoolPrivilege> tSchoolPrivilegeList = tSchoolPrivilegeService.findBySchoolId(schoolId);
        return ResultUtil.ok(tSchoolPrivilegeList.stream().map(s -> String.valueOf(s.getPrivilegeId())).collect(Collectors.toList()));
    }
}
