package cn.com.qmth.stmms.biz.exam.dao;

import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
import cn.com.qmth.stmms.biz.exam.model.MarkGroupPK;
import cn.com.qmth.stmms.common.enums.*;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;

import java.util.Date;
import java.util.List;

public interface MarkGroupDao
        extends PagingAndSortingRepository<MarkGroup, MarkGroupPK>, JpaSpecificationExecutor<MarkGroup> {

    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 and q.pk.number=?3")
    MarkGroup findOne(Integer examId, String subjectCode, Integer groupNumber);

    @Modifying(clearAutomatically = true)
    @Query("delete from MarkGroup q where q.pk.examId=?1")
    void deleteByExamId(Integer examId);

    @Modifying(clearAutomatically = true)
    @Query("delete from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2")
    void deleteByExamIdAndSubjectCode(Integer examId, String subjectCode);

    @Query("select count(q) from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 and q.status in (?3)")
    long countByExamIdAndSubjectCodeAndStatus(Integer examId, String subjectCode, MarkStatus... status);

    @Query("select count(q) from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 "
            + "and q.pk.number=?3 and q.status in (?4)")
    long countByExamIdAndSubjectCodeAndNumberAndStatus(Integer examId, String subjectCode, Integer groupNumber,
            MarkStatus... status);

    @Query("select q from MarkGroup q where q.pk.examId=?1 order by q.pk.number")
    List<MarkGroup> findByExamId(Integer examId);

    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 order by q.pk.number")
    List<MarkGroup> findByExamIdAndSubjectCode(Integer examId, String subjectCode);

    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 "
            + "and q.status in (?3) order by q.pk.number")
    List<MarkGroup> findByExamIdAndSubjectCodeAndStatus(Integer examId, String subjectCode, MarkStatus... status);

    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 and q.status in (?3)"
            + "and q.doubleRate!=null and q.doubleRate>0 order by q.pk.number")
    List<MarkGroup> findByExamIdAndSubjectCodeAndStatusWithDouble(Integer examId, String subjectCode,
            MarkStatus... status);

    @Query("select e.id from Exam e where e.status=?1 and exists "
            + "(select g.pk.number from MarkGroup g where g.pk.examId=e.id and g.status in (?2))")
    List<Integer> findExamIdByStatus(ExamStatus examStatus, MarkStatus... markStatus);

    @Query("select count(q) from MarkGroup q where q.pk.examId=?1")
    long countByExamId(Integer examId);

    @Query("select count(q) from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2")
    long countByExamIdAndSubjectCode(Integer examId, String subjectCode);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.libraryCount=?4, g.leftCount=(?4-g.markedCount) where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateLibraryCount(Integer examId, String subjectCode, Integer number, Integer totalCount);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.markedCount=?4, g.leftCount=(g.libraryCount-?4) where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateMarkedCount(Integer examId, String subjectCode, Integer number, Integer markedCount);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.leftCount = g.libraryCount, g.markedCount = 0 "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void resetCount(Integer examId, String subjectCode, Integer number);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.picList=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updatePicList(Integer examId, String subjectCode, Integer number, String picList);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.totalScore=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateTotalScore(Integer examId, String subjectCode, Integer number, Double score);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.scorePolicy=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateScorePolicy(Integer examId, String subjectCode, Integer number, ScorePolicy policy);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.buildTime=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateBuildTime(Integer examId, String subjectCode, Integer number, Date time);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.buildTime=?3 where g.pk.examId=?1 and g.pk.subjectCode=?2")
    void updateBuildTime(Integer examId, String subjectCode, Date time);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.doubleRate=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateDoubleRate(Integer examId, String subjectCode, Integer number, Double doubleRate);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.markMode=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateMarkMode(Integer examId, String subjectCode, Integer number, MarkMode markMode);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.arbitrateThreshold=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateArbitrateThreshold(Integer examId, String subjectCode, Integer number, Double arbitrateThreshold);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.sheetView=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateSheetView(Integer examId, String subjectCode, Integer number, boolean sheetView);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.enableAllZero=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateEnableAllZero(Integer examId, String subjectCode, Integer number, boolean enableAllZero);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.status=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3 "
            + "and g.status in (?5)")
    Integer updateStatus(Integer examId, String subjectCode, Integer number, MarkStatus newStatus,
            MarkStatus... currentStatus);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.thirdPolicy=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateThirdPolicy(Integer examId, String subjectCode, Integer number, ThirdPolicy third);

    @Modifying(clearAutomatically = true)
    @Query("update MarkGroup g set g.selective=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateSelective(Integer examId, String subjectCode, Integer number, boolean selective);

    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 and q.selective=?3 order by q.pk.number")
    List<MarkGroup> findByExamAndSubjectAndSelective(Integer examId, String subjectCode, boolean selective);

}
