package com.qmth.teachcloud.task.job.service.impl;

import com.qmth.boot.redis.uid.RedisMachineService;
import com.qmth.distributed.print.business.bean.dto.initMarkData.ExamDetailCourseInitMarkDto;
import com.qmth.distributed.print.business.entity.ExamTaskDetail;
import com.qmth.distributed.print.business.entity.TBSyncTask;
import com.qmth.distributed.print.business.entity.TBTaskPdf;
import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
import com.qmth.distributed.print.business.service.*;
import com.qmth.distributed.print.business.templete.execute.AsyncCreatePdfTemplateService;
import com.qmth.teachcloud.common.bean.dto.MqDto;
import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.enums.PushTypeEnum;
import com.qmth.teachcloud.common.enums.TaskResultEnum;
import com.qmth.teachcloud.common.enums.TaskStatusEnum;
import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
import com.qmth.teachcloud.common.util.DateDisposeUtils;
import com.qmth.teachcloud.common.util.ExamTaskUtil;
import com.qmth.teachcloud.common.util.RedisUtil;
import com.qmth.teachcloud.mark.entity.MarkGroup;
import com.qmth.teachcloud.mark.entity.MarkPaper;
import com.qmth.teachcloud.mark.entity.MarkUserGroup;
import com.qmth.teachcloud.mark.service.MarkGroupService;
import com.qmth.teachcloud.mark.service.MarkPaperService;
import com.qmth.teachcloud.mark.service.MarkService;
import com.qmth.teachcloud.mark.service.MarkUserGroupService;
import com.qmth.teachcloud.mark.utils.TaskLockUtil;
import com.qmth.teachcloud.task.job.service.JobService;
import com.qmth.teachcloud.task.service.PrintFinishService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Description: job service impl
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/3/31
 */
@Service
public class JobServiceImpl implements JobService {
    private final static Logger log = LoggerFactory.getLogger(JobServiceImpl.class);

    @Resource
    PrintCommonService printCommonService;
    @Resource
    SmsSendService smsSendService;
    @Resource
    BasicMessageService basicMessageService;
    @Resource
    private ExamTaskDetailService examTaskDetailService;
    @Resource
    MarkPaperService markPaperService;
    @Resource
    MarkGroupService markGroupService;
    @Resource
    MarkUserGroupService markUserGroupService;
    @Resource
    MarkService markService;
    @Resource
    ExamDetailService examDetailService;
    @Resource
    PrintFinishService printFinishService;
    @Resource
    RedisUtil redisUtil;
    @Resource
    RedisMachineService redisMachineService;
    @Resource
    TBSyncTaskService tbSyncTaskService;
    @Resource
    TBTaskPdfService tbTaskPdfService;
    @Resource
    AsyncCreatePdfTemplateService asyncCreatePdfTempleteService;
    @Override
    public void sendSmsExpireTask() {
        smsSendService.sendSmsExpireTask();
    }

    @Override
    public void sendSmsOverdueTask() {
        smsSendService.sendSmsOverdueTask();
    }

    @Override
    public void resendSmsTask() {
        basicMessageService.resendSmsTask();
    }

    @Override
    public void machineHeart() {
        redisUtil.set(SystemConstant.TASK_MACHINE_ID + redisMachineService.getMachineId(), redisMachineService.getMachineId(), 30, TimeUnit.SECONDS);
    }

