package com.qiaoba.module.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.api.system.entity.SysRole;
import com.qiaoba.api.system.entity.SysUser;
import com.qiaoba.api.system.entity.dto.ResetPasswordDto;
import com.qiaoba.api.system.entity.dto.ResetUserStatusDto;
import com.qiaoba.api.system.entity.dto.SysUserDto;
import com.qiaoba.api.system.entity.param.SysPostParam;
import com.qiaoba.api.system.entity.param.SysRoleParam;
import com.qiaoba.api.system.entity.param.SysUserParam;
import com.qiaoba.api.system.entity.vo.SysUserVo;
import com.qiaoba.api.auth.utils.SecurityUtil;
import com.qiaoba.common.base.enums.BaseEnum;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.common.base.validate.AddGroup;
import com.qiaoba.common.base.validate.EditGroup;
import com.qiaoba.common.database.entity.PageQuery;
import com.qiaoba.common.database.entity.TableDataInfo;
import com.qiaoba.common.poi.util.ExcelUtil;
import com.qiaoba.module.system.service.*;
import com.qiaoba.module.system.templates.SysUserExport;
import com.qiaoba.module.system.templates.SysUserImport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户管理 web层
 *
 * @author ailanyin
 * @version 1.0
 * @since 2023-04-23 20:51:26
 */
@Validated
@RestController
@RequestMapping("/system/user")
@Tag(name = "用户管理")
@RequiredArgsConstructor
public class SysUserController {

    private final SysUserService sysUserService;
    private final SysRoleService sysRoleService;
    private final SysPostService sysPostService;
    private final SysUserPostService sysUserPostService;
    private final SysUserRoleService sysUserRoleService;
    private final SysUserImportService sysUserImportService;

    @PreAuthorize("hasAuthority('system:user:add')")
    @PostMapping
    @Operation(summary = "新增用户")
    public AjaxResult add(@Validated(AddGroup.class) @RequestBody SysUserDto dto) {
        return AjaxResult.toAjax(sysUserService.saveOrUpdate(dto, false));
    }

    @PreAuthorize("hasAuthority('system:user:edit')")
    @PutMapping
    @Operation(summary = "修改用户")
    public AjaxResult edit(@Validated(EditGroup.class) @RequestBody SysUserDto dto) {
        return AjaxResult.toAjax(sysUserService.saveOrUpdate(dto, true));
    }

    @PreAuthorize("hasAuthority('system:user:resetPwd')")
    @PutMapping("/resetPwd")
    @Operation(summary = "重置密码")
    public AjaxResult resetPwd(@Validated @RequestBody ResetPasswordDto dto) {
        SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
        sysUser.setPassword(SecurityUtil.encryptPassword(dto.getPassword()));
        return AjaxResult.toAjax(sysUserService.updateById(sysUser));
    }

    @PreAuthorize("hasAuthority('system:user:edit')")
    @PutMapping("/changeStatus")
    @Operation(summary = "更改状态")
    public AjaxResult changeStatus(@RequestBody ResetUserStatusDto dto) {
        SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
        return AjaxResult.toAjax(sysUserService.updateById(sysUser));
    }

    @PreAuthorize("hasAuthority('system:user:remove')")
    @DeleteMapping("/{userIds}")
    @Operation(summary = "删除用户")
    public AjaxResult remove(@PathVariable List<String> userIds) {
        return AjaxResult.toAjax(sysUserService.deleteByIds(userIds));
    }

    @GetMapping("/list")
    @Operation(summary = "分页查询")
    public TableDataInfo<SysUserVo> list(SysUserParam param, PageQuery pageQuery) {
        return sysUserService.selectVoPageList(param, pageQuery);
    }

    @PreAuthorize("hasAuthority('system:user:query')")
    @GetMapping(value = {"/", "/{userId}"})
    @Operation(summary = "获取详情")
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) String userId) {
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = sysRoleService.selectList(new SysRoleParam());
        ajax.put("roles", roles);
        ajax.put("posts", sysPostService.selectList(new SysPostParam(BaseEnum.NORMAL.getCode())));
        if (StrUtil.isNotBlank(userId)) {
            SysUser sysUser = sysUserService.selectById(userId, false);
            ajax.put(AjaxResult.DATA_TAG, sysUser);
            ajax.put("postIds", sysUserPostService.selectPostIdsByUserId(userId));
            ajax.put("roleIds", sysUserRoleService.selectRoleIdsByUserId(userId, null));
        }
        return ajax;
    }

    @PreAuthorize("hasAuthority('system:user:export')")
    @PostMapping("/export")
    @Operation(summary = "导出用户")
    public void export(HttpServletResponse response, SysUserParam param) {
        List<SysUserExport> list = sysUserService.selectExportData(param);
        ExcelUtil.exportExcel(list, SysUserExport.class, "用户数据", response);
    }

    @PostMapping("/importTemplate")
    @Operation(summary = "导出模板")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil.exportExcel(new ArrayList<>(), SysUserImport.class, "用户导入模板-(*)必填", response);
    }

    @PreAuthorize("hasAuthority('system:user:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception {
        List<SysUserImport> list = ExcelUtil.importExcel(file, SysUserImport.class);
        Integer success = sysUserImportService.importUser(list);
        return AjaxResult.success(StrUtil.format("成功导入({})条数据", success));
    }

    @PreAuthorize("hasAuthority('system:user:query')")
    @GetMapping("/authRole/{userId}")
    @Operation(summary = "已分配角色列表")
    public AjaxResult authRole(@PathVariable("userId") String userId) {
        AjaxResult ajax = AjaxResult.success();
        SysUser user = sysUserService.selectById(userId, false);
        List<SysRole> roles = sysRoleService.selectList(new SysRoleParam());
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("hasRoleIds", sysUserRoleService.selectRoleIdsByUserId(userId, null));
        return ajax;
    }

    @PreAuthorize("hasAuthority('system:user:edit')")
    @PutMapping("/authRole")
    @Operation(summary = "分配角色")
    public AjaxResult handleUserRole(String userId, String[] roleIds) {
        sysUserService.handleUserRole(userId, Arrays.stream(roleIds).collect(Collectors.toSet()), true);
        return AjaxResult.success();
    }

}
