package com.njcn.msgpush.module.push.client.sender.impl;

import com.alibaba.fastjson.JSON;
import com.njcn.msgpush.module.push.client.sender.SmsSender;
import com.njcn.msgpush.module.push.client.setting.impl.TelecomSmsSetting;
import com.njcn.msgpush.module.push.constant.MessageStatusConstant;
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
import com.njcn.msgpush.module.push.util.RestTemplateUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author caozehui
 * @data 2026-02-11
 */
public class TelecomSmsSender implements SmsSender {
    /**
     * 短信接口地址
     */
    private static final String API_URL = "https://sms.ymeeting.cn/smsv2";
    /**
     * 虚拟接入码
     */
    private static final String ACCESS_CODE = "106905631";
    /**
     * 短信接口内容类型
     */
    private static final String CONTENT_TYPE = "application/json;charset=utf-8";

    private TelecomSmsSetting telecomSmsSetting;

    private RestTemplateUtil restTemplateUtil;

    private final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
            5,
            5,
            1000,
            TimeUnit.MILLISECONDS,
            new java.util.concurrent.ArrayBlockingQueue<>(1000),
            r -> {
                Thread thread = new Thread(r);
                thread.setName("TelecomSmsSender-Pool-" + thread.getId());
                thread.setDaemon(false);
                return thread;
            },
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    private class TelecomSmsResponse {
        private String status;
        private Double balance;
        private List<TelecomSmsMessageRes> list;
    }

    private class TelecomSmsMessageRes {
        //消息ID（用于状态报告匹配）
        private String mid;
        //手机号码
        private String mobile;
        //短信提交错误代码
        private Integer result;
    }


    public TelecomSmsSender(TelecomSmsSetting telecomSmsSetting, RestTemplateUtil restTemplateUtil) {
        this.telecomSmsSetting = telecomSmsSetting;
        this.restTemplateUtil = restTemplateUtil;
    }

    @Override
    public boolean sendSms(MessageRecordDO message) {
        Future<Boolean> future = THREAD_POOL_EXECUTOR.submit(() -> {
            message.setStatus(MessageStatusConstant.SENDING);
            // 构建请求参数
            Map<String, Object> request = new HashMap<>();
            request.put("action", "send");
            request.put("account", telecomSmsSetting.getAccount());
            request.put("password", telecomSmsSetting.getPassword());
            request.put("mobile", message.getReceiver());
            request.put("content", message.getContent());
            request.put("extno", ACCESS_CODE);

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", CONTENT_TYPE);

            LocalDateTime now = LocalDateTime.now();
            long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            message.setSendTime(now);
            // 发送请求
            ResponseEntity<String> response = restTemplateUtil.post(
                    API_URL,
                    request,
                    headers,
                    String.class
            );
            LocalDateTime end = LocalDateTime.now();
            message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
            TelecomSmsResponse telecomSmsResponse = JSON.parseObject(response.getBody(), TelecomSmsResponse.class);

            if (telecomSmsResponse.list.get(0).result == 0) {
                return true;
            } else {
                return false;
            }
        });

        Boolean b = null;
        try {
            b = future.get(3, TimeUnit.SECONDS);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        if (b) {
            message.setStatus(MessageStatusConstant.SUCCESS);
        } else {
            message.setStatus(MessageStatusConstant.FAILED);
        }
        return b;
    }

    @Override
    public boolean sendBatchSms(List<MessageRecordDO> messageList) {
        Map<String, Object> request = new HashMap<>();
        request.put("action", "p2p");
        request.put("account", telecomSmsSetting.getAccount());
        request.put("password", telecomSmsSetting.getPassword());
        Map<String, String> mobileContentKvp = new HashMap<>();
        for (MessageRecordDO message : messageList) {
            mobileContentKvp.put(message.getReceiver(), "【" + message.getTitle() + "】" + message.getContent());
            message.setStatus(MessageStatusConstant.SENDING);
        }
        request.put("mobileContentKvp", JSON.toJSONString(mobileContentKvp));
        request.put("extno", ACCESS_CODE);

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", CONTENT_TYPE);

        LocalDateTime now = LocalDateTime.now();
        long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

        // 发送请求
        ResponseEntity<String> response = restTemplateUtil.post(
                API_URL,
                request,
                headers,
                String.class
        );
        LocalDateTime end = LocalDateTime.now();
        for (MessageRecordDO message : messageList) {
            message.setSendTime(now);
            message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
        }
        TelecomSmsResponse telecomSmsResponse = JSON.parseObject(response.getBody(), TelecomSmsResponse.class);
        boolean res = true;
        for (TelecomSmsMessageRes telecomSmsMessageRes : telecomSmsResponse.list) {
            res &= telecomSmsMessageRes.result == 0;
        }
        return res;
    }
}
