
package com.tmerclub.cloud.auth.controller;

import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.auth.bo.UidInfoBO;
import com.tmerclub.cloud.api.auth.vo.TokenInfoVO;
import com.tmerclub.cloud.auth.dto.ForgetPasswordDTO;
import com.tmerclub.cloud.auth.dto.UpdatePasswordDTO;
import com.tmerclub.cloud.auth.manager.PasswordManager;
import com.tmerclub.cloud.auth.manager.TokenStore;
import com.tmerclub.cloud.auth.model.AuthAccount;
import com.tmerclub.cloud.auth.service.AuthAccountService;
import com.tmerclub.cloud.common.cache.util.RedisUtil;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * @author tmerclub
 * @date 2021/01/29
 */
@RestController
@Tag(name = "密码")
public class PasswordController {

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthAccountService authAccountService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private PasswordManager passwordManager;

    public static final String CHECK_UPDATE_SMS_FLAG = "checkUpdatePwdSmsFlag";


    @PutMapping("/updatePassword")
    @Operation(summary = "更新密码", description = "更新当前用户的密码, 更新密码之后要退出登录，清理token")
    public ServerResponseEntity<TokenInfoVO> updatePassword(@Valid @RequestBody UpdatePasswordDTO updatePasswordDTO) {
        UidInfoBO uidInfoBO = AuthUserContext.get();
        AuthAccount authAccount = authAccountService.getByUserIdAndType(uidInfoBO.getUserId(), uidInfoBO.getSysType());
        ServerResponseEntity<String> oldPasswordEntity = passwordManager.decryptPassword(updatePasswordDTO.getOldPassword());
        if (!oldPasswordEntity.isSuccess()) {
            return ServerResponseEntity.transform(oldPasswordEntity);
        }
        String oldDecryptPassword = oldPasswordEntity.getData();
        ServerResponseEntity<String> newPasswordEntity = passwordManager.decryptPassword(updatePasswordDTO.getNewPassword());
        if (!newPasswordEntity.isSuccess()) {
            return ServerResponseEntity.transform(newPasswordEntity);
        }
        String newDecryptPassword = newPasswordEntity.getData();
        if (!passwordEncoder.matches(oldDecryptPassword, authAccount.getPassword())) {
            return ServerResponseEntity.showFailMsg("旧密码不正确");
        }


        authAccountService.updatePassword(uidInfoBO.getUserId(), uidInfoBO.getSysType(), newDecryptPassword);

        tokenStore.deleteUserToken();
        return ServerResponseEntity.success();
    }

    @PutMapping("/ua/forgetPassword")
    @Operation(summary = "忘记密码", description = "通过验证码修改密码，更新密码之后要退出登录，清理token")
    public ServerResponseEntity<TokenInfoVO> password(@Valid @RequestBody ForgetPasswordDTO forgetPasswordDTO) {

        AuthAccount authAccount = authAccountService.getAccountByInputUserName(forgetPasswordDTO.getMobile(), forgetPasswordDTO.getSysType());
        if (authAccount == null) {
            return ServerResponseEntity.showFailMsg("用户不存在");
        }

        String checkUpdatePwdSmsFlag = CHECK_UPDATE_SMS_FLAG + forgetPasswordDTO.getCheckUpdatePwdSmsFlag();
        // 看看有没有校验验证码成功的标识
        if (StrUtil.isBlank(forgetPasswordDTO.getCheckUpdatePwdSmsFlag())) {
            // 验证码已过期，请重新发送验证码校验
            throw new LuckException("验证码已过期，请重新发送验证码校验");
        } else {
            String checkRegisterSmsFlagMobile = RedisUtil.get(checkUpdatePwdSmsFlag);
            if (!Objects.equals(checkRegisterSmsFlagMobile, forgetPasswordDTO.getMobile())) {
                // 验证码已过期，请重新发送验证码校验
                throw new LuckException("验证码已过期，请重新发送验证码校验");
            }
        }

        ServerResponseEntity<String> newPasswordEntity = passwordManager.decryptPassword(forgetPasswordDTO.getNewPassword());
        if (!newPasswordEntity.isSuccess()) {
            return ServerResponseEntity.transform(newPasswordEntity);
        }
        String newDecryptPassword = newPasswordEntity.getData();
        authAccountService.updatePassword(authAccount.getUserId(), authAccount.getSysType(), newDecryptPassword);

        tokenStore.deleteUserToken();
        return ServerResponseEntity.success();
    }

}
