package com.qmth.distributed.print.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.qmth.distributed.print.business.entity.GradeBatch;
import com.qmth.distributed.print.business.entity.GradeBatchPaper;
import com.qmth.distributed.print.business.entity.TBSyncTask;
import com.qmth.distributed.print.business.service.DataSyncReportService;
import com.qmth.distributed.print.business.service.GradeBatchPaperService;
import com.qmth.distributed.print.business.service.GradeBatchService;
import com.qmth.distributed.print.business.service.TBSyncTaskService;
import com.qmth.teachcloud.common.entity.BasicSemester;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.GradeAnalyzePaperStatusEnum;
import com.qmth.teachcloud.common.enums.TaskResultEnum;
import com.qmth.teachcloud.common.enums.TaskStatusEnum;
import com.qmth.teachcloud.common.service.BasicSemesterService;
import com.qmth.teachcloud.common.sync.TeachCloudReportTaskUtils;
import com.qmth.teachcloud.common.util.Base64Util;
import com.qmth.teachcloud.common.util.ShaUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 同步服务类
 */
@Service
public class DataSyncReportServiceImpl implements DataSyncReportService {

    private static final Logger log = LoggerFactory.getLogger(DataSyncReportServiceImpl.class);

    @Resource
    private BasicSemesterService basicSemesterService;

    @Resource
    private TBSyncTaskService tbSyncTaskService;

    @Resource
    private GradeBatchService gradeBatchService;

    @Resource
    private GradeBatchPaperService gradeBatchPaperService;

    @Resource
    private TeachCloudReportTaskUtils teachCloudReportTaskUtils;

    @Async
    @Override
    public void syncGradeBatch(GradeBatch gradeBatch, TBSyncTask tbSyncTask) {
        // 同步初始参数
        TaskResultEnum result = null;
        TaskStatusEnum status;
        String errorMessage = null;
        Long schoolId = tbSyncTask.getSchoolId();
        Long thirdSemesterId = gradeBatch.getThirdSemesterId();
        Long thirdExamId = gradeBatch.getThirdExamId();
        Long semesterId = gradeBatch.getSemesterId();
        try {
            // 同步中
            status = TaskStatusEnum.RUNNING;
            tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), null, status, null, null);

            // 同步学期
            BasicSemester basicSemester = basicSemesterService.getById(semesterId);
            if (basicSemester == null) {
                throw ExceptionResultEnum.ERROR.exception("学期不存在");
            }
            thirdSemesterId = teachCloudReportTaskUtils.syncSemester(schoolId, thirdSemesterId, basicSemester.getName(), basicSemester.getStartTime(), basicSemester.getEndTime(), true);
            if (thirdSemesterId == null) {
                throw ExceptionResultEnum.ERROR.exception("学期同步失败");
            }
            // 更新批次表考试ID、状态
            gradeBatch.setThirdSemesterId(thirdSemesterId);

            // 同步考试（分析批次）
            thirdExamId = teachCloudReportTaskUtils.syncExam(schoolId, thirdExamId, gradeBatch.getBatchName(), gradeBatch.getBatchTime(), String.valueOf(thirdSemesterId), true);
            if (thirdExamId == null) {
                throw ExceptionResultEnum.ERROR.exception("考试同步失败");
            }

            gradeBatch.setThirdExamId(thirdExamId);

            // 同步分析课程
            QueryWrapper<GradeBatchPaper> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(GradeBatchPaper::getBatchId, gradeBatch.getId());
            List<GradeBatchPaper> gradeBatchPaperList = gradeBatchPaperService.list(queryWrapper);
            for (GradeBatchPaper gradeBatchPaper : gradeBatchPaperList) {
                String courseCode = gradeBatchPaper.getPaperNumber() + gradeBatchPaper.getPaperType();
                boolean syncCourse = teachCloudReportTaskUtils.syncCourse(schoolId, String.valueOf(thirdExamId), courseCode, gradeBatchPaper.getPaperName(), gradeBatchPaper.getPaperType(), gradeBatchPaper.getTeachCollegeName(), gradeBatchPaper.getEnable());
                if (syncCourse) {
                    // 删除enable=false的课程
                    if(!gradeBatchPaper.getEnable()) {
                        gradeBatchPaperService.removeById(gradeBatchPaper.getId());
                    }

                    QueryWrapper<GradeBatchPaper> gradeBatchPaperQueryWrapper = new QueryWrapper<>();
                    gradeBatchPaperQueryWrapper.lambda().eq(GradeBatchPaper::getSchoolId, schoolId).eq(GradeBatchPaper::getPaperNumber, gradeBatchPaper.getPaperNumber()).eq(GradeBatchPaper::getPaperType, gradeBatchPaper.getPaperType());
                    List<GradeBatchPaper> gradeBatchPapers = gradeBatchPaperService.list(gradeBatchPaperQueryWrapper);
                    long count = gradeBatchPapers.stream().filter(m -> GradeAnalyzePaperStatusEnum.READY_TO_CALCULATE.equals(m.getStatus()) || GradeAnalyzePaperStatusEnum.CALCULATING.equals(m.getStatus()) || GradeAnalyzePaperStatusEnum.FINISH_CALCULATE.equals(m.getStatus())).count();

                    // 更新批次课程状态
                    gradeBatchPaper.setGradeCourseCode(courseCode);
                    gradeBatchPaper.setStatus(count > 0 ? GradeAnalyzePaperStatusEnum.READY_TO_CALCULATE : GradeAnalyzePaperStatusEnum.SETTING_GRADE_PAPER_PARAM);
                    gradeBatchPaperService.updateById(gradeBatchPaper);
                }
            }

