package cn.iocoder.yudao.module.system.framework.sms.util;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendBatchSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendBatchSmsResponse;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
import darabonba.core.client.ClientOverrideConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;


import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Slf4j
@Component
public class AliyunSmsUtils {

    // 阿里云访问密钥配置（实际项目中应从配置文件读取）
    private static final String ACCESS_KEY_ID = "LTAI5t7WBsJukGiEJADJ9THx";
    private static final String ACCESS_KEY_SECRET = "JcTYKH0xLFqHJfAzojZ1NsCdPip0Vv";
    private static final String REGION = "cn-hangzhou";
    private static final String ENDPOINT = "dysmsapi.aliyuncs.com";

    // 超时时间配置（毫秒）
    private static final int TIMEOUT_MS = 10000;

    // 短信客户端
    private static volatile AsyncClient client;


    /**
     * 获取阿里云短信客户端实例
     * 使用双重检查锁定实现单例模式，保证线程安全
     *
     * @return AsyncClient 短信客户端实例
     */
    private static AsyncClient getClient() {
        if (client == null) {
            synchronized (AliyunSmsUtils.class) {
                if (client == null) {
                    try {
                        StaticCredentialProvider provider = StaticCredentialProvider.create(
                                Credential.builder()
                                        .accessKeyId(ACCESS_KEY_ID)
                                        .accessKeySecret(ACCESS_KEY_SECRET)
                                        .build()
                        );

                        client = AsyncClient.builder()
                                .region(REGION)
                                .credentialsProvider(provider)
                                .overrideConfiguration(
                                        ClientOverrideConfiguration.create()
                                                .setEndpointOverride(ENDPOINT)
                                                .setConnectTimeout(Duration.ofSeconds(30))
                                )
                                .build();

                        log.info("阿里云短信客户端初始化成功");
                    } catch (Exception e) {
                        log.error("阿里云短信客户端初始化失败", e);
                        throw new RuntimeException("阿里云短信客户端初始化失败", e);
                    }
                }
            }
        }
        return client;
    }

    /**
     * 发送单条短信
     *
     * @param phoneNumber   接收短信的手机号码
     * @param signName      短信签名
     * @param templateCode  短信模板CODE
     * @param templateParam 短信模板变量对应的实际值，JSON格式
     * @return boolean 发送是否成功
     */
    public static boolean sendSms(String phoneNumber, String signName, String templateCode, String templateParam) {
        log.info("开始发送短信, 手机号:{}, 签名:{}, 模板CODE:{}, 参数:{}", phoneNumber, signName, templateCode, templateParam);

        try {
            // 构建发送短信请求
            SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
                    .phoneNumbers(phoneNumber)
                    .signName(signName)
                    .templateCode(templateCode)
                    .templateParam(templateParam)
                    .build();

            // 发送短信并获取响应
            CompletableFuture<SendSmsResponse> future = getClient().sendSms(sendSmsRequest);
            SendSmsResponse response = future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);

            // 解析响应结果
            String code = response.getBody().getCode();
            String message = response.getBody().getMessage();
            String bizId = response.getBody().getBizId();

            if ("OK".equals(code)) {
                log.info("短信发送成功, 手机号:{}, 业务ID:{}", phoneNumber, bizId);
                return true;
            } else {
                log.error("短信发送失败, 手机号:{}, 错误码:{}, 错误信息:{}, 业务ID:{}", phoneNumber, code, message, bizId);
                return false;
            }
        } catch (TimeoutException e) {
            log.error("短信发送超时, 手机号:{}", phoneNumber, e);
            return false;
        } catch (ExecutionException e) {
            log.error("短信发送执行异常, 手机号:{}", phoneNumber, e.getCause());
            return false;
        } catch (Exception e) {
            log.error("短信发送发生未知异常, 手机号:{}", phoneNumber, e);
            return false;
        }
    }

    /**
     * 批量发送短信
     *
     * @param phoneNumbersJson  接收短信的手机号码JSON数组
     * @param signNamesJson     短信签名JSON数组
     * @param templateCode      短信模板CODE
     * @param templateParamsJson 短信模板变量对应的实际值JSON数组
     * @return boolean 发送是否成功
     */
    public static boolean sendBatchSms(String phoneNumbersJson, String signNamesJson, String templateCode, String templateParamsJson) {
        log.info("开始批量发送短信, 手机号:{}, 签名:{}, 模板CODE:{}, 参数:{}", phoneNumbersJson, signNamesJson, templateCode, templateParamsJson);

        try {
            // 构建批量发送短信请求
            SendBatchSmsRequest sendBatchSmsRequest = SendBatchSmsRequest.builder()
                    .phoneNumberJson(phoneNumbersJson)
                    .signNameJson(signNamesJson)
                    .templateCode(templateCode)
                    .templateParamJson(templateParamsJson)
                    .build();

            // 发送短信并获取响应
            CompletableFuture<SendBatchSmsResponse> future = getClient().sendBatchSms(sendBatchSmsRequest);
            SendBatchSmsResponse response = future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);

            // 解析响应结果
            String code = response.getBody().getCode();
            String message = response.getBody().getMessage();
            String bizId = response.getBody().getBizId();

            if ("OK".equals(code)) {
                log.info("批量短信发送成功, 业务ID:{}", bizId);
                return true;
            } else {
                log.error("批量短信发送失败, 错误码:{}, 错误信息:{}, 业务ID:{}", code, message, bizId);
                return false;
            }
        } catch (TimeoutException e) {
            log.error("批量短信发送超时", e);
            return false;
        } catch (ExecutionException e) {
            log.error("批量短信发送执行异常", e.getCause());
            return false;
        } catch (Exception e) {
            log.error("批量短信发送发生未知异常", e);
            return false;
        }
    }


    /**
     * 关闭短信客户端，释放资源
     */
    public static void close() {
        if (client != null) {
            try {
                client.close();
                client = null;
                log.info("阿里云短信客户端已关闭");
            } catch (Exception e) {
                log.warn("关闭阿里云短信客户端时发生异常", e);
            }
        }
    }

}
