package ink.wgink.service.user.controller.app.api;

import ink.wgink.annotation.CheckRequestBodyAnnotation;
import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.exceptions.DependencyException;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.exceptions.UpdateException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.interfaces.sms.ISmsBaseService;
import ink.wgink.pojo.dtos.user.UserDTO;
import ink.wgink.pojo.result.ErrorResult;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultData;
import ink.wgink.pojo.vos.IdsVO;
import ink.wgink.pojo.vos.UpdatePasswordVO;
import ink.wgink.pojo.vos.UpdatePhonePasswordVO;
import ink.wgink.service.user.pojo.dtos.AppUserDTO;
import ink.wgink.service.user.pojo.vos.UpdateUserVO;
import ink.wgink.service.user.service.IUserService;
import ink.wgink.util.ReflectUtil;
import ink.wgink.util.RegexUtil;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: UserAppController
 * @Description: 用户
 * @Author: WangGeng
 * @Date: 2019-08-14 14:24
 * @Version: 1.0
 **/
@Api(tags = ISystemConstant.API_TAGS_APP_PREFIX + "用户")
@RestController
@RequestMapping(ISystemConstant.APP_PREFIX + "/user")
public class UserAppController extends DefaultBaseController {

    @Autowired
    private IUserService userService;
    @Autowired(required = false)
    private ISmsBaseService smsBaseService;

    @ApiOperation(value = "注销用户", notes = "注销用户接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @DeleteMapping("log-off")
    public SuccessResult deleteByUserId(@RequestHeader("token") String token) {
        userService.deleteByToken(token);
        return new SuccessResult();
    }

    @ApiOperation(value = "修改用户信息", notes = "修改用户信息接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update-info")
    @CheckRequestBodyAnnotation
    public SuccessResultData<String> updateInfo(@RequestHeader("token") String token, @RequestBody UpdateUserVO updateUserVO) throws Exception {
        if (StringUtils.isBlank(updateUserVO.getName())) {
            throw new ParamsException("昵称不能为空");
        }
        if (!StringUtils.isBlank(updateUserVO.getPhone()) && !RegexUtil.isPhone(updateUserVO.getPhone())) {
            throw new ParamsException("手机格式不正确");
        }
        if (!StringUtils.isBlank(updateUserVO.getEmail()) && !RegexUtil.isEmail(updateUserVO.getEmail())) {
            throw new ParamsException("邮箱格式不正确");
        }
        return new SuccessResultData<>(userService.updateInfo(token, updateUserVO));
    }

    @ApiOperation(value = "修改头像", notes = "修改头像接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update-avatar")
    public SuccessResultData<String> updateAvatar(@RequestHeader("token") String token, @RequestBody UpdateUserVO updateUserVO) throws Exception {
        if (StringUtils.isBlank(updateUserVO.getAvatar())) {
            throw new ParamsException("头像不能为空");
        }
        return new SuccessResultData<>(userService.updateInfo(token, updateUserVO));
    }

    @ApiOperation(value = "修改昵称", notes = "修改昵称接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update-name")
    public SuccessResult updateName(@RequestHeader("token") String token, @RequestBody UpdateUserVO updateUserVO) throws Exception {
        if (StringUtils.isBlank(updateUserVO.getName())) {
            throw new ParamsException("昵称不能为空");
        }
        return new SuccessResultData<>(userService.updateInfo(token, updateUserVO));
    }

    @ApiOperation(value = "修改电话", notes = "修改电话接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update-phone")
    public SuccessResult updatePhone(@RequestHeader("token") String token, @RequestBody UpdateUserVO updateUserVO) throws Exception {
        if (StringUtils.isBlank(updateUserVO.getPhone())) {
            throw new ParamsException("电话不能为空");
        }
        return new SuccessResultData<>(userService.updateInfo(token, updateUserVO));
    }

    @ApiOperation(value = "修改邮箱", notes = "修改邮箱接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update-email")
    public SuccessResult updateEmail(@RequestHeader("token") String token, @RequestBody UpdateUserVO updateUserVO) throws Exception {
        if (StringUtils.isBlank(updateUserVO.getEmail())) {
            throw new ParamsException("邮箱不能为空");
        }
        return new SuccessResultData<>(userService.updateInfo(token, updateUserVO));
    }

    @ApiOperation(value = "修改密码", notes = "修改密码接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update-password")
    @CheckRequestBodyAnnotation
    public SuccessResult updatePassword(@RequestHeader("token") String token,
                                        @RequestBody UpdatePasswordVO updatePasswordVO) throws ParamsException, SearchException, UpdateException, ReflectUtil.ReflectException {
        if (updatePasswordVO.getNewPassword().length() < 6) {
            throw new ParamsException("新密码长度必须大于6位");
        }
        userService.updatePassword(token, updatePasswordVO);
        return new SuccessResult();
    }

    @ApiOperation(value = "忘记手机密码", notes = "忘记手机密码接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("forget-phone-password")
    @CheckRequestBodyAnnotation
    public SuccessResult updatePhonePassword(@RequestBody UpdatePhonePasswordVO updatePhonePasswordVO) throws ParamsException, SearchException, UpdateException, ReflectUtil.ReflectException {
        if (smsBaseService == null) {
            throw new DependencyException("短信依赖未引入");
        }
        if (updatePhonePasswordVO.getNewPassword().length() < 6) {
            throw new ParamsException("新密码长度必须大于6位");
        }
        String verifyCode = smsBaseService.getVerifyCode(updatePhonePasswordVO.getPhone());
        if (StringUtils.isBlank(verifyCode)) {
            throw new ParamsException("验证码为空");
        }
        if (!StringUtils.equalsIgnoreCase(verifyCode, updatePhonePasswordVO.getVerificationCode())) {
            throw new ParamsException("验证码错误");
        }
        userService.updatePasswordByUsername(updatePhonePasswordVO.getPhone(), updatePhonePasswordVO.getNewPassword());
        return new SuccessResult();
    }

    @ApiOperation(value = "获取APP用户", notes = "获取APP用户接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header"),
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("get-app-user")
    public AppUserDTO getAppUser(@RequestHeader("token") String token) throws ReflectUtil.ReflectException {
        return userService.getAppUser(token);
    }

    @ApiOperation(value = "下载用户头像", notes = "下载用户头像接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("download-avatar/{userId}")
    public void downLoadAvatar(@PathVariable("userId") String userId, HttpServletRequest request, HttpServletResponse response) {
        userService.downLoadAvatar(userId, request, response);
    }

    @ApiOperation(value = "通过ID列表获取用户列表", notes = "通过ID列表获取用户列表接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PostMapping("list/ids")
    public List<UserDTO> listByIds(@RequestHeader("token") String token, @RequestBody IdsVO idsVO) {
        if (idsVO.getIds().isEmpty()) {
            throw new ParamsException("id列表不能为空");
        }
        return userService.listByUserIds(idsVO.getIds());
    }

    @ApiOperation(value = "是否过期", notes = "是否过期接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "header")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("is-expired")
    public SuccessResult isExpired(@RequestHeader("token") String token) {
        userService.isExpiredByToken(token);
        return new SuccessResult();
    }

}
