package com.njcn.msgpush.module.push.client.sender.impl;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.njcn.msgpush.module.push.client.sender.Sender;
import com.njcn.msgpush.module.push.client.sender.SmsSender;
import com.njcn.msgpush.module.push.client.setting.impl.AliYunMailSetting;
import com.njcn.msgpush.module.push.constant.MessageStatusConstant;
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
import com.njcn.msgpush.module.push.enums.RetryStrategyEnum;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import static com.aliyun.teautil.Common.toJSONString;

/**
 * @author caozehui
 * @data 2026-02-11
 */
@Slf4j
public class AliyunSmsSender implements SmsSender {

    public static final String OK = "OK";

    private Sender sender;

    private Client smsClient;

    public AliyunSmsSender(AliYunMailSetting aliYunSmsSetting, Sender sender) {
        this.sender = sender;
        if (ObjectUtil.isNotNull(aliYunSmsSetting)) {
            Config config = new Config()
                    .setAccessKeyId(aliYunSmsSetting.getAccessKeyId())
                    .setAccessKeySecret(aliYunSmsSetting.getAccessKeySecret())
                    .setRegionId(aliYunSmsSetting.getRegionId())
                    .setEndpoint(aliYunSmsSetting.getEndpoint());

            try {
                this.smsClient = new Client(config);
            } catch (Exception e) {
                log.error("阿里云-短信服务初始化失败，请检查配置信息");
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public boolean sendSms(MessageRecordDO message) {
        Future<Boolean> future = this.sender.MSG_PUSH_THREAD_POOL_EXECUTOR.submit(() -> {
            message.setStatus(MessageStatusConstant.SENDING);
            RuntimeOptions runtimeOptions = new RuntimeOptions();
            // 设置自动重试，默认是不开启的。重试次数默认是3次
            runtimeOptions.autoretry = true;
            SendSmsRequest request = new SendSmsRequest()
                    .setPhoneNumbers(message.getReceiver()) //手机号码之间以半角逗号（,）分隔。上限为 1000 个手机号码。
                    .setSignName(message.getTitle())
                    .setTemplateCode(message.getTemplateCode())
                    .setTemplateParam(message.getTemplateParams());
            try {
                LocalDateTime now = LocalDateTime.now();
                long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
                message.setSendTime(now);
                SendSmsResponse response = this.smsClient.sendSmsWithOptions(request, runtimeOptions);
                LocalDateTime end = LocalDateTime.now();
                message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
                System.out.println(toJSONString(response));
                if (OK.equals(response.body.code)) {
                    return true;
                } else {
                    message.setErrorCode(response.body.code);
                    message.setErrorMsg(response.body.message);
                    this.sender.messageRetryQueueService.addRetryMessage(message, RetryStrategyEnum.EXPONENTIAL_BACKOFF);
                    this.sender.channelProviderConfigService.failureUpdate(message.getProviderType(), message.getChannel());
                    return false;
                }
            } catch (Exception e) {
                log.error("阿里云-短信服务发送失败");
                throw new RuntimeException(e);
            }
        });
        Boolean b = null;
        try {
            b = future.get(3, TimeUnit.SECONDS);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return b;
    }

    @Override
    public boolean sendBatchSms(List<MessageRecordDO> messageIdList) {
        boolean res = true;
        for (MessageRecordDO message : messageIdList) {
            res &= this.sendSms(message);
        }
        return res;
    }
}