            long batchCount = gradeBatchPaperList.stream().filter(m -> m.getEnable() && GradeAnalyzePaperStatusEnum.SETTING_GRADE_PAPER_PARAM.equals(m.getStatus())).count();
            gradeBatch.setStatus(batchCount > 0 ? GradeAnalyzePaperStatusEnum.SETTING_GRADE_PAPER_PARAM : GradeAnalyzePaperStatusEnum.READY_TO_CALCULATE);

            // 任务结果
            result = TaskResultEnum.SUCCESS;
        } catch (Exception e) {
            result = TaskResultEnum.ERROR;
            errorMessage = e.getMessage();
        } finally {
            // 同步结束
            status = TaskStatusEnum.FINISH;
            tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), null, status, result, errorMessage);

            // 更新批次表学期Id、考试ID、状态
            gradeBatchService.updateById(gradeBatch);
        }
    }

    @Async
    @Override
    public void startCalc(GradeBatch gradeBatch, TBSyncTask tbSyncTask) {
        // 同步初始参数
        TaskResultEnum result = null;
        TaskStatusEnum status;
        String errorMessage = null;
        String source = null;
        Long schoolId = tbSyncTask.getSchoolId();
        try {
            // 同步中
            status = TaskStatusEnum.RUNNING;
            tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), null, status, null, null);

            // 清空错误日志文件
            UpdateWrapper<GradeBatch> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(GradeBatch::getReportFilePath, null).eq(GradeBatch::getId, gradeBatch.getId());
            gradeBatchService.update(updateWrapper);

            QueryWrapper<GradeBatchPaper> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(GradeBatchPaper::getBatchId, gradeBatch.getId());
            List<GradeBatchPaper> gradeBatchPaperList = gradeBatchPaperService.list(queryWrapper);
            if (gradeBatchPaperList.isEmpty()) {
                throw ExceptionResultEnum.ERROR.exception("没有可分析的课程");
            }

            List<String> courseCodes = gradeBatchPaperList.stream().map(m -> m.getPaperNumber() + m.getPaperType()).collect(Collectors.toList());
            Collections.sort(courseCodes);
            source = Base64Util.encode(ShaUtils.sha1(gradeBatch.getThirdExamId() + courseCodes.toString()));
            teachCloudReportTaskUtils.startCalc(schoolId, gradeBatch.getThirdExamId(), courseCodes);
            // 任务结果
            result = TaskResultEnum.SUCCESS;
        } catch (Exception e) {
            result = TaskResultEnum.ERROR;
            errorMessage = e.getMessage();

            // 生成txt
            gradeBatchService.createTxt(gradeBatch, errorMessage);
        } finally {
            // 同步结束
            status = TaskStatusEnum.FINISH;
            tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), null, status, result, errorMessage);

            if (source != null) {
                UpdateWrapper<GradeBatch> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(GradeBatch::getSource, source).eq(GradeBatch::getId, gradeBatch.getId());
                gradeBatchService.update(updateWrapper);
            }
        }
    }

    @Async
    @Override
    public void publish(GradeBatch gradeBatch, GradeBatchPaper gradeBatchPaper, TBSyncTask tbSyncTask) {
        // 同步初始参数
        TaskResultEnum result = null;
        TaskStatusEnum status;
        String errorMessage = null;
        boolean publish = false;
        Long schoolId = tbSyncTask.getSchoolId();
        try {
            // 同步中
            status = TaskStatusEnum.RUNNING;
            tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), null, status, null, null);

            publish = teachCloudReportTaskUtils.publish(schoolId, gradeBatch.getThirdExamId(), gradeBatchPaper.getGradeCourseCode(), true);
            // 任务结果
            result = TaskResultEnum.SUCCESS;
        } catch (Exception e) {
            result = TaskResultEnum.ERROR;
            errorMessage = e.getMessage();
        } finally {
            // 同步结束
            status = TaskStatusEnum.FINISH;
            tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), null, status, result, errorMessage);

            if(!gradeBatchPaper.getPublishStatus()) {
                UpdateWrapper<GradeBatchPaper> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(GradeBatchPaper::getPublishStatus, publish).eq(GradeBatchPaper::getId, gradeBatchPaper.getId());
                gradeBatchPaperService.update(updateWrapper);
            }
        }
    }
}
