package cn.com.countrygarden.bi.main.service.message.impl;

import cn.com.countrygarden.bi.main.dto.message.SmsParamBO;
import cn.com.countrygarden.bi.main.service.message.SmsTemplateSender;
import cn.com.countrygarden.bi.main.sms.client.SyncApiClientSmsService;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.cloudapi.sdk.core.model.ApiResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.rholder.retry.*;
import com.google.common.base.Predicates;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@Service
public class SmsTemplateSenderImpl implements SmsTemplateSender {
    private static final Logger LOG  = LoggerFactory.getLogger(SmsTemplateSenderImpl.class);

    @Autowired
    private SyncApiClientSmsService syncApiClientSmsService;

    public static final int REPLACE_SEND_MSG_COUNT=3;
    /**
     * 重试器
     */
    private Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
            .retryIfResult(Predicates.<Boolean>isNull())
            .retryIfExceptionOfType(Exception.class)
            .retryIfRuntimeException()
            .withStopStrategy(StopStrategies.stopAfterAttempt(REPLACE_SEND_MSG_COUNT))
            .withWaitStrategy(WaitStrategies.fixedWait(800, TimeUnit.MILLISECONDS))
            .withRetryListener(new RetryListener() {
                @Override
                public <V> void onRetry(Attempt<V> attempt) {
                    if (attempt.hasException()&&attempt.getAttemptNumber()==REPLACE_SEND_MSG_COUNT){
                        attempt.getExceptionCause().printStackTrace();
                    }
                }
            })
            .build();


    @Override
    public void sendBatchSms(String templateCode, List<SmsParamBO> bos)  {
        for (SmsParamBO bo : bos) {
            sendSms(bo);
        }
    }

    @Override
    public void sendSms(SmsParamBO bo)  {
        String modelText="【碧桂园物业】 验证码：{0}，180秒内输入有效。提示:请勿泄露验证码给他人。";
        String[] array = ArrayUtil.toArray(bo.getTemplateParams(), String.class);
        String format = MessageFormat.format(modelText, array);
        try {
            retryer.call(()->{
                sendSingleSms(format, bo.getPhone());
                return true;
            });
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (RetryException e) {
            e.printStackTrace();
        }
        ;
    }

    /**
     * 发送单条短信
     *
     * @param smsContent
     * @param phone
     */
    public void sendSingleSms(String smsContent, String phone) {
        ApiResponse smsResponse = syncApiClientSmsService.postSms(null, null, null, null, null, null,
                phone, smsContent, "verify", "eng0phahhoo9Oof2");
        try {
            validateSmsState(smsResponse, phone);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new RuntimeException("短信发送失败，转换异常");
        }
        LOG.info("[{}]短信发送成功！内容：[{}]", phone, smsContent);
    }

    /**
     * 联通发送单条短信
     *
     * @param smsContent
     * @param phone
     */
    public void sendSingleSms2(String smsContent, String phone) {
//       // ApiResponse smsResponse = syncApiClientSmsService.postSms2(null, null, null, null, null, null,
//                phone, "10","[\"5833\",\"10\"]", "verify", "n57HFtrnCqbGRXFl");
////        try {
////           // validateSmsState(smsResponse, phone);
////        } catch (UnsupportedEncodingException e) {
////            e.printStackTrace();
////            throw new RuntimeException("短信发送失败，转换异常");
////        }
//        LOG.info("[{}]短信发送成功！内容：[{}]", phone, smsContent);
    }
    /**
     * 校验短信发送结果
     *
     * @param smsResponse
     * @param phone
     */
    private void validateSmsState(ApiResponse smsResponse, String phone) throws UnsupportedEncodingException {
        // 获得发送的数据
        try {
            String responseStr = new String(smsResponse.getBody(), "utf-8");
            JSONObject jsonObject = JSON.parseObject(responseStr);
            JSONObject jsonData = JSON.parseObject(jsonObject.getString("data"));
            smsResponse = syncApiClientSmsService.getSms(null, null, null, null, null, null,
                    jsonData.getInteger("id"));
            responseStr = new String(smsResponse.getBody(), "utf-8");
            // 通过发送数据其中的id得到信息发送的状态
            jsonObject = JSON.parseObject(responseStr.toString());
            jsonData = JSON.parseObject(jsonObject.getString("data"));
            LOG.error(responseStr.toString());
            // 根据statusCode判断是否发送成功
            if (!jsonData.getString("statusCode").equals("0") && !jsonData.getString("statusCode").equals("200")
                    && !jsonData.getString("statusCode").equals("DELIVRD") && !jsonData.getString("statusCode").equals("")) {
                throw new RuntimeException("获取短信状态发送异常！");
            }
        }catch(Exception e){
            e.printStackTrace();
            return;
        }
    }
}
