package com.starry.admin.modules.system.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.starry.admin.common.component.JwtToken;
import com.starry.admin.common.domain.LoginUser;
import com.starry.admin.common.oss.service.IOssFileService;
import com.starry.admin.modules.system.module.entity.SysRoleEntity;
import com.starry.admin.modules.system.module.entity.SysUserEntity;
import com.starry.admin.modules.system.service.SysRoleService;
import com.starry.admin.modules.system.service.SysUserService;
import com.starry.admin.modules.system.vo.*;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.annotation.Log;
import com.starry.common.constant.UserConstants;
import com.starry.common.enums.BusinessType;
import com.starry.common.result.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 * 后台用户表 前端控制器
 * </p>
 *
 * @author admin
 * @since 2021-09-03
 */
@Api(tags = "用户管理", description = "系统用户管理相关接口")
@RestController
@RequestMapping("/ucenter/user")
public class SysUserController {

    @Resource
    private SysUserService userService;
    @Resource
    private SysRoleService roleService;
    @Resource
    private JwtToken tokenService;

    @Resource
    private IOssFileService ossFileService;

    @ApiOperation(value = "注册用户", notes = "新用户注册接口")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = SysUserEntity.class),
            @ApiResponse(code = 500, message = "操作失败")})
    @PostMapping(value = "register")
    public R register(@ApiParam(value = "用户信息", required = true) @RequestBody SysUserEntity user) {
        SysUserEntity sysUserEntity = userService.register(user);
        if (sysUserEntity == null) {
            return R.error("注册失败,用户名已存在");
        }
        return R.ok(sysUserEntity);
    }

    @ApiOperation(value = "分页用户列表", notes = "分页查询用户列表信息")
    @ApiResponses({
            @ApiResponse(code = 200, message = "操作成功", response = SysUserEntity.class, responseContainer = "Page")})
    @GetMapping(value = "/list-page")
    public R listPage(UserQueryVo queryVo) {
        IPage<SysUserEntity> page = userService.listMemberPage(queryVo);
        return R.ok(page);
    }

    @ApiOperation(value = "分页用户列表(V1)", notes = "分页查询用户列表信息，返回格式化后的结果")
    @ApiResponses({
            @ApiResponse(code = 200, message = "操作成功", response = SysUserEntityListVo.class, responseContainer = "Page")})
    @GetMapping(value = "/list-page/v1")
    public R listPageV1(UserQueryVo queryVo) {
        IPage<SysUserEntity> page = userService.listMemberPage(queryVo);
        List<SysUserEntity> records = page.getRecords();
        List<SysUserEntityListVo> list = userService.generatePageData(records);
        IPage<SysUserEntityListVo> result = new Page<>();
        result.setTotal(page.getTotal());
        result.setRecords(list);
        return R.ok(result);
    }

    @ApiOperation(value = "添加用户", notes = "创建新的系统用户")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "操作失败，登录账号已存在")})
    @PostMapping(value = "add")
    public R add(@ApiParam(value = "用户信息", required = true) @RequestBody SysUserEntity user) {
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserCode()))) {
            return R.error("新增用户'" + user.getUserCode() + "'失败，登录账号已存在");
        }
        boolean success = userService.create(user);
        if (success) {
            return R.ok();
        }
        return R.error("添加失败");
    }

    @ApiOperation(value = "添加用户(V1)", notes = "创建新的系统用户，使用参数对象")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PostMapping(value = "add/v1")
    public R addV1(@ApiParam(value = "用户添加参数", required = true) @Valid @RequestBody UserAddParam param) {
        boolean success = userService.addV1(param);
        return R.ok();
    }

    @ApiOperation(value = "修改用户", notes = "根据ID修改用户信息")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String", paramType = "path")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "修改失败")})
    @PostMapping(value = "/update/{id}")
    public R update(@PathVariable("id") String id,
            @ApiParam(value = "用户信息", required = true) @RequestBody SysUserEntity user) {
        user.setUserId(id);
        boolean flag = userService.update(user);
        if (flag) {
            return R.ok();
        }
        return R.error("修改失败");
    }

    @ApiOperation(value = "修改用户密码", notes = "修改当前用户的密码")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PostMapping(value = "/update/password")
    public R updatePassword(
            @ApiParam(value = "密码修改参数", required = true) @Valid @RequestBody UpdateUserPasswordParam param) {
        userService.updatePassword(param);
        return R.ok();
    }

    @ApiOperation(value = "修改用户密码", notes = "修改当前用户的密码")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PostMapping(value = "/profile/updatePwd")
    public R updatePasswordV2(
            @ApiParam(value = "密码修改参数", required = true) @Valid @RequestBody UpdateUserPasswordParamV2 param) {
        userService.updatePasswordV2(param);
        return R.ok();
    }

    @ApiOperation(value = "修改用户手机号", notes = "修改当前用户的手机号")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PostMapping(value = "/update/mobile")
    public R updateMobile(
            @ApiParam(value = "手机号修改参数", required = true) @Valid @RequestBody UpdateUserMobileParam param) {
        userService.updateMobile(param);
        return R.ok();
    }

    @ApiOperation(value = "删除用户", notes = "根据ID删除用户")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String", paramType = "path")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "操作失败")})
    @PostMapping(value = "/delete/{id}")
    public R delete(@PathVariable("id") String id) {
        boolean flag = userService.delete(Collections.singletonList(id));
        if (flag) {
            return R.ok();
        }
        return R.error();
    }

    @ApiOperation(value = "登出功能", notes = "用户登出系统")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PostMapping(value = "logout")
    public R logout() {
        return R.ok();
    }

    @ApiOperation(value = "获取用户详情", notes = "根据用户ID获取用户详细信息，不传ID则获取当前用户")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = false, dataType = "String", paramType = "path")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = Map.class)})
    @GetMapping(value = {"/", "/{userId}"})
    public R getInfo(@PathVariable(value = "userId", required = false) String userId) {
        SysUserEntity user = userService.selectUserById(userId);
        Map<String, Object> map = new HashMap<>(8);
        List<SysRoleEntity> roles = roleService.selectRoleList(new SysRoleEntity());
        map.put("roles",
                SysUserEntity.isAdmin(user)
                        ? roles
                        : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        map.put("roleIds", user.getRoles().stream().map(SysRoleEntity::getRoleId).collect(Collectors.toList()));
        map.put("user", user);
        return R.ok(map);
    }

    @ApiOperation(value = "获取个人信息", notes = "获取当前登录用户的个人信息")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = Map.class)})
    @GetMapping(value = "/profile")
    public R getProfile() {
        Map<String, Object> map = new HashMap<>(8);
        SysUserEntity loginUser = userService.selectUserById(SecurityUtils.getUserId());
        map.put("user", loginUser);
        map.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUserId()));
        return R.ok(map);
    }

    @ApiOperation(value = "用户头像上传", notes = "上传用户头像图片")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = String.class),
            @ApiResponse(code = 500, message = "上传头像异常")})
    @Log(title = "用户头像上传", businessType = BusinessType.UPDATE)
    @PostMapping("/profile/avatar")
    public R uploadAvatar(@ApiParam(value = "头像文件", required = true) @RequestParam("avatarfile") MultipartFile file)
            throws Exception {
        if (!file.isEmpty()) {
            String avatar = ossFileService.upload(file.getInputStream(), "avatar", file.getOriginalFilename());
            if (userService.updateUserAvatar(SecurityUtils.getUserId(), avatar)) {
                // 更新缓存用户头像
                LoginUser loginUser = SecurityUtils.getLoginUser();
                loginUser.getUser().setAvatar(avatar);
                tokenService.refreshToken(loginUser);
                return R.ok(avatar);
            }
        }
        return R.error("上传头像异常，请联系管理员");
    }
}
