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

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.njcn.msgpush.module.push.client.sender.Sender;
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.constant.MsgPushConstant;
import com.njcn.msgpush.module.push.dal.dataobject.channel.ProviderErrorCodeMappingDO;
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
import lombok.Data;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.alibaba.fastjson.JSON.toJSON;

/**
 * @author caozehui
 * @data 2026-02-11
 */
@Data
public class TelecomSmsSender implements SmsSender {
    /**
     * 短信接口内容类型
     */
    private static final String CONTENT_TYPE = "application/json;charset=utf-8";

    private TelecomSmsSetting telecomSmsSetting;
    private Sender sender;

    private ScheduledExecutorService scheduledExecutorService;

    @Data
    private static class TelecomSmsSendResponse {
        private String status;
        private Double balance;
        private List<TelecomSmsSendDetailRes> list;
    }

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

    @Data
    private static class TelecomSmsSelectResponse {
        private String status;
        private Double balance;
        private List<TelecomSmsSelectDetailRes> list;
    }

    @Data
    private static class TelecomSmsSelectDetailRes {
        private String apmid;
        private String apSubmitTime;
        private String mobile;
        private Integer status;
        private String stat;
        private String deliverTime;
    }

    public TelecomSmsSender(TelecomSmsSetting telecomSmsSetting, Sender sender) {
        this.telecomSmsSetting = telecomSmsSetting;
        this.sender = sender;
    }

    @Override
    public boolean sendSms(MessageRecordDO message) {
        Future<Boolean> future = this.sender.MSG_PUSH_THREAD_POOL_EXECUTOR.submit(() -> {
            message.setStatus(MessageStatusConstant.SENDING);
            // 构建请求参数
            Map<String, Object> request = new HashMap<>();
            boolean isTemplateSend = StrUtil.isNotBlank(message.getTemplateCode());
            request.put("account", telecomSmsSetting.getAccount());
            request.put("password", telecomSmsSetting.getPassword());
            request.put("extno", telecomSmsSetting.getExtno());
            if (isTemplateSend) {
                request.put("action", "templatep2p");
                Map<String, Object> templateJsonMap = new HashMap<>();
                templateJsonMap.put("templateID", message.getTemplateCode());
                JSONObject jsonObject = JSON.parseObject(message.getTemplateParams());
                Map<String, String> variable = new HashMap<>();
                variable.put("mobile", message.getReceiver());
                jsonObject.forEach((key, value) -> variable.put(key, value.toString()));
                templateJsonMap.put("variable", "[" + toJSON(variable) + "]");
                request.put("templateJson", toJSON(templateJsonMap));
            } else {
                request.put("action", "send");
                request.put("mobile", message.getReceiver());
                request.put("content", message.getContent());
            }


            // 设置请求头
            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> response1 = this.sender.restTemplateUtil.post(
                    telecomSmsSetting.getApiUrl(),
                    request,
                    headers,
                    String.class
            );
            LocalDateTime end = LocalDateTime.now();
            message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
            TelecomSmsSendResponse telecomSmsSendResponse = JSON.parseObject(response1.getBody(), TelecomSmsSendResponse.class);

            if (response1.getStatusCode() == HttpStatus.OK) {
                String mid = telecomSmsSendResponse.list.get(0).mid;
                // 定时任务，指定时间间隔后获取下行信息
                this.getDownInfo(mid, message);
                return true;
            } else {
                ProviderErrorCodeMappingDO providerErrorCodeMappingDO = this.sender.providerErrorCodeMappingService.getByProviderErrorCode(message.getProviderType(), message.getChannel(), telecomSmsSendResponse.list.get(0).result + "");
                message.setErrorCode(telecomSmsSendResponse.list.get(0).result + "");
                message.setErrorMsg(providerErrorCodeMappingDO.getOriginalMessage());
                this.sender.messageRetryQueueService.saveOrUpdateRetryMessage(message);
                return false;
            }
        });

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

        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", telecomSmsSetting.getExtno());
//
//        // 设置请求头
//        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 = this.sender.restTemplateUtil.post(
//                telecomSmsSetting.getApiUrl(),
//                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));
//        }
//        TelecomSmsSendResponse telecomSmsSendResponse = JSON.parseObject(response.getBody(), TelecomSmsSendResponse.class);
//        boolean res = true;
//        for (TelecomSmsSendDetailRes telecomSmsSendDetailRes : telecomSmsSendResponse.list) {
//            res &= telecomSmsSendDetailRes.result == 0;
//
//            // 定时任务，指定时间间隔后获取下行信息
//            //this.getDownInfo(telecomSmsSendDetailRes.getMid(), message);
//        }
//        return res;

        boolean res = true;
        for (MessageRecordDO message : messageList) {
            res &= this.sendSms(message);
        }
        return res;
    }

