package com.liquidnet.service.goblin.controller;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.common.sms.constant.SmsEnum;
import com.liquidnet.common.sms.processor.SmsProcessor;
import com.liquidnet.commons.lang.constant.LnsEnum;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
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.RandomStringUtils;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.util.Arrays;

@ApiSupport(order = 141000)
@Api(tags = "商城:短信API")
@Slf4j
@Validated
@RestController
@RequestMapping("sms")
public class GoblinSmsController {
    @Autowired
    Environment env;
    @Autowired
    SmsProcessor smsProcessor;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "发送验证码", notes = "验证码10分钟内有效，发送频率最短1分钟")
    @PostMapping(value = {"code/send"})
    public ResponseDto<Object> sendVerificationCode() {
        String mobile = (String) CurrentUtil.getTokenClaims().get(CurrentUtil.TOKEN_MOBILE);
        String smsCode = goblinRedisUtils.getSmsCodeByMobile(mobile);
        if (StringUtils.isEmpty(smsCode)) {
            smsCode = RandomStringUtils.randomNumeric(6);
        } else {
            Long ttl = goblinRedisUtils.ttlSmsCodeByMobile(mobile);
            if (null != ttl && ttl != -2 && ttl > 540) {
                return ResponseDto.failure(ErrorMapping.get("140000"));
            }
        }
        if (LnsEnum.ENV.prod.name().equals(env.getProperty(CurrentUtil.CK_ENV_ACTIVE))) {
//        if (Arrays.asList(LnsEnum.ENV.prod.name(), LnsEnum.ENV.test.name()).contains(env.getProperty(CurrentUtil.CK_ENV_ACTIVE))) {
            ObjectNode msgNode = JsonUtils.OM().createObjectNode();
            msgNode.put("code", smsCode);
            boolean sendRst = smsProcessor.send(mobile, SmsEnum.ADSignName.M02.getVal(), SmsEnum.ADTemplate.SMS_221055862.name(), msgNode.toString());
            if (sendRst) {
                goblinRedisUtils.setSmsCodeByMobile(mobile, smsCode);

                return ResponseDto.success();
            }
        } else {
            goblinRedisUtils.setSmsCodeByMobile(mobile, CurrentUtil.GRAY_LOGIN_SMS_CODE);
            return ResponseDto.success();
        }
        return ResponseDto.failure(ErrorMapping.get("140017"));
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "校验验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "code", value = "验证码"),
    })
    @PostMapping(value = {"code/check"})
    public ResponseDto<Object> checkVerificationCode(@NotBlank(message = "验证码不能为空") @Pattern(regexp = "\\d{6}", message = "验证码格式有误") @RequestParam String code) {
        String mobile = (String) CurrentUtil.getTokenClaims().get(CurrentUtil.TOKEN_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 smsCodeByMobile = goblinRedisUtils.getSmsCodeByMobile(mobile);
        if (null == smsCodeByMobile) return ResponseDto.failure(ErrorMapping.get("140018"));

        return smsCodeByMobile.equals(code) ? ResponseDto.success() : ResponseDto.failure(ErrorMapping.get("140019"));
    }
}
