package com.backendsys.modules.sms.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.backendsys.exception.CustException;
import com.backendsys.modules.common.config.redis.utils.RedisUtil;
import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
import com.backendsys.modules.sdk.tencentcloud.sms.service.TencentSmsService;
import com.backendsys.modules.sms.dao.SmsDao;
import com.backendsys.modules.sms.entity.Sms;
import com.backendsys.utils.response.ResultEnum;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SmsServiceImpl implements com.backendsys.modules.sms.service.SmsService {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private HttpRequestUtil httpRequestUtil;
    @Autowired
    private TencentSmsService tencentSmsService;
    @Autowired
    private SmsDao smsDao;

    // [模板] 通用验证码
    @Value("${tencent.sms.template-id-of-common}")
    private String TEMPLATE_ID_COMMON;

    @Value("${spring.application.name}")
    private String APPLICATION_NAME;

    /**
     * 发送验证码
     */
    @Override
    public Map<String, Object> sendValidCode(Sms sms) throws TencentCloudSDKException {

        String origin = sms.getOrigin();
        String phone = sms.getPhone();
        Integer phoneAreaCode = sms.getPhone_area_code();

        Integer smsExpire = 5;
        Integer smsCode =  RandomUtil.randomInt(100000, 999999);    // 生成一个6位的随机整数 (验证码) (5分钟失效)
        sms.setSms_code(smsCode);

        // -- 腾讯云短信 ------------------------------------------------
        // 模板参数 {1} 验证码, {2} 过期时间(分钟)
        // 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空
        String[] templateParamSet = {String.valueOf(smsCode), String.valueOf(smsExpire)};
        // 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
        // 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号
        String[] phoneNumberSet = {"+" + phoneAreaCode + phone};
        SendSmsResponse sendSmsResponse = tencentSmsService.send(TEMPLATE_ID_COMMON, templateParamSet, phoneNumberSet);
        if (sendSmsResponse != null) {
            SendStatus[] response = sendSmsResponse.getSendStatusSet();
            if (response.length > 0) {
                // for (int i = 0; i < sendStatuses.length; ++i) {
                if (response[0] != null && !response[0].getCode().equals("Ok")) {
                    // String sendStatusStr = JSONUtil.toJsonStr(sendStatuses[0]);
                    if (response.length > 1) {
                        throw new CustException("发送失败", ResultEnum.REMOTE_EXCEPTION.getCode(), response[1]);
                    } else {
                        JSONObject sendStatusesObj = JSONUtil.parseObj(response[0]);
                        System.out.println("sendStatusesObj = " + sendStatusesObj);
                        String message = Convert.toStr(sendStatusesObj.get("Message"));
                        System.out.println("message = " + message);
                        throw new CustException(message, ResultEnum.REMOTE_EXCEPTION.getCode(), message);
                    }
                }
            }
        }
        // ------------------------------------------------------------

        // -- 发送成功 --------------------------------------------------
        // [Redis] 将 来源+手机号码 为标识，将验证码存入缓存
        String originStr = StrUtil.isNotBlank(origin) ? (origin + "-") : "";
        String redisKey = APPLICATION_NAME + "-sms-" + originStr + phone;

        redisUtil.setCacheObject(redisKey, smsCode, smsExpire, TimeUnit.MINUTES);

        // [插入] 新增短信记录
        sms.setIp(httpRequestUtil.getIpAddr());
        sms.setUa(httpRequestUtil.getUa());
        smsDao.insert(sms);

        return Map.of("phone", sms.getPhone());
    }
}