    @Override
    public void queryTemplate(String templateIdentifier) {
        Map<String, Object> request = new HashMap<>();
        request.put("action", "templateSelect");
        request.put("account", telecomSmsSetting.getAccount());
        request.put("password", telecomSmsSetting.getPassword());
        request.put("templateJson", StrUtil.isBlank(templateIdentifier) ? 0 : templateIdentifier);

        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", CONTENT_TYPE);
        ResponseEntity<String> response = this.sender.restTemplateUtil.post(
                telecomSmsSetting.getApiUrl(),
                request,
                headers,
                String.class
        );
        System.out.println(toJSON(response));
    }

    /**
     * 获取下行信息
     *
     * @param mid
     * @param message
     */
    private void getDownInfo(String mid, MessageRecordDO message) {
        if (ObjectUtil.isNull(this.scheduledExecutorService)) {
            this.scheduledExecutorService = Executors.newScheduledThreadPool(1);
        }
        this.scheduledExecutorService.schedule(() -> {
            // 构建请求参数
            Map<String, Object> request = new HashMap<>();
            request.put("action", "select");
            request.put("account", telecomSmsSetting.getAccount());
            request.put("password", telecomSmsSetting.getPassword());
            request.put("date", message.getSendTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            request.put("condition", "APMID");
            request.put("valueList", mid);
//            request.put("condition", "MOBILE");
//            request.put("valueList", message.getReceiver());
            request.remove("mobile");
            request.remove("content");
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", CONTENT_TYPE);
            ResponseEntity<String> response = this.sender.restTemplateUtil.post(
                    telecomSmsSetting.getApiUrl(),
                    request,
                    headers,
                    String.class
            );
            System.out.println(JSON.toJSONString(JSON.toJSONString(response)));

//            if (response.getStatusCode() == HttpStatus.OK) {
            TelecomSmsSelectResponse telecomSmsSelectResponse = JSON.parseObject(response.getBody(), TelecomSmsSelectResponse.class);
            TelecomSmsSelectDetailRes telecomSmsSelectDetailRes = telecomSmsSelectResponse.list.get(0);
            if (telecomSmsSelectDetailRes.getStatus() == 5) {
                ProviderErrorCodeMappingDO providerErrorCodeMappingDO = this.sender.providerErrorCodeMappingService.getByProviderErrorCode(message.getProviderType(), message.getChannel(), telecomSmsSelectDetailRes.getStat());
                message.setErrorCode(telecomSmsSelectDetailRes.getStat());
                if (ObjectUtil.isNotNull(providerErrorCodeMappingDO)) {
                    message.setErrorMsg(providerErrorCodeMappingDO.getOriginalMessage());
                } else {
                    message.setErrorMsg(MsgPushConstant.ERROR_MSG_UNKNOWN);
                }
                this.sender.messageRetryQueueService.saveOrUpdateRetryMessage(message);
            }
//            }
            this.scheduledExecutorService.shutdown();
            this.scheduledExecutorService = null;
        }, 10, TimeUnit.SECONDS);
    }
}
