package com.lutao.cloud.admin.controller;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lutao.cloud.admin.api.dto.ForgetPwdDTO;
import com.lutao.cloud.admin.api.dto.RegisterDTO;
import com.lutao.cloud.admin.api.dto.UserDTO;
import com.lutao.cloud.admin.api.dto.UserInfo;
import com.lutao.cloud.admin.api.entity.SysUser;
import com.lutao.cloud.admin.api.vo.UserByIdVO;
import com.lutao.cloud.admin.api.vo.UserExcelVO;
import com.lutao.cloud.admin.api.vo.UserPageVo;
import com.lutao.cloud.admin.api.vo.UserVO;
import com.lutao.cloud.admin.service.SysUserService;
import com.lutao.cloud.common.core.util.MessageInfo;
import com.lutao.cloud.common.excel.annotation.RequestExcel;
import com.lutao.cloud.common.excel.annotation.ResponseExcel;
import com.lutao.cloud.common.log.annotation.SysLog;
import com.lutao.cloud.common.security.annotation.Inner;
import com.lutao.cloud.common.security.password.PasswordEncoderSha;
import com.lutao.cloud.common.security.util.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;

/**
 * @date 2018/12/16
 */
@Api(value = "/user", tags ={"用户管理"})
@RestController
@AllArgsConstructor
@RequestMapping("/user")
@Slf4j
public class SysUserController{

    private final SysUserService userService;

    private static final PasswordEncoder ENCODER = new PasswordEncoderSha();


//    @Inner
    @ApiOperation(value = "根据用户名查询用户权限信息", notes = "根据用户名查询用户权限信息", httpMethod = "GET")
    @GetMapping("/userPermission/{username}")
    public MessageInfo<UserVO> userPermission(@PathVariable String username){
        SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
        if (user == null){
            return MessageInfo.failed(null, String.format("用户信息为空 %s", username));
        }
        return MessageInfo.ok(userService.findUserPermission(user.getUsername()));
    }

    /**
     * 获取指定用户全部信息
     *
     * @return 用户信息
     */
    @ApiOperation(value = "获取指定用户全部信息", notes = "获取指定用户全部信息", httpMethod = "GET")
    @Inner
    @GetMapping("/info/{username}")
    public MessageInfo<UserInfo> info(@PathVariable String username){
        SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
        if (user == null){
            return MessageInfo.failed(null, String.format("用户信息为空 %s", username));
        }
        return MessageInfo.ok(userService.findUserInfo(user));
    }

    /**
     * 获取当前用户全部信息
     *
     * @return 用户信息
     */
    @ApiOperation(value = "获取当前用户全部信息", notes = "获取当前用户全部信息", httpMethod = "GET")
    @Inner
    @GetMapping(value ={"/info"})
    public MessageInfo<UserInfo> info(){
        String username = SecurityUtils.getUser().getUsername();
        SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
        if (user == null){
            return MessageInfo.failed(null, "获取当前用户信息失败");
        }
        return MessageInfo.ok(userService.findUserInfo(user));
    }
    /**
     * 获取当前用户的信息
     * @return 用户信息
     */
    @ApiOperation(value = "获取当前用户的信息", notes = "获取当前用户的信息", httpMethod = "GET")
    @GetMapping(value ={"/user/getPersonInfo"})
    public MessageInfo<UserByIdVO> getPerson(){
        return MessageInfo.ok(userService.selectPerson());
    }

    /**
     * 通过ID查询用户信息
     *
     * @param id ID
     * @return 用户信息
     */
    @ApiOperation(value = "通过ID查询用户信息", notes = "通过ID查询用户信息", httpMethod = "GET")
    @GetMapping("/{id}")
//    @PreAuthorize("@pms.hasPermission('admin_user_view')" )
    public MessageInfo<UserVO> user(@PathVariable Integer id){
        UserVO vo = userService.selectUserVoById(id);
        if (vo != null){
            vo.setPassword("");
        }
        return MessageInfo.ok(vo);
    }

    /**
     * 通过ID查询用户信息
     *
     * @param  userId
     * @return 用户信息
     */
    @ApiOperation(value = "通过ID查询用户信息", notes = "通过ID查询用户信息", httpMethod = "GET")
    @GetMapping("/detail/{userId}")
    @Inner
    public MessageInfo<UserVO> detail(@PathVariable Integer userId){
        return MessageInfo.ok(userService.selectUserVoById(userId));
    }



    /**
     * 根据用户名查询用户信息
     *
     * @param username 用户名
     * @return
     */
    @ApiOperation(value = "根据用户名查询用户信息", notes = "根据用户名查询用户信息", httpMethod = "GET")
    @GetMapping("/details/{username}")
    @Inner
    public MessageInfo<SysUser> user(@PathVariable String username){
        SysUser condition = new SysUser();
        condition.setUsername(username);
        return MessageInfo.ok(userService.getOne(new QueryWrapper<>(condition)));
    }

    /**
     * 删除用户信息
     *
     * @param id ID
     * @return R
     */
    @ApiOperation(value = "删除用户", notes = "根据ID删除用户", httpMethod = "DELETE")
    @SysLog("删除用户信息")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('sys_user_del')")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "int", dataTypeClass = Integer.class, paramType = "path")
    public MessageInfo<Boolean> userDel(@PathVariable Integer id){
        SysUser sysUser = userService.getById(id);

        return MessageInfo.ok(userService.deleteUserById(sysUser));
    }

