package com.qmth.jkserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.dao.ExamTaskDao;
import com.qmth.jkserver.enums.TaskResultEnum;
import com.qmth.jkserver.enums.TaskStatusEnum;
import com.qmth.jkserver.enums.TaskTypeEnum;
import com.qmth.jkserver.model.ExamTask;
import com.qmth.jkserver.model.User;
import com.qmth.jkserver.service.ExamTaskService;
import com.qmth.jkserver.service.JkExamPlanService;
import com.qmth.jkserver.service.UserService;
import com.qmth.jkserver.templete.execute.AsyncCloudMarkTempleteService;
import com.qmth.jkserver.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Description: 考试任务
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/5/11
 */
@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskDao, ExamTask> implements ExamTaskService {
    private static final Logger log = LoggerFactory.getLogger(ExamTaskServiceImpl.class);

//    @Resource
//    MongoOperations mongoTemplate;

    @Resource
    @Lazy
    JkExamPlanService examPlanService;

    @Resource
    AsyncCloudMarkTempleteService asyncCloudMarkTempleteService;

    @Resource
    UserService userService;

    @Resource
    @Lazy
    ExamTaskService examTaskService;

    /**
     * 保存任务
     *
     * @param examCode
     * @param user
     * @param resetSync
     * @return
     */
    @Override
    public Map<String, Object> saveExamTask(String examCode, User user, boolean resetSync) {
        Map<String, Object> map = new HashMap<>();
        try {
            if (resetSync) {
                ExamTask examTask = new ExamTask(examCode, Objects.nonNull(user) ? user.getId() : null);
                saveExamTaskCommon(map, examCode, examTask, user);
            } else {
//                Query query = new Query();
//                query.addCriteria(Criteria.where("examCode").is(examCode));
//                int count = (int) mongoTemplate.count(query, ExamTask.class);
                QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
                examTaskQueryWrapper.lambda().eq(ExamTask::getExamCode, examCode);
                int count = examTaskService.count(examTaskQueryWrapper);
                if (count == 0) {
                    ExamTask examTask = new ExamTask(examCode, user.getId());
                    saveExamTaskCommon(map, examCode, examTask, user);
                } else {
                    throw new JkServerException("考试编码" + examCode + "已创建了考试任务");
                }
            }
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof JkServerException) {
                ResultUtil.error((JkServerException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return map;
    }

    /**
     * 更新任务
     *
     * @param examTask
     * @param user
     * @return
     */
    @Override
    public Map<String, Object> updateExamTask(ExamTask examTask, User user) {
        Map<String, Object> map = new HashMap<>();
        try {
            examTask.updateInfo(examTask, Objects.nonNull(user) ? user.getId() : null);
            saveExamTaskCommon(map, examTask.getExamCode(), examTask, user);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof JkServerException) {
                ResultUtil.error((JkServerException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return map;
    }

    /**
     * 完成任务
     *
     * @param examTask
     * @param user
     * @return
     */
    @Override
    public Map<String, Object> finishExamTask(ExamTask examTask, User user) {
        Map<String, Object> map = new HashMap<>();
        try {
            examTask.finishInfo(examTask, Objects.nonNull(user) ? user.getId() : null);
            saveExamTaskCommon(map, examTask.getExamCode(), examTask, user);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof JkServerException) {
                ResultUtil.error((JkServerException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return map;
    }

    /**
     * 更新任务状态
     *
     * @throws IOException
     */
    @Override
    public void updateStatus() throws Exception {
//        Query query = new Query();
//        query.addCriteria(Criteria.where("type").is(TaskTypeEnum.SYNC_YUN_MARK));
//        query.addCriteria(Criteria.where("status").ne(TaskStatusEnum.FINISH));
//        query.addCriteria(Criteria.where("result").ne(TaskResultEnum.SUCCESS));
//        List<ExamTask> examTaskList = mongoTemplate.find(query, ExamTask.class);
        QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
        examTaskQueryWrapper.lambda().eq(ExamTask::getType, TaskTypeEnum.SYNC_YUN_MARK)
                .ne(ExamTask::getStatus, TaskStatusEnum.FINISH)
                .ne(ExamTask::getResult, TaskResultEnum.SUCCESS);
        List<ExamTask> examTaskList = examTaskService.list(examTaskQueryWrapper);
        if (Objects.nonNull(examTaskList) && examTaskList.size() > 0) {
            for (ExamTask examTask : examTaskList) {
                Map<String, Object> map = new HashMap<>();
                map.computeIfAbsent(SystemConstant.TASK, v -> examTask);
                map.computeIfAbsent(SystemConstant.USER, v -> userService.findById(examTask.getCreateUserId()));
                asyncCloudMarkTempleteService.cloudMarkTask(map, null);
            }
        }
    }

    /**
     * 保存考试任务公用
     *
     * @param map
     * @param examCode
     * @param examTask
     * @param user
     */
    public void saveExamTaskCommon(Map<String, Object> map, String examCode, ExamTask examTask, User user) {
        map.computeIfAbsent(SystemConstant.TASK, v -> examTask);
        map.computeIfAbsent(SystemConstant.USER, v -> user);
//        mongoTemplate.save(examTask);
        examTaskService.saveOrUpdate(examTask);
        examPlanService.saveExamPlanByTask(examCode, examTask);
    }
}
