/**
 * Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.xiaoniu.subsystem.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.xiaoniu.common.core.exception.ServiceException;
import com.xiaoniu.common.core.result.R;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.web.domain.AjaxResult;
import com.xiaoniu.common.log.annotation.Log;
import com.xiaoniu.common.log.enums.BusinessType;
import com.xiaoniu.common.security.annotation.RequiresPermissions;
import com.xiaoniu.common.security.utils.SecurityUtils;
import com.xiaoniu.subsystem.system.domain.SysRole;
import com.xiaoniu.subsystem.system.domain.SysUser;
import com.xiaoniu.subsystem.system.domain.SysUserRole;
import com.xiaoniu.subsystem.system.domain.Unit;
import com.xiaoniu.subsystem.system.domain.dto.AddSysUserDTO;
import com.xiaoniu.subsystem.system.domain.dto.EditSysUserDTO;
import com.xiaoniu.subsystem.system.domain.dto.UserDetailVO;
import com.xiaoniu.subsystem.system.domain.dto.UserListQueryDTO;
import com.xiaoniu.subsystem.system.domain.vo.UserListVO;
import com.xiaoniu.subsystem.system.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.*;

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

import static com.xiaoniu.common.security.utils.SecurityUtils.getUnitId;

/**
 * 用户信息表 控制器
 *
 * @author sst
 * @since 2024-11-26
 */
@RestController
@AllArgsConstructor
@RequestMapping("/sysuser")
@Tag(name = "用户信息表", description = "用户信息表接口")
public class SysUserController {

    @Resource
    private ISysUserService sysUserService;
    @Resource
    private ISysPermissionService permissionService;
    @Resource
    private ISysPostService postService;
    @Resource
    private ISysRoleService roleService;
    @Resource
    private ISysUserRoleService sysUserRoleService;
    private IUnitService unitService;

    public static boolean isAdmin(Long userId) {
        return userId != null && 1L == userId;
    }

    /**
     * 详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "详情", description = "传入sysUser")
    public R<UserDetailVO> detail(@RequestParam Long userId) {
        UserDetailVO detail = sysUserService.detail(userId);
        return R.data(detail);
    }

    /**
     * 自定义分页 用户信息表
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @Operation(summary = "分页", description = "传入sysUser")
    public R<IPage<UserListVO>> page(UserListQueryDTO dto) {
        if (0 != getUnitId() && null == dto.getUnitId()){
            dto.setUnitId(getUnitId());
        }
        IPage<UserListVO> pages = sysUserService.selectUserList(
                new Page<>(dto.getPageNum(), dto.getPageSize()), dto);
        return R.data(pages);
    }

    /**
     * 新增 用户信息表
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @Operation(summary = "新增", description = "传入sysUser")
    public R save(@Valid @RequestBody AddSysUserDTO dto) {
        return R.status(sysUserService.addUser(dto));
    }

    /**
     * 修改 用户信息表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @Operation(summary = "修改", description = "传入sysUser")
    public R update(@Valid @RequestBody EditSysUserDTO dto) {
        return R.status(sysUserService.editUser(dto));
    }

    /**
     * 删除 用户信息表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @Operation(summary = "逻辑删除", description = "传入ids")
    public R remove(@Parameter(description = "主键集合", required = true) @RequestParam List<Long> userIds) {
        return R.status(sysUserService.del(userIds));
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    @Operation(summary = "获取用户信息")
    public AjaxResult getInfo() {
        SysUser user = sysUserService.selectUserById(SecurityUtils.getUserId());
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 根据用户编号获取详细信息
     */
    @RequiresPermissions("system:user:query")
    @GetMapping(value = {"/", "/{userId}"})
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = roleService.selectRoleAll();
        ajax.put("roles", isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        ajax.put("posts", postService.selectPostAll());
        if (StringUtils.isNotNull(userId)) {
            SysUser sysUser = sysUserService.selectUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, sysUser);
            ajax.put("postIds", postService.selectPostListByUserId(userId));
            // 获取用户关联角色信息
            List<SysUserRole> userRoleList = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
            if (StringUtils.isNotNull(userRoleList)) {
                ajax.put("roleIds", userRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
            }
        }
        return ajax;
    }

    /**
     * 重置密码
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public R resetPwd(@RequestBody SysUser user) {
        if (StringUtils.isNotNull(user.getUserId()) && isAdmin(user.getUserId())) {
            throw new ServiceException("不允许操作超级管理员用户");
        }
        if (!isAdmin(SecurityUtils.getUserId())) {
            SysUser sysUser = sysUserService.selectUserById(SecurityUtils.getUserId());
            if (StringUtils.isNull(sysUser)) {
                throw new ServiceException("没有权限访问用户数据！");
            }
        }
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setUpdateBy(SecurityUtils.getUsername());
        return R.status(sysUserService.updateById(user));
    }

    private void setUnit(List<Unit> list, List<Long> ids){
        if (CollectionUtils.isNotEmpty(list)){
            List<Long> longs = list.stream().map(Unit::getUnitId).toList();
            ids.addAll(longs);
            List<Unit> units = unitService.list(new LambdaQueryWrapper<Unit>()
                    .in(Unit::getParentId,longs));
            setUnit(units,ids);
        }
    }

}