    /**
     * 添加用户
     *
     * @param userDto 用户信息
     * @return success/false
     */
    @ApiOperation(value = "添加用户", notes = "添加用户", httpMethod = "POST")
    @SysLog("添加用户")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('sys_user_add')")
    public MessageInfo<Boolean> user(@RequestBody UserDTO userDto){
        return userService.saveUser(userDto);
    }

    /**
     * 添加用户
     *
     * @param userDto 用户信息
     * @return success/false
     */
    @ApiOperation(value = "添加用户", notes = "添加用户", httpMethod = "POST")
    @SysLog("添加用户")
    @PostMapping("/info")
    @Inner
    public MessageInfo<Boolean> userInner(@RequestBody UserDTO userDto){
        return userService.saveUser(userDto);
    }

    /**
     * 注册用户
     *
     * @param registerDTO 注册用户
     * @return success/false
     */
    @ApiOperation(value = "注册用户", notes = "注册用户", httpMethod = "POST")
    @SysLog("注册用户")
    @PostMapping("/register")
    @Inner(value = false)
    public MessageInfo<Integer> user(@RequestBody RegisterDTO registerDTO){
        return userService.register(registerDTO);
    }

    /**
     * 更新用户信息
     *
     * @param userDto 用户信息
     */
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息", httpMethod = "PUT")
    @SysLog("更新用户信息")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('sys_user_edit')")
    public MessageInfo<Boolean> updateUser(@Valid @RequestBody UserDTO userDto){
        return MessageInfo.ok(userService.updateUser(userDto));
    }

    /**
     * 更新用户信息
     *
     * @param userDto 用户信息
     */
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息", httpMethod = "PUT")
    @SysLog("更新用户信息")
    @PutMapping("/info")
    @Inner
    public MessageInfo<Boolean> updateUserInner(@Valid @RequestBody UserDTO userDto){
        return MessageInfo.ok(userService.updateUser(userDto));
    }

    /**
     * 分页查询用户
     *
     * @param page    参数集
     * @param userDTO 查询参数列表
     * @return 用户集合
     */
    @ApiOperation(value = "分页查询用户", notes = "分页查询用户", httpMethod = "GET")
    @GetMapping("/page")
    @SysLog("分页查询用户")
//    @PreAuthorize("@pms.hasPermission('admin_user_page')")
    public MessageInfo<IPage<UserVO>> getUserPage(Page page, UserDTO userDTO){
        return MessageInfo.ok(userService.getUsersWithRolePage(page, userDTO));
    }

    /**
     *用户信息的分页
     * @param page
     * @return
     */
    @ApiOperation(value = "用户信息的分页", notes = "用户信息的分页", httpMethod = "GET")
    @GetMapping("/userPage")
    @SysLog("分页查询用户")
    public MessageInfo<IPage<UserPageVo>> getUserAllPage(Page page){
        return userService.getSelectAll(page);
    }
    /**
     * 修改个人信息
     *
     * @param userDto userDto
     * @return success/false
     */
    @ApiOperation(value = "修改个人信息", notes = "修改个人信息", httpMethod = "PUT")
    @SysLog("修改个人信息")
    @PutMapping("/edit")
    public MessageInfo<Boolean> updateUserInfo(@Valid @RequestBody UserDTO userDto){
        return userService.updateUserInfo(userDto);
    }

    /**
     * @param username 用户名称
     * @return 上级部门用户列表
     */
    @ApiOperation(value = "上级部门用户列表", notes = "上级部门用户列表", httpMethod = "GET")
    @GetMapping("/ancestor/{username}")
    public MessageInfo<List<SysUser>> listAncestorUsers(@PathVariable String username){
        return MessageInfo.ok(userService.listAncestorUsers(username));
    }


    /**
     * 导出excel 表格
     * @param userDTO 查询条件
     * @return
     */
    @ResponseExcel
    @GetMapping("/export")
//    @PreAuthorize("@pms.hasPermission('sys_log_export')")
    public List export(UserDTO userDTO){
        return userService.listUser(userDTO);
    }

    /**
     * 导入用户
     * @param excelVOList 用户列表
     * @param bindingResult 错误信息列表
     * @return MessageInfo
     */
    @PostMapping("/import")
//    @PreAuthorize("@pms.hasPermission('sys_log_export')")
    public MessageInfo importUser(@RequestExcel List<UserExcelVO> excelVOList, BindingResult bindingResult){
        return userService.importUser(excelVOList, bindingResult);
    }

    /**
     * 重置密码
     *
     */
    @ApiOperation(value = "重置密码", notes = "重置密码", httpMethod = "PUT")
    @SysLog("重置密码")
    @PutMapping("resetpw")
    @PreAuthorize("@pms.hasPermission('sys_user_resetpw')")
    public MessageInfo resetpwd(@RequestBody UserDTO userDTO){
        String password = ENCODER.encode("cast:123456");
        userDTO.setPassword(password);
        userService.updateUser(userDTO);
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOnce("result","新密码是  cast:123456");
        return MessageInfo.ok().setData(jsonObject);
    }

    /**
     * 忘记密码
     *
     */
    @ApiOperation(value = "忘记密码", notes = "忘记密码", httpMethod = "PUT")
    @SysLog("忘记密码")
    @PutMapping("forgetPwd")
    @Inner(value = false)
//    @PreAuthorize("@pms.hasPermission('sys_user_forgetPwd')")
    public MessageInfo forgetPwd(@RequestBody ForgetPwdDTO forgetPwdDTO){
        return userService.forgetPwd(forgetPwdDTO);
    }


}
