package com.philisense.www.api.processor.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.philisense.www.api.SmsCodeSender;
import com.philisense.www.api.generator.impl.SmsCodeGenerator;
import com.philisense.www.api.processor.AbstractVcodeProcessor;
import com.philisense.www.consts.ErrorConst;
import com.philisense.www.dto.SmsCode;
import com.philisense.www.enums.VcodeType;
import com.philisense.www.exception.UtilsException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Component
public class SmsCodeProcessor extends AbstractVcodeProcessor<SmsCode> {
    private static final Logger log = LoggerFactory.getLogger(SmsCodeProcessor.class);

    @Autowired
    private SmsCodeSender smsCodeSender;

    @Autowired
    private ObjectMapper objectMapper;

    public SmsCodeProcessor(SmsCodeGenerator vcodeGenerator) {
        super(VcodeType.SMS_CODE, vcodeGenerator);
    }

    @Override
    protected void preValidate(ServletWebRequest request) throws UtilsException {
        String code = request.getParameter("smsCode");
        if (StringUtils.isBlank(code)) {
            throw new UtilsException("smsCode不能为空", ErrorConst.ERR_CODE);
        }
    }

    @Override
    protected void validate(ServletWebRequest request, Object savedValue) throws UtilsException {
        String code = request.getParameter("smsCode");
        /**
         * todo 这里还可以加上短信校验失败次数的逻辑，比如发送超过了三次。直接抛出”日发送次数已用完“的异常
         */
        if (!StringUtils.equals(code, (String) savedValue)) {
            throw new UtilsException("短信验证码校验失败", ErrorConst.ERR_CODE);
        }
    }

    @Override
    protected void send(ServletWebRequest request, SmsCode smsCode) throws Exception {
        String mobile = request.getParameter("mobile");
        String required = request.getParameter("required");
        // 某些情况下发送短信验证码需要确保手机号存在于系统中，比如找回密码，
        // 要校验手机号存在，只要前端传一个required=true
        boolean mobileRequired = StringUtils.isNotBlank(required) && Boolean.parseBoolean(required);
        smsCodeSender.send(mobile, smsCode.getCode(), mobileRequired);
        log.info("已发送的短信验证码：{}", smsCode.getCode());

        HttpServletResponse response = request.getResponse();
        Map<String, Object> result = new HashMap();
        result.put("success", true);
        result.put("message", "生成成功！");
        Map<String, Object> data = new HashMap<>();
        data.put("vcodeKey", smsCode.getKey());
        result.put("data", data);
        response.getWriter().write(objectMapper.writeValueAsString(result));
    }
}