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.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.distributed.print.business.entity.TBSyncTask;
import com.qmth.distributed.print.business.mapper.TBSyncTaskMapper;
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.distributed.print.business.templete.execute.AsyncTeachCloudReportService;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.bean.result.SyncListResult;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
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.service.BasicRoleDataPermissionService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @Date: 2021/5/20.
 */
@Service
public class TBSyncTaskServiceImpl extends ServiceImpl<TBSyncTaskMapper, TBSyncTask> implements TBSyncTaskService {

    @Resource
    AsyncTeachCloudReportService asyncTeachCloudReportService;

    @Resource
    GradeBatchService gradeBatchService;

    @Resource
    GradeBatchPaperService gradeBatchPaperService;

    @Resource
    BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Transactional
    @Override
    public TBSyncTask saveTask(Long schoolId, Long semesterId, Long examId, Long objectId, PushTypeEnum type, String remark) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        QueryWrapper<TBSyncTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TBSyncTask::getSchoolId, schoolId)
                .eq(TBSyncTask::getObjectId, objectId)
                .eq(TBSyncTask::getType, type);
        TBSyncTask tbSyncTask = this.getOne(queryWrapper);
        Long id = SystemConstant.getDbUuid();
        if (tbSyncTask != null) {
            if (!TaskStatusEnum.FINISH.equals(tbSyncTask.getStatus())) {
                throw ExceptionResultEnum.ERROR.exception("有任务未结束");
            }
            id = tbSyncTask.getId();
            this.removeById(id);
        }
        tbSyncTask = new TBSyncTask();
        tbSyncTask.setId(id);
        tbSyncTask.setSchoolId(schoolId);
        tbSyncTask.setSemesterId(semesterId);
        tbSyncTask.setExamId(examId);
        tbSyncTask.setObjectId(objectId);
        tbSyncTask.setType(type);
        tbSyncTask.setRemark(remark);
        tbSyncTask.setStatus(TaskStatusEnum.INIT);
        tbSyncTask.setCreateId(sysUser.getId());
        tbSyncTask.setCreateTime(System.currentTimeMillis());
        this.save(tbSyncTask);
        return tbSyncTask;
    }

    @Override
    public TBSyncTask saveTask(Long schoolId, Long semesterId, Long examId, String courseCode, String courseName, String paperNumber, String paperType, PushTypeEnum type, String remark) {
        QueryWrapper<TBSyncTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TBSyncTask::getSchoolId, schoolId)
                .eq(TBSyncTask::getSemesterId, semesterId)
                .eq(TBSyncTask::getExamId, examId)
                .eq(TBSyncTask::getPaperNumber, paperNumber)
                .eq(TBSyncTask::getPaperType, paperType)
                .eq(TBSyncTask::getType, type);
        TBSyncTask tbSyncTask = this.getOne(queryWrapper);

        if (tbSyncTask != null) {
            if (!TaskStatusEnum.FINISH.equals(tbSyncTask.getStatus())) {
                return tbSyncTask;
            }
            tbSyncTask.setStatus(TaskStatusEnum.INIT);
            tbSyncTask.setRemark(remark);
            tbSyncTask.setUpdateTime(System.currentTimeMillis());
        } else {
            tbSyncTask = new TBSyncTask();
            tbSyncTask.setId(SystemConstant.getDbUuid());
            tbSyncTask.setSchoolId(schoolId);
            tbSyncTask.setSemesterId(semesterId);
            tbSyncTask.setExamId(examId);
            tbSyncTask.setCourseCode(courseCode);
            tbSyncTask.setCourseName(courseName);
            tbSyncTask.setPaperNumber(paperNumber);
            tbSyncTask.setPaperType(paperType);
            tbSyncTask.setType(type);
            tbSyncTask.setRemark(remark);
            tbSyncTask.setStatus(TaskStatusEnum.INIT);
            tbSyncTask.setCreateTime(System.currentTimeMillis());
        }
        this.saveOrUpdate(tbSyncTask);
        return tbSyncTask;
    }

    @Override
    public void updateStatusAndResultById(Long id, TaskStatusEnum status, TaskResultEnum result, String errorMessage) {
        UpdateWrapper<TBSyncTask> tbSyncTaskUpdateWrapper = new UpdateWrapper<>();
        tbSyncTaskUpdateWrapper.lambda().set(TBSyncTask::getStatus, status)
                .set(TBSyncTask::getResult, result)
                .set(TBSyncTask::getErrorMessage, errorMessage)
                .eq(TBSyncTask::getId, id);
        this.update(tbSyncTaskUpdateWrapper);
    }

    @Override
    public void updateStatusAndResultById(Long id, TaskStatusEnum status, TaskResultEnum result, String errorMessage, String remark) {
        UpdateWrapper<TBSyncTask> tbSyncTaskUpdateWrapper = new UpdateWrapper<>();
        tbSyncTaskUpdateWrapper.lambda().set(TBSyncTask::getStatus, status)
                .set(TBSyncTask::getResult, result)
                .set(TBSyncTask::getErrorMessage, errorMessage)
                .set(TBSyncTask::getRemark, remark)
                .eq(TBSyncTask::getId, id);
        this.update(tbSyncTaskUpdateWrapper);
    }

    @Override
    public IPage<SyncListResult> query(Long schoolId, Long semesterId, Long examId, String courseCode, String paperNumber, TaskStatusEnum status, PushTypeEnum type, TaskResultEnum result, int pageNumber, int pageSize) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());

        IPage<SyncListResult> page = this.baseMapper.query(new Page<>(pageNumber, pageSize), schoolId, semesterId, examId, courseCode, paperNumber, status, type, result, dpr);
        List<SyncListResult> list = page.getRecords();
        for (SyncListResult syncListResult : list) {
            syncListResult.setStatus(Objects.nonNull(syncListResult.getStatus()) ? TaskStatusEnum.valueOf(syncListResult.getStatus()).getTitle() : null);
            syncListResult.setType(Objects.nonNull(syncListResult.getType()) ? PushTypeEnum.valueOf(syncListResult.getType()).getTitle() : null);
            syncListResult.setResultStr(Objects.nonNull(syncListResult.getResult()) ? TaskResultEnum.valueOf(syncListResult.getResult()).getTitle() : null);
        }
        return page;
    }

    @Override
    public void resync(Long id) throws IllegalAccessException {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        TBSyncTask tbSyncTask = this.getById(id);
        if (tbSyncTask == null) {
            throw ExceptionResultEnum.ERROR.exception("任务不存在");
        }
        if (!TaskStatusEnum.FINISH.equals(tbSyncTask.getStatus())) {
            throw ExceptionResultEnum.ERROR.exception("任务同步中");
        }
        if (TaskResultEnum.SUCCESS.equals(tbSyncTask.getResult())) {
            throw ExceptionResultEnum.ERROR.exception("任务同步成功");
        }
        switch (tbSyncTask.getType()) {
            case INIT_MARK_DATA:
//                this.syncMarkData(this.getById(tbSyncTask.getObjectId()));
                break;
            case GRADE_BATCH_PUSH:
                asyncTeachCloudReportService.syncGradeBatch(gradeBatchService.getById(tbSyncTask.getObjectId()));
                break;
            case PUBLISH:
                asyncTeachCloudReportService.publish(gradeBatchPaperService.getById(tbSyncTask.getObjectId()));
                break;
            case CALCULATE:
                asyncTeachCloudReportService.startCalc(gradeBatchService.getById(tbSyncTask.getObjectId()));
            default:
                break;
        }
    }
}
