package com.chushang.system.controller;

import com.chushang.common.core.exception.ResultException;
import com.chushang.common.core.util.StringUtils;
import com.chushang.common.core.web.AjaxResult;
import com.chushang.common.log.annotation.SysLog;
import com.chushang.common.log.enums.BusinessType;
import com.chushang.datascope.entity.DataScopeEntity;
import com.chushang.security.annotation.RequiresPermissions;
import com.chushang.security.service.TokenService;
import com.chushang.security.utils.SecurityUtils;
import com.chushang.system.entity.bo.PasswordForm;
import com.chushang.system.entity.dto.ListUserDTO;
import com.chushang.system.entity.po.SysPost;
import com.chushang.system.entity.po.SysRole;
import com.chushang.system.entity.po.SysUser;
import com.chushang.security.entity.vo.LoginUser;
import com.chushang.system.service.*;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @author by zhaowenyuan create 2022/8/18 17:50
 */
@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Resource
    ISysUserService sysUserService;
    @Resource
    ISysRoleService sysRoleService;
    @Resource
    ISysPostService sysPostService;
    @Resource
    ISysPermissionService permissionService;
    @Resource
    TokenService tokenService;

    /**
     * 用户列表
     */
    @GetMapping(value = "/list")
    // 权限校验 -- 菜单权限
    @RequiresPermissions("system:user:list")
    public AjaxResult listUser(ListUserDTO listUserDTO) {
        return sysUserService.listUser(listUserDTO);
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("info")
    public AjaxResult getInfo() {
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = sysUserService.selectUserById(userId);
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(sysUser);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(sysUser);

        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", sysUser);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取个人信息
     */
    @GetMapping("/profile")
    public AjaxResult profile()
    {
        String username = SecurityUtils.getUsername();
        SysUser user = sysUserService.selectUserByUserName(username);
        user.setPassword(null);
        user.setSalt(null);
        return AjaxResult.success(user)
                        .add("roleGroup", sysUserService.selectUserRoleGroup(username))
                .add("postGroup", sysUserService.selectUserPostGroup(username));
    }

    /**
     * 修改用户
     */
    @SysLog(value = "信息登录名称", businessType = BusinessType.UPDATE)
    @PutMapping("/profile")
    public AjaxResult updateProfile(@RequestBody SysUser user)
    {
        LoginUser<SysUser, DataScopeEntity> loginUser = SecurityUtils.getLoginUser();
        String username = user.getUsername();
        if (!sysUserService.checkUsername(username)){
            SysUser sysUser = loginUser.getSysUser();
            user.setUserId(sysUser.getUserId());
            user.setUsername(username);
            user.setEmail(user.getEmail());
            user.setPhone(user.getPhone());
            user.setGender(user.getGender());
            user.setPassword(null);
            user.setDeptId(null);
            if (sysUserService.updateUserProfile(user))
            {
                // 更新缓存用户信息
                tokenService.setLoginUser(loginUser);
                return AjaxResult.success();
            }
        }
        return AjaxResult.error("修改个人信息异常，请联系管理员");
    }

    /**
     * 根据用户编号获取详细信息
     */
    @RequiresPermissions("system:user:query")
    @GetMapping(value = {"/", "/{userId}"})
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        sysUserService.checkUserDataScope(new SysUser(userId));
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = sysRoleService.selectRoleAll(new SysRole());

        List<SysPost> posts = sysPostService.allPostList();
        // 角色
        ajax.put("roles", SysUser.isAdmin(userId) || SecurityUtils.isAdmin() ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        // 岗位
        ajax.put("posts", posts);
        if (StringUtils.isNotNull(userId)) {
            SysUser sysUser = sysUserService.selectUserById(userId);
            sysUser.setPassword("");
            sysUser.setSalt("");
            ajax.put(AjaxResult.DATA_TAG, sysUser);
            ajax.put("postIds", sysPostService.selectPostListByUserId(userId));
            ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));

        }
        return ajax;
    }

    @SysLog(value = "用户", businessType = BusinessType.INSERT)
    @PostMapping("/save")
    @RequiresPermissions(value = "system:user:save")
    public AjaxResult save(@RequestBody SysUser user) {

        user.setCreateBy(SecurityUtils.getUsername());

        sysUserService.saveUser(user);

        return AjaxResult.success();
    }


    /**
     * 修改用户
     */
    @SysLog(value = "用户", businessType = BusinessType.UPDATE)
    @PostMapping("/update")
    @RequiresPermissions("system:user:update")
    public AjaxResult update(@RequestBody SysUser user) {

        sysUserService.checkUserAllowed(user);

        sysUserService.checkUserDataScope(new SysUser(user.getUserId()));

        sysUserService.update(user);

        return AjaxResult.success();
    }

    /**
     * 删除用户
     */
    @SysLog(value = "用户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    @RequiresPermissions("system:user:delete")
    public AjaxResult delete(@PathVariable Long[] userIds) {
        if (ArrayUtils.contains(userIds, 1)) {
            return AjaxResult.error("系统管理员不能删除");
        }

        if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) {
            return AjaxResult.error("当前用户不能删除");
        }

        sysUserService.deleteBatch(userIds);

        return AjaxResult.success();
    }

    /**
     * 修改自己的
     */
    @RequiresPermissions("system:user:updatePwd")
    @SysLog(value = "密码", businessType = BusinessType.DELETE)
    @PutMapping("/updatePwd")
    public AjaxResult updatePwd(@RequestBody @Valid PasswordForm form)
    {
        // 这里没有密码
        LoginUser<SysUser, DataScopeEntity> loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getSysUser();
        if (!SecurityUtils.matchesPassword(form.getOldPassword(), sysUser.getSalt(), sysUser.getPassword())){
            throw new ResultException("原密码不正确");
        }
        //sha256加密
        String newPassword = SecurityUtils.encryptPassword(form.getNewPassword(), sysUser.getSalt());
        //更新密码
        boolean flag = sysUserService.updatePassword(sysUser.getUserId(), sysUser.getPassword(), newPassword);
        if(!flag){
            throw new ResultException("原密码不正确");
        }

        // 更新缓存用户密码
        loginUser.getSysUser().setPassword(newPassword);
        tokenService.setLoginUser(loginUser);
        return AjaxResult.success();
    }

    /**
     * 重置密码 别人的
     */
    @RequiresPermissions("system:user:resetPwd")
    @SysLog(value = "重置密码", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd/{userId}")
    public AjaxResult resetPwd(@RequestBody @Valid PasswordForm form,
                               @PathVariable Long userId)
    {
        // 不允许操作超级管理账号
        sysUserService.checkUserAllowed(new SysUser(userId));
        // 查看自己有没有权限操作
        sysUserService.checkUserDataScope(new SysUser(SecurityUtils.getUserId()));

        sysUserService.resetPwd(userId, form.getNewPassword());

        return AjaxResult.success();
    }

    @RequiresPermissions("system:user:edit")
    @SysLog(value = "头像", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/avatar")
    public AjaxResult updateAvatar(@RequestBody SysUser user){
        Long userId = SecurityUtils.getUserId();
        sysUserService.update(new SysUser()
                        .setUserId(userId)
                        .setAvatar(user.getAvatar())
        );
        return AjaxResult.success();
    }

    /**
     * 状态修改
     */
    @RequiresPermissions("system:user:changeStatus")
    @SysLog(value = "用户状态", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysUser user)
    {
        sysUserService.checkUserAllowed(user);
        sysUserService.checkUserDataScope(new SysUser(user.getUserId()));
        user.setUpdateBy(SecurityUtils.getUsername());
        sysUserService.updateUserStatus(user);
        return AjaxResult.success();
    }

    /**
     * 根据用户编号获取授权角色
     */
    @RequiresPermissions("system:user:query")
    @GetMapping("/authRole/{userId}")
    public AjaxResult authRole(@PathVariable Long userId)
    {
        AjaxResult ajax = AjaxResult.success();
        SysUser user = sysUserService.selectUserById(userId);
        // 此处获取的 role 应当为 当前用户所能显示的所有role
        List<SysRole> roles = sysRoleService.selectRolesByUserId(user);
        user.setPassword("");
        user.setSalt("");
        ajax.put("user", user);
        ajax.put("roles", SysUser.isAdmin(userId) || SecurityUtils.isAdmin() ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return ajax;
    }

    /**
     * 用户授权角色
     */
    @RequiresPermissions("system:user:auth")
    @SysLog(value = "用户", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
    {
        sysUserService.checkUserDataScope(new SysUser(userId));
        sysUserService.insertUserAuth(userId, roleIds);
        return AjaxResult.success();
    }


    /**
     * todo 导入用户
     */
    @PostMapping(value = "/import")
    @RequiresPermissions("system:user:import")
    public AjaxResult importUser(MultipartFile file){
        return AjaxResult.error("暂未开放");
    }

    /**
     * todo 导出用户
     */
    @GetMapping(value = "/export")
    @RequiresPermissions("system:user:export")
    public AjaxResult exportUser(){
        return AjaxResult.error("暂未开放");
    }

    /**
     * todo 下载导入模版
     */
    @GetMapping(value = "/import/template")
    @RequiresPermissions("system:user:import")
    public AjaxResult importTemplate(){
        return AjaxResult.error("暂未开放");
    }
}
