package com.liquidnet.service.goblin.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.commons.lang.constant.LnsEnum;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.dto.GoblinUserSafeConfigDto;
import com.liquidnet.service.goblin.service.IGoblinUserSafeConfigService;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@ApiSupport(order = 142001)
@Api(tags = "用户安全设置")
@Slf4j
@Validated
@RestController
@RequestMapping("user/safe")
public class GoblinUserSafeController {
    @Autowired
    Environment env;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;
    @Autowired
    IGoblinUserSafeConfigService goblinUserAssetConfigService;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "是否设置安全密码", notes = "<br />响应【data】值描述：是否设置[0-未设置|1-已设置]")
    @GetMapping(value = {"passwd/had"})
    public ResponseDto<String> hadSecurityCode() {
        return ResponseDto.success(null == goblinRedisUtils.getUserSafeConfigDto(CurrentUtil.getCurrentUid()) ? "0" : "1");
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "设置安全密码")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "passwd", value = "安全密码:MD5(******)"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "code", value = "验证码"),
    })
    @PostMapping(value = {"passwd/set"})
    public ResponseDto<Object> setSecurityCode(@NotBlank(message = "安全密码不能为空") @Size(min = 32, max = 32, message = "安全密码无效") @RequestParam String passwd,
                                               @NotBlank(message = "验证码不能为空") @Pattern(regexp = "\\d{6}", message = "验证码格式有误") @RequestParam String code
    ) {
        String currentUid = CurrentUtil.getCurrentUid(), currentMobile = (String) CurrentUtil.getTokenClaims().get(CurrentUtil.TOKEN_MOBILE);
        ResponseDto<Object> validResultDto = this.validVerificationCode(code, currentMobile);
        if (!validResultDto.isSuccess()) return validResultDto;

        GoblinUserSafeConfigDto userSafeConfigDto = goblinRedisUtils.getUserSafeConfigDto(currentUid);
        if (null != userSafeConfigDto) {
            return ResponseDto.failure(ErrorMapping.get("140020"));
        }
        String lockKey = GoblinRedisConst.USER_SAFE_CONFIG.concat("lk").concat(currentUid);
        if (goblinRedisUtils.incr(lockKey, 1) > 1) return ResponseDto.failure(ErrorMapping.get("140000"));
        goblinRedisUtils.expire(lockKey, 30);
        boolean resultFlg = goblinUserAssetConfigService.initSafePasswd(passwd, currentUid);
        goblinRedisUtils.del(lockKey);
        return resultFlg ? ResponseDto.success() : ResponseDto.failure(ErrorMapping.get("140002"));
    }

    private ResponseDto<Object> validVerificationCode(String code, String mobile) {
        if (!LnsEnum.ENV.prod.name().equals(env.getProperty(CurrentUtil.CK_ENV_ACTIVE))) {
            if (CurrentUtil.GRAY_LOGIN_SMS_CODE.equals(code)) return ResponseDto.success();
        }
        String cacheCode = goblinRedisUtils.getSmsCodeByMobile(mobile);
        if (StringUtils.isEmpty(cacheCode)) {
            return ResponseDto.failure(ErrorMapping.get("140018"));
        }
        if (!cacheCode.equals(code)) {
            return ResponseDto.failure(ErrorMapping.get("140019"));
        }
        return ResponseDto.success();
    }
}
