package com.qmth.teachcloud.mark.service.impl;

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.enums.LockType;
import com.qmth.teachcloud.mark.lock.LockService;
import com.qmth.teachcloud.mark.service.MarkService;
import com.qmth.teachcloud.mark.service.MarkSyncService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

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

@Service
public class MarkSyncServiceImpl implements MarkSyncService {

    @Resource
    private MarkService markService;
    @Resource
    private LockService lockService;

    /**
     * 评卷员重置
     *
     * @param markUserGroup
     */
    @Async
    @Override
    public void markerResetSync(MarkUserGroup markUserGroup) {
        try {
            if (markUserGroup != null) {
                lockService.waitlock(LockType.EXAM_SUBJECT, markUserGroup.getExamId(), markUserGroup.getPaperNumber());
                lockService.waitlock(LockType.MARK_USER_GROUP, markUserGroup.getId());
                lockService.watch(LockType.GROUP, markUserGroup.getExamId(), markUserGroup.getPaperNumber(), markUserGroup.getGroupNumber());
                markService.resetMarker(markUserGroup);
            }
        } catch (Exception e) {
            log.error("reset marker error", e);
        } finally {
            lockService.unwatch(LockType.GROUP, markUserGroup.getExamId(), markUserGroup.getPaperNumber(), markUserGroup.getGroupNumber());
            lockService.unlock(LockType.MARK_USER_GROUP, markUserGroup.getId());
            lockService.unlock(LockType.EXAM_SUBJECT, markUserGroup.getExamId(), markUserGroup.getPaperNumber());
            lockService.unlock(LockType.MARKER_RESET, markUserGroup.getId());
        }
    }

    @Async
    @Override
    public void updateQuality(List<MarkUserGroup> markUserGroups, String lockKey) {
        if (CollectionUtils.isNotEmpty(markUserGroups)) {
            for (MarkUserGroup markUserGroup : markUserGroups) {
                try {
                    markService.updateQuality(markUserGroup);
                } catch (Exception e) {
                    log.error("marker quality thread error", e);
                }
            }
        }
        lockService.unlock(LockType.BATCH_QUALITY, lockKey);
    }

    @Async
    @Override
    public void deleteMarkGroup(MarkGroup markGroup, boolean deleteGroupInfo) {
        if (markGroup == null) {
            return;
        }
        try {
            lockService.waitlock(LockType.EXAM_SUBJECT, markGroup.getExamId(), markGroup.getPaperNumber());
            lockService.waitlock(LockType.GROUP, markGroup.getExamId(), markGroup.getPaperNumber(), markGroup.getNumber());
            markService.deleteMarkGroup(markGroup, deleteGroupInfo);
        } catch (Exception e) {
            log.error("delete group error", e);
        } finally {
            lockService.unlock(LockType.GROUP, markGroup.getExamId(), markGroup.getPaperNumber(), markGroup.getNumber());
            lockService.unlock(LockType.EXAM_SUBJECT, markGroup.getExamId(), markGroup.getPaperNumber());
            lockService.unlock(LockType.GROUP_DELETE, markGroup.getExamId(), markGroup.getPaperNumber(), markGroup.getNumber());
        }
    }

    @Async
    @Override
    public void calcObjectiveScore(MarkPaper markPaper) {
        try {
            if (markPaper != null) {
                markService.calcObjectiveScore(markPaper);
            }
        } catch (Exception e) {
            log.error("reset marker error", e);
        } finally {
            lockService.unlock(LockType.SCORE_CALCULATE, markPaper.getId());
        }
    }
}
