
package org.springblade.modules.resource.service;

import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.sms.SmsTemplate;
import org.springblade.core.sms.enums.SmsEnum;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.resource.pojo.entity.Sms;
import org.springblade.modules.resource.rule.context.SmsContext;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * SMS流程编排服务 (替代 LiteFlow smsChain)
 *
 * 原 LiteFlow 流程:
 * THEN(
 *   preSmsRule,
 *   SWITCH(smsBuildRule).TO(aliSmsRule, qiniuSmsRule, tencentSmsRule, yunpianSmsRule, cacheSmsRule),
 *   finallySmsRule
 * )
 *
 * @author Chill
 */
@Service
public class SmsChainService {

	/**
	 * 执行 SMS 构建流程
	 *
	 * @param tenantId   租户ID
	 * @param smsContext SMS上下文
	 * @return SmsTemplate
	 */
	public SmsTemplate execute(String tenantId, SmsContext smsContext) {
		try {
			// 1. preSmsRule - 前置处理
			preSmsProcess(tenantId, smsContext);

			// 2. SWITCH(smsBuildRule) - 根据类型和缓存状态构建
			smsBuildProcess(tenantId, smsContext);

			// 3. finallySmsRule - 后置处理
			finallySmsProcess(tenantId, smsContext);

			return smsContext.getSmsTemplate();
		} catch (Exception e) {
			throw new ServiceException("未获取到对应的短信配置");
		}
	}

	/**
	 * preSmsRule - SMS构建前置处理
	 */
	private void preSmsProcess(String tenantId, SmsContext smsContext) {
		Map<String, Sms> smsPool = smsContext.getSmsPool();
		Map<String, SmsTemplate> templatePool = smsContext.getTemplatePool();
		Sms sms = smsContext.getSms();
		Sms smsCached = smsPool.get(tenantId);
		SmsTemplate template = templatePool.get(tenantId);

		// 若为空或者不一致,则重新加载
		if (Func.hasEmpty(template, smsCached)
			|| !sms.getTemplateId().equals(smsCached.getTemplateId())
			|| !sms.getAccessKey().equals(smsCached.getAccessKey())) {
			smsContext.setIsCached(Boolean.FALSE);
		} else {
			smsContext.setIsCached(Boolean.TRUE);
		}
	}

	/**
	 * smsBuildRule - 根据 SMS 类型构建对应的 SmsTemplate
	 */
	private void smsBuildProcess(String tenantId, SmsContext smsContext) {
		Sms sms = smsContext.getSms();

		// 如果有缓存,直接返回
		if (smsContext.getIsCached()) {
			// cacheSmsRule - 从缓存读取,在 finallySmsProcess 中处理
			return;
		}

		// 构建 SmsProperties
		org.springblade.core.sms.props.SmsProperties smsProperties = new org.springblade.core.sms.props.SmsProperties();
		smsProperties.setRegionId(sms.getRegionId());
		smsProperties.setTemplateId(sms.getTemplateId());
		smsProperties.setAccessKey(sms.getAccessKey());
		smsProperties.setSecretKey(sms.getSecretKey());
		smsProperties.setSignName(sms.getSignName());

		SmsTemplate smsTemplate;

		if (sms.getCategory() == SmsEnum.YUNPIAN.getCategory()) {
			// yunpianSmsRule - 创建 YunpianClient 并构建模板
			com.yunpian.sdk.YunpianClient client = new com.yunpian.sdk.YunpianClient(sms.getAccessKey()).init();
			smsTemplate = new org.springblade.core.sms.YunpianSmsTemplate(smsProperties, client, smsContext.getBladeRedis());
		} else if (sms.getCategory() == SmsEnum.QINIU.getCategory()) {
			// qiniuSmsRule - 创建 QiNiu Auth 和 SmsManager 并构建模板
			com.qiniu.util.Auth auth = com.qiniu.util.Auth.create(sms.getAccessKey(), sms.getSecretKey());
			com.qiniu.sms.SmsManager smsManager = new com.qiniu.sms.SmsManager(auth);
			smsTemplate = new org.springblade.core.sms.QiniuSmsTemplate(smsProperties, smsManager, smsContext.getBladeRedis());
		} else if (sms.getCategory() == SmsEnum.ALI.getCategory()) {
			// aliSmsRule - 创建 AliYun IAcsClient 并构建模板
			com.aliyuncs.profile.IClientProfile profile = com.aliyuncs.profile.DefaultProfile.getProfile(
				sms.getRegionId(), sms.getAccessKey(), sms.getSecretKey()
			);
			com.aliyuncs.IAcsClient acsClient = new com.aliyuncs.DefaultAcsClient(profile);
			smsTemplate = new org.springblade.core.sms.AliSmsTemplate(smsProperties, acsClient, smsContext.getBladeRedis());
		} else if (sms.getCategory() == SmsEnum.TENCENT.getCategory()) {
			// tencentSmsRule - 创建 Tencent SmsMultiSender 并构建模板
			com.github.qcloudsms.SmsMultiSender smsSender = new com.github.qcloudsms.SmsMultiSender(
				org.springblade.core.tool.utils.Func.toInt(sms.getAccessKey()), sms.getSecretKey()
			);
			smsTemplate = new org.springblade.core.sms.TencentSmsTemplate(smsProperties, smsSender, smsContext.getBladeRedis());
		} else {
			throw new ServiceException("未找到SMS配置");
		}

		smsContext.setSmsTemplate(smsTemplate);
	}

	/**
	 * finallySmsRule - SMS构建后置处理
	 */
	private void finallySmsProcess(String tenantId, SmsContext smsContext) {
		Map<String, Sms> smsPool = smsContext.getSmsPool();
		Map<String, SmsTemplate> templatePool = smsContext.getTemplatePool();

		if (smsContext.getIsCached()) {
			SmsTemplate template = templatePool.get(tenantId);
			smsContext.setSmsTemplate(template);
		} else {
			Sms sms = smsContext.getSms();
			SmsTemplate template = smsContext.getSmsTemplate();
			if (Func.hasEmpty(template, sms)) {
				throw new ServiceException("SMS接口读取失败!");
			} else {
				templatePool.put(tenantId, template);
				smsPool.put(tenantId, sms);
			}
		}
	}
}
