package com.docus.server.message.thread;

import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.web.api.CommonResult;
import com.docus.server.message.config.JobAdminConfig;
import com.docus.server.message.entity.DelayedMessages;
import com.docus.server.message.enums.TaskWait;
import com.docus.server.message.feign.dto.CompensateTasRequest;
import com.docus.server.message.feign.service.CollectTaskService;
import com.docus.server.message.mapper.DelayedMessagesMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author YongBin Wen
 * @date 2024/1/23 10:59
 */

public class DelayTaskIssuanceHelper {
    private static Logger logger = LoggerFactory.getLogger(DelayTaskIssuanceHelper.class);
    private static DelayTaskIssuanceHelper instance = new DelayTaskIssuanceHelper();

    public static DelayTaskIssuanceHelper getInstance() {
        return instance;
    }

    private Thread delayTaskIssuanceThread;
    private volatile boolean toStop = false;

    public void start() {
        delayTaskIssuanceThread = new Thread(() -> {
            final String messageType = TaskWait.SUBMIT_TASK_WAIT_DELAY_MSG_TYPE;
            DelayedMessages condition = new DelayedMessages();
            condition.setMessageType(messageType);
            DelayedMessagesMapper delayedMessagesMapper = JobAdminConfig.getJobAdminConfig().getDelayedMessagesMapper();
            CollectTaskService collectTaskService = JobAdminConfig.getJobAdminConfig().getCollectTaskService();
            while (!toStop) {
                try {
                    LocalDateTime currentDateTime = LocalDateTime.now();
                    String formatCurrentDateTime = Func.formatDateTime(currentDateTime);
                    // 数据量暂时不大，使用
                    List<DelayedMessages> delayedMessages = delayedMessagesMapper.findExecutableMessages(condition, formatCurrentDateTime);
                    if (Func.isNotEmpty(delayedMessages)) {
                        for (DelayedMessages message : delayedMessages) {
                            try {
                                String messageContent = message.getMessage();
                                String[] split = messageContent.split("-");
                                String patientId = split[0];
                                String collectorId = split[1];
                                List<String> patientIds = Collections.singletonList(patientId);
                                List<String> collectorIds = Collections.singletonList(collectorId);

                                logger.info("提交延迟,补偿任务 patientIds:{} collectId:{}", patientIds, collectorIds);
                                CompensateTasRequest dto = new CompensateTasRequest();
                                dto.setPatientIds(patientIds);
                                dto.setCollectorIds(collectorIds);
                                dto.setPriority(3);
                                CommonResult<String> result = collectTaskService.compensateTask(dto);
                                logger.info("提交延迟，补偿任务结果：{}",Func.toJson(result));
                                delayedMessagesMapper.delById(message.getId());
                            } catch (Exception ex) {
                                if (!toStop) {
                                    logger.error(">>>>>>>>>>> Delay Task Issuance  thread error:" + ex.getMessage() + " ,delayMessage:" + Func.toJson(message), ex);
                                    int retries = message.getRetries() + 1;
                                    Integer delaySeconds = message.getDelaySeconds();
                                    LocalDateTime nexExecuteLocalDateTime = LocalDateTime.now().plusSeconds(delaySeconds);
                                    String dateTime = Func.formatDateTime(nexExecuteLocalDateTime);
                                    Date nexExecuteTime = Func.parseDate(dateTime, DateUtil.PATTERN_DATETIME);

                                    message.setRetries(retries);
                                    message.setErrorMessage(ex.getMessage());
                                    message.setNextExecutionTime(nexExecuteTime);
                                    delayedMessagesMapper.updateById(message);
                                }
                            }
                        }
                    }

                    TimeUnit.SECONDS.sleep(10);
                } catch (Exception ex) {
                    if (!toStop) {
                        logger.error(">>>>>>>>>>> Delay Task Issuance thread error:" + ex.getMessage(), ex);
                    }
                }

            }
            logger.info(">>>>>>>>>>> Delay Task Issuance thread stop");
        });
        delayTaskIssuanceThread.setDaemon(true);
        delayTaskIssuanceThread.setName("delayTaskIssuanceHelper");
        delayTaskIssuanceThread.start();
    }

    public void toStop() {
        toStop = false;
        delayTaskIssuanceThread.interrupt();
        try {
            delayTaskIssuanceThread.join();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
}
