package cn.iocoder.yudao.framework.sms.core.client.impl.yCloud;

import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.json.core.KeyValue;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.sms.YCloudWhatsappHttp;
import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.yudao.framework.sms.core.client.dto.*;
import cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient;
import cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum;
import cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
import cn.iocoder.yudao.framework.sms.core.enums.YCloudReceiveStatusEnum;
import cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * ycloud客户端
 *
 * @author Jayden
 * @date 2024/11/7
 */
@Slf4j
public class YCloudSmsClient extends AbstractSmsClient {

    // 创建HTTP客户端实例，用于发送短信
    private final YCloudWhatsappHttp yCloudWhatsappHttp = new YCloudWhatsappHttp();

    public YCloudSmsClient(SmsChannelProperties properties) {
        super(properties, new YCloudSmsCodeMapping());
        Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
        Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
    }

    @Override
    protected void doInit() {

    }

    @Override
    protected SmsCommonResult<SmsSendRespDTO> doSendSms(Long sendLogId, String mobile, String apiTemplateId, List<KeyValue<String, Object>> templateParams) {
        return null;
    }

    /**
     * 发送短信V2版本
     * 该方法用于发送短信，根据提供的日志ID、手机号码、短信模板和模板参数进行短信发送
     * 主要逻辑包括处理模板参数、调用HTTP工具发送短信以及解析响应结果
     *
     * @param logId          日志ID，用于追踪和记录发送短信的日志
     * @param mobile         手机号码，指定短信接收者的电话号码
     * @param smsTemplateDTO 短信模板数据传输对象，包含短信模板的相关信息
     * @param templateParams 模板参数列表，包含短信模板中的变量和对应的值
     * @return 返回一个通用的结果对象，包含短信发送的相关信息和结果状态
     */
    @Override
    public SmsCommonResult<SmsSendRespDTO> sendSmsV2(Long logId, String mobile, SmsTemplateDTO smsTemplateDTO, List<KeyValue<String, Object>> templateParams) {
        // 默认验证码为空字符串
        String code = "";
        // 如果模板参数不为空，则遍历模板参数以获取验证码
        if (templateParams != null) {
            for (KeyValue<String, Object> entry : templateParams) {
                code = (String) entry.getValue();
            }
        }

        // 发送短信并获取响应
        Response response = yCloudWhatsappHttp.postWhatsapp(yCloudWhatsappHttp.setHeader(properties.getApiSecret()),
                yCloudWhatsappHttp.setParams(code, smsTemplateDTO.getApiTemplateId(), smsTemplateDTO.getLanguage(), mobile));

        // 解析结果
        Map<?, ?> responseObj = JSON.parseObject(response.getBody(), Map.class);
        // 构建短信发送结果对象
        SmsCommonResult<SmsSendRespDTO> smsCommonResult = SmsCommonResult.build(String.valueOf(responseObj.get("status")), String.valueOf(responseObj.get("status")), String.valueOf(responseObj.get("id")), null, codeMapping);
        // 设置短信发送结果的详细信息
        smsCommonResult.setData(new SmsSendRespDTO().setSerialNo(String.valueOf(responseObj.get("id"))));
        // 返回短信发送结果
        return smsCommonResult;
    }

    /**
     * 获取短信接收状态
     * 本方法通过调用第三方API来获取短信的实际接收状态，并更新短信日志DTO中的相关信息
     *
     * @param smsLogDO 短信日志DTO，包含需要查询接收状态的短信的相关信息
     * @return 返回更新了接收状态和接收时间的短信日志DTO
     */
    @Override
    public SmsLogDTO getReceiveStatus(SmsLogDTO smsLogDO) {
        // 初始化短信日志DTO，并默认设置接收状态为未接收到
        SmsLogDTO smsLogDTO = new SmsLogDTO();
        smsLogDTO.setReceiveStatus(ReceiveStatusEnum.Receive_STATUS_20.getValue());

        try {
            // 发送短信并获取响应
            Response response = yCloudWhatsappHttp.getReceiveStatus(yCloudWhatsappHttp.setHeader(properties.getApiSecret()), smsLogDO.getApiSerialNo());
            // 解析响应内容为对象，以便后续处理
            SmsReceiveStatus smsReceiveStatus = JSON.parseObject(response.getBody(), SmsReceiveStatus.class);
            // 获取短信状态
            if (smsReceiveStatus == null) {
                return smsLogDTO;
            }
            String status = smsReceiveStatus.getStatus();
            // 如果短信状态为已送达或已读取，则进一步处理
            if (YCloudReceiveStatusEnum.DELIVERED.getCode().equals(status) || YCloudReceiveStatusEnum.READ.getCode().equals(status)) {
                // 获取送达时间
                String deliverTime = smsReceiveStatus.getDeliverTime();
                // 解析并转换送达时间为本地时间
                Date localDate = DateUtils.parseAndConvertToLocalDate(deliverTime);
                // 更新短信日志DTO的接收时间和接收状态
                smsLogDTO.setReceiveTime(localDate);
                smsLogDTO.setReceiveStatus(ReceiveStatusEnum.Receive_STATUS_10.getValue());
            }
        } catch (Exception e) {
            // 记录异常信息
            log.error("Error occurred while getting receive status: ", e);
            // 保持默认的接收状态为未接收到
            smsLogDTO.setReceiveStatus(ReceiveStatusEnum.Receive_STATUS_20.getValue());
        }
        // 返回更新后的短信日志DTO
        return smsLogDTO;
    }

    @Override
    protected List<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) {
        throw new UnsupportedOperationException("无回调");
    }

    @Override
    protected SmsCommonResult<SmsTemplateRespDTO> doGetSmsTemplate(String apiTemplateId) {
        SmsTemplateRespDTO data = new SmsTemplateRespDTO().setId(apiTemplateId).setContent("")
                .setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus()).setAuditReason("");
        return SmsCommonResult.build("accepted", "accepted", null, data, codeMapping);
    }

    /**
     * 短信接收状态
     * <p>
     *
     * @author 捷道源码
     */
    @Data
    public static class SmsReceiveStatus {
        /**
         * status
         */
        @JsonProperty("status")
        private String status;
        /**
         * reference
         */
        @JsonProperty("deliverTime")
        private String deliverTime;
    }
}
