package com.qmth.paper.library.api;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.paper.library.business.bean.params.TSchoolPrivilegeParam;
import com.qmth.paper.library.business.bean.result.CustomPrivilegeResult;
import com.qmth.paper.library.business.bean.result.TSchoolPrivilegeResult;
import com.qmth.paper.library.common.base.BaseEntity;
import com.qmth.paper.library.common.bean.dto.PrivilegeDto;
import com.qmth.paper.library.common.contant.ApiPrefixConstant;
import com.qmth.paper.library.common.entity.*;
import com.qmth.paper.library.common.service.*;
import com.qmth.paper.library.common.util.Result;
import com.qmth.paper.library.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.util.CollectionUtils;
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;

/**
 * 菜单权限修改
 */
@Api(tags = "菜单权限修改Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + ApiPrefixConstant.PREFIX_MENU)
public class MenuCustomController {

    @Resource
    SysPrivilegeService sysPrivilegeService;

    @Resource
    TSchoolPrivilegeService tSchoolPrivilegeService;

    @Resource
    SysRolePrivilegeService sysRolePrivilegeService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SysUserService sysUserService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    LibraryCommonService commonService;

    @ApiOperation(value = "查询自定义菜单权限")
    @ApiResponses({@ApiResponse(code = 200, message = "菜单权限信息", response = SysPrivilege.class)})
    @RequestMapping(value = "/custom/list", method = RequestMethod.POST)
    public Result customList() {
        List<PrivilegeDto> customPrivilegeList = sysPrivilegeService.commonCustomList();
        return ResultUtil.ok(new CustomPrivilegeResult(customPrivilegeList));
    }

    @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 (!CollectionUtils.isEmpty(tSchoolPrivileges)) {//编辑
            Set<Long> changePrivilegeSetIds = tSchoolPrivileges.stream().filter(s -> !Arrays.asList(tSchoolPrivilegeParam.getPrivilegeIds()).contains(s.getPrivilegeId()))
                    .collect(Collectors.toList())
                    .stream().map(TSchoolPrivilege::getPrivilegeId)
                    .collect(Collectors.toSet());
            //数据发生改变
            if (!CollectionUtils.isEmpty(changePrivilegeSetIds)) {
                //查询该菜单下所有角色，删除该角色所发生改变的菜单数据
                QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
                sysRoleQueryWrapper.lambda().eq(SysRole::getSchoolId, tSchoolPrivilegeParam.getSchoolId());
                List<SysRole> sysRoleList = sysRoleService.list(sysRoleQueryWrapper);

                if (!CollectionUtils.isEmpty(sysRoleList)) {
                    QueryWrapper<SysRolePrivilege> sysRolePrivilegeQueryWrapper = new QueryWrapper<>();
                    sysRolePrivilegeQueryWrapper.lambda()
                            .in(SysRolePrivilege::getRoleId, sysRoleList.stream().map(BaseEntity::getId).collect(Collectors.toList()))
                            .in(SysRolePrivilege::getPrivilegeId, changePrivilegeSetIds);
                    List<SysRolePrivilege> sysRolePrivilegeList = sysRolePrivilegeService.list(sysRolePrivilegeQueryWrapper);
                    //仅删除绑定了该权限的角色用户缓存
                    roleSetIds = sysRolePrivilegeList.stream().map(SysRolePrivilege::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 (Long privilegeId : privilegeIds) {
                tSchoolPrivilegeList.add(new TSchoolPrivilege(tSchoolPrivilegeParam.getSchoolId(), privilegeId));
            }
            tSchoolPrivilegeService.saveBatch(tSchoolPrivilegeList);
        }

        //清缓存
        if (!CollectionUtils.isEmpty(roleSetIds)) {
            for (Long l : roleSetIds) {
                //绑定该角色的用户都需要清除鉴权缓存
                List<SysUserRole> sysUserRoleList = sysUserRoleService.listByRoleId(l);
                for (SysUserRole s : sysUserRoleList) {
                    SysUser user = sysUserService.getById(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);
        List<String> privilegeIdList = tSchoolPrivilegeList.stream().map(s -> String.valueOf(s.getPrivilegeId())).collect(Collectors.toList());
        return ResultUtil.ok(new TSchoolPrivilegeResult(schoolId, privilegeIdList));
    }
}
