package com.liquidnet.common.sms.processor;

import com.alibaba.fastjson.JSON;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.*;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Slf4j
@Component
public class SmsProcessor {
    /* ================================================================== | aliyun dysms */
    @Value("${liquidnet.aliyun.dysms.accessKeyId}")
    private String aliyunDysmsAccessKeyId;
    @Value("${liquidnet.aliyun.dysms.accessKeySecret}")
    private String aliyunDysmsAccessKeySecret;
    private static Client aliyunDysmsAcsClient;
    /* ================================================================== |  */

    @PostConstruct
    private void init() throws Exception {
        Config config = new Config()
                .setAccessKeyId(aliyunDysmsAccessKeyId)
                .setAccessKeySecret(aliyunDysmsAccessKeySecret)
                .setEndpoint("dysmsapi.aliyuncs.com");
        aliyunDysmsAcsClient = new Client(config);
    }

    /* ================================================================== | aliyun dysms */

    /**
     * AliyunDysms.send
     * - link: https://help.aliyun.com/document_detail/101414.htm?spm=a2c4g.11186623.2.8.302f56958lnARh#t83759.html
     *
     * @param phoneNumber   接收短信的手机号码(国内短信:+/+86/0086/86或无任何前缀的11位手机号码;国际/港澳台消息:国际区号+号码)
     * @param signName      短信签名名称
     * @param templateCode  短信模板ID
     * @param templateParam 短信模板变量对应的实际值，JSON格式(建议使用com.liquidnet.commons.lang.util.JsonUtils.OM().createObjectNode())
     * @return SendSmsResponse
     */
    private SendSmsResponse aliyunDysmsSend(String phoneNumber, String signName, String templateCode, String templateParam) throws Exception {
        SendSmsRequest smsRequest = new SendSmsRequest()
                .setPhoneNumbers(phoneNumber)
                .setSignName(signName)
                .setTemplateCode(templateCode)
                .setTemplateParam(templateParam);
            return aliyunDysmsAcsClient.sendSms(smsRequest);
    }

    /**
     * AliyunDysms.sendBatch
     * - note: 在一次请求中，最多可以向100个手机号码分别发送短信(整体请求量限定在128k以内)
     * - link: https://help.aliyun.com/document_detail/102364.html?spm=a2c4g.11186623.6.633.3d855ecb5j4CR8
     *
     * @param phoneNumberJson   接收短信的手机号码(国内短信:+/+86/0086/86或无任何前缀的11位手机号码;国际/港澳台消息:国际区号+号码)，JSON数组格式(建议使用com.liquidnet.commons.lang.util.JsonUtils.OM().createArrayNode())
     * @param signNameJson      短信签名名称，JSON数组格式(建议使用com.liquidnet.commons.lang.util.JsonUtils.OM().createArrayNode())
     * @param templateCode      短信模板CODE
     * @param templateParamJson 短信模板变量对应的实际值，JSON格式(建议使用com.liquidnet.commons.lang.util.JsonUtils.OM().createObjectNode())
     * @return SendBatchSmsResponse
     */
    private SendBatchSmsResponse aliyunDysmsSendBatch(String phoneNumberJson, String signNameJson, String templateCode, String templateParamJson) throws Exception {
        SendBatchSmsRequest batchSmsRequest = new SendBatchSmsRequest()
                .setPhoneNumberJson(phoneNumberJson)
                .setSignNameJson(signNameJson)
                .setTemplateCode(templateCode)
                .setTemplateParamJson(templateParamJson);
        return aliyunDysmsAcsClient.sendBatchSms(batchSmsRequest);
    }

    /* ================================================================== | sender */

    public boolean send(String phoneNumber, String signName, String templateCode, String templateParam) {
        try {
            SendSmsResponse smsResponse = this.aliyunDysmsSend(phoneNumber, signName, templateCode, templateParam);

            SendSmsResponseBody smsResponseBody = smsResponse.getBody();

            boolean isSucc = null != smsResponseBody && "OK".equalsIgnoreCase(smsResponseBody.getCode());

            if (!isSucc) {
                log.warn("###发送短信API处理失败[{}]", JSON.toJSON(smsResponse));
            }

            return isSucc;
        } catch (Exception e) {
            log.error("发送短信API处理异常", e);
        }
        return false;
    }

    /* ================================================================== |  */
}
