package com.cnooc.expert.auth.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.cnooc.expert.common.constant.TokenConstants;
import com.cnooc.expert.common.utils.JsonUtils;
import com.cnooc.expert.common.utils.SmsHttpUtil;
import com.cnooc.expert.common.utils.SmsUtil;
import com.cnooc.expert.system.entity.vo.SmsConfig;
import com.cnooc.expert.auth.service.SmsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Service
@AllArgsConstructor
@Slf4j
public class SmsServiceImpl implements SmsService {
//    public static final String SMS_CODE_CONTENT = "您的验证码是：%s（有效期为2分钟），请勿泄露给他人，如非本人操作，请忽略此消息。";
    public static final String SMS_LOGIN_CODE_CONTENT = "【专家小程序】您正在登录专家小程序，请确认是本人操作。验证码为：%s，10分钟内有效，请勿告知他人。‌";
    public static final String SMS_CHANGEPWD_CODE_CONTENT = "【专家小程序】您正在修改登录密码，请确认是本人操作。验证码为：%s，10分钟内有效，请勿告知他人。";
    @Autowired
    private StringRedisTemplate redisTemplate;
    private final SmsConfig smsConfig;

    /**
     * 校验短信验证码
     *
     * @param phone 手机号
     * @param code  用户输入的验证码
     * @return 是否校验通过
     */
    @Override
    public boolean verifySmsCode(String phone, String code) {
        String key = "sms:code:" + phone;
        String storedCode = redisTemplate.opsForValue().get(key);
        if (storedCode != null && storedCode.equals(code)) {
            // 验证码正确，删除缓存中的验证码
            redisTemplate.delete(key);
            return true;
        }
        return false;
    }

    /**
     * 发送短信验证码（可选方法）
     *
     * @param phone 手机号
     * @return 是否发送成功
     */
    public boolean sendSmsCode(String phone,int smsTemplateType) {
        // 生成6位验证码
        //String code = RandomUtil.randomNumbers(6);
        String code = "666666";
        String key = "sms:code:" + phone;
        redisTemplate.opsForValue().set(key, code, 10,TimeUnit.MINUTES);// 存入 Redis，设置过期时间为10分钟
        //String storedCode = (String)redisTemplate.opsForValue().get(key);
        System.out.println("发送短信验证码：" + phone + " -> " + code);// 模拟发送短信，实际应调用第三方短信服务
        return true;
        //return sendGlySmsCode(phone,smsTemplateType);
    }

    @Override
    public boolean sendGlySmsCode(String phone,int smsTemplateType) {
        // 生成验证码并构建缓存键
        String code = SmsUtil.generateVerificationCode();
        System.out.println("发送短信验证码：" + phone + " -> " + code);
        String key = SmsUtil.buildCacheKey(phone);

        try {
            // 构建短信内容
            String content = String.format(SMS_LOGIN_CODE_CONTENT,  code);
            if(smsTemplateType == 2){
                //修改密码
                content = String.format(SMS_CHANGEPWD_CODE_CONTENT,  code);
            }
            System.out.println("发送短信验证码：" + phone + " -> " + code);
            log.info("云MAS业务平台 发送手机号: {}，短信验证码：{}", phone, code);
            System.out.println("云MAS业务平台 短信内容: " + content);

            boolean result = sendGlySmsContent(phone, content, code, smsTemplateType);
            if(result){
                redisTemplate.opsForValue().set(key, code, 10 * 60); // 存入 Redis，设置过期时间为10分钟
            }
            return result;
        } catch (Exception e) {
            log.error("云MAS业务平台短信验证码发送失败: {}", e.getMessage(), e);
            return false;
        }

    }

    @Override
    public boolean sendGlySmsContent(String phone, String content, String code, int smsTemplateType) {
        try {

            log.info("管理云业务平台 短信内容: {}", content);
            log.info("管理云业务平台 发送手机号: {}，短信内容：{}", phone, content);

            // 构建请求体并转换为 Base64 编码的 JSON 字符串
            String encodedJson = SmsUtil.encodeRequestBodyToBase64(buildRequestBody(phone, content, code,smsTemplateType));
            System.out.println("管理云业务平台 请求体Base64编码: " + encodedJson);
            log.info("管理云业务平台 请求体Base64编码: {}", encodedJson);

            // 设置请求头并发送 POST 请求
            String response = SmsHttpUtil.sendPostRequest(smsConfig.getApiUrl(), encodedJson,smsConfig.getAppCode());
            System.out.println("管理云业务平台 响应体: " + response);
            log.info("管理云业务平台 响应体response: {}", response);

            // 解析响应并处理结果
            return SmsUtil.handleResponse(response);

        } catch (Exception e) {
            log.error("管理云业务平台短信发送失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public void asyncSendGlySmsContent(String phone, String content, String code, int smsTemplateType){
        CompletableFuture.runAsync(() -> {
                    try {
                        System.out.println("======开始发送短信======");
                        sendGlySmsContent(phone, content,code,smsTemplateType);
                        System.out.println("======发送短信结束======");
                    } catch (Exception e) {
                        log.error("asyncSendMasSmsContent异步执行失败", e);
                    }
                }
        );
    }

    /**
     * 构建请求体
     */
    private Map<String, String> buildRequestBody(String phone, String content, String code, int smsTemplateType) {
        Map<String, Object> sms = new HashMap<>();
        Map<String, String> dataItems = new HashMap<>();
        dataItems.put("code", code);
        dataItems.put("time", "10");
        sms.put("template", smsConfig.getLoginTemplate());
        if(smsTemplateType == 2){
            sms.put("template", smsConfig.getChangePwdTemplate());
        }
        sms.put("dataItems", JsonUtils.toJsonString((dataItems)));
        sms.put("type", "1");
        String[] recvNumArray = new String[1];
        recvNumArray[0] = phone;
        sms.put("recvNum", recvNumArray);
        //sms.put("content", content);
        sms.put("sendNum", "");
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("priority", "high");
        requestBody.put("label", "消息标签");
        requestBody.put("sms", JsonUtils.toJsonString(sms));
        return requestBody;
    }



}