    @Override
    public void updateMarkerQuality() {
        log.info("start auto-update marker");
        try {
            List<MarkPaper> markPaperList = markPaperService.listQualityMarkPaperByStatus(MarkPaperStatus.FORMAL, 0);
            for (MarkPaper markPaper : markPaperList) {
                List<MarkGroup> markGroups = markGroupService.listGroupByExamIdAndPaperNumber(markPaper.getExamId(), markPaper.getPaperNumber());
                for (MarkGroup markGroup : markGroups) {
                    List<MarkUserGroup> markUserGroups = markUserGroupService.listByExamIdAndPaperNumberAndGroupNumber(markPaper.getExamId(), markPaper.getPaperNumber(), markGroup.getNumber());
                    for (MarkUserGroup marker : markUserGroups) {
                        try {
                            if (markService.needUpdateQuality(marker, 30)) {
                                log.info("start auto-update markerId: " + marker.getId());
                                markService.updateQuality(marker);
                            }
                        } catch (Exception e) {
                            log.error("update marker quality error for markerId=" + marker.getId(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("auto-update marker error", e);
        } finally {
            log.info("finish auto-update marker");
        }
    }

    @Override
    public void updateBuildMarkTask() {
        log.info("start auto-create library");
        try {
            List<MarkPaper> markPaperList = markPaperService.listQualityMarkPaperByStatus(MarkPaperStatus.FORMAL, 0);
            for (MarkPaper markPaper : markPaperList) {
                markService.buildMarkTask(markPaper);
            }
        } catch (Exception e) {
            log.error("auto-create library error", e);
        } finally {
            log.info("finish auto-create library");
        }
    }

    @Override
    public void initMarkData() {
        log.info("开始同步数据：" + DateDisposeUtils.dateTimeNow(DateDisposeUtils.YYYY_MM_DD_HH_MM_SS));
        // 结束阅卷的课程，不同步，3.3.0版本更新前的历史数据，统一不同步
        long startTime = DateDisposeUtils.parseDate("2024-04-22 00:00:00").getTime();
        List<ExamDetailCourseInitMarkDto> examDetailCourseInitMarkDtoList = examDetailService.listPrintFinishExamDetailCourse(ExamDetailStatusEnum.FINISH.name(), startTime, MarkPaperStatus.FINISH.name());
        for (ExamDetailCourseInitMarkDto dto : examDetailCourseInitMarkDtoList) {
            for (String paperType : dto.getPaperType().split(",")) {
                TBSyncTask tbSyncTask = tbSyncTaskService.saveTask(dto.getSchoolId(), dto.getSemesterId(), dto.getExamId(), dto.getCourseCode(), dto.getCourseName(), dto.getPaperNumber(), paperType, PushTypeEnum.INIT_MARK_DATA, "");
                try {
                    ExamTaskDetail examTaskDetail = examTaskDetailService.getByExamIdAndCourseCodeAndPaperNumber(dto.getExamId(), dto.getCourseCode(),dto.getPaperNumber());
                    List<PaperInfoVo> paperInfoVos = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds(), paperType);
                    printFinishService.insertMarkPaper(dto.getExamId(), dto.getCourseCode(), dto.getCourseName(), dto.getPaperNumber(), dto.getCoursePaperId(), dto.getCreateId(), paperType, paperInfoVos);
                    printFinishService.insertMarkPaperPackageCode(dto, paperType);
                    printFinishService.insertMarkStudent(dto, paperType);
                    printFinishService.insertScanAnswerCardAndMarkQuestion(dto, paperType);
                    tbSyncTask.setResult(TaskResultEnum.SUCCESS);
                } catch (Exception e) {
                    tbSyncTask.setResult(TaskResultEnum.ERROR);
                    tbSyncTask.setSummary(e.getMessage());
                    log.info("结束同步失败：" + DateDisposeUtils.dateTimeNow(DateDisposeUtils.YYYY_MM_DD_HH_MM_SS));
                } finally {
                    tbSyncTask.setStatus(TaskStatusEnum.FINISH);
                    tbSyncTaskService.updateById(tbSyncTask);
                    log.info("结束同步数据：" + DateDisposeUtils.dateTimeNow(DateDisposeUtils.YYYY_MM_DD_HH_MM_SS));
                }
            }
        }
    }

    @Override
    public void clearTimeoutTask() {
        try {
            long timeoutMinute = 60L;
            TaskLockUtil.clearTimeoutTask(timeoutMinute * 60 * 1000);
        } catch (Exception e) {
            log.error("CronCleanTask error", e);
        }
    }

    @Override
    public void createPdfTask() {
        List<TBTaskPdf> tbTaskPdfList = tbTaskPdfService.listWaitingTask();
        for (TBTaskPdf tbTaskPdf : tbTaskPdfList) {
            asyncCreatePdfTempleteService.createPdf(tbTaskPdf, null);
        }

    }

    /**
     * 组装job
     *
     * @param redisKey
     */
    @Override
    public void assembleJob(String redisKey) {
        Long size = redisUtil.getHashSize(redisKey);
        if (Objects.nonNull(size) && size.longValue() > 0) {
            log.info("redisKey:{}缓冲区的消息数为:{}", redisKey, size);
            Map map = redisUtil.getHashEntries(redisKey);
            map.forEach((k, v) -> {
                MqDto mqDto = (MqDto) v;
                redisUtil.sendMessage(mqDto.getTopic(), mqDto);
            });
        }
    }
}
