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

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

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 cn.com.qmth.stmms.biz.exam.model.MarkGroup;
import cn.com.qmth.stmms.biz.exam.model.MarkGroupPK;
import cn.com.qmth.stmms.common.enums.LibraryStatus;
import cn.com.qmth.stmms.common.enums.ScorePolicy;

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
    @Query("delete from MarkGroup q where q.pk.examId=?1")
    void deleteByExamId(int examId);

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

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

    @Query("select q from MarkGroup q where q.pk.examId=?1 order by q.pk.number")
    List<MarkGroup> findByExamId(int 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(int examId, String code);

    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 "
            + "and q.doubleRate!=null and q.doubleRate>0 order by q.pk.number")
    List<MarkGroup> findByExamIdAndSubjectCodeWithDouble(int examId, String code);

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

    @Query("select sum(g.libraryCount) from MarkGroup g where g.pk.examId=?1")
    Integer sumLibraryCount(Integer examId);

    @Query("select sum(g.markedCount) from MarkGroup g where g.pk.examId=?1")
    Integer sumMarkedCount(Integer examId);

    @Modifying
    @Query("update MarkGroup g set g.libraryCount=(select count(l) from MarkLibrary l "
            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number) "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
    void updateLibraryCount(int examId, String subjectCode);

    @Modifying
    @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number and l.status in (?3)) "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
    void updateMarkedCount(int examId, String subjectCode, LibraryStatus... status);

    @Modifying
    @Query("update MarkGroup g set g.leftCount = g.libraryCount - g.markedCount "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
    void updateLeftCount(int examId, String subjectCode);

    @Modifying
    @Query("update MarkGroup g set g.libraryCount=(select count(l) from MarkLibrary l "
            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3) "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateLibraryCount(int examId, String subjectCode, int number);

    @Modifying
    @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3 and l.status in (?4) ) "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateMarkedCount(int examId, String subjectCode, int number, LibraryStatus... status);

    @Modifying
    @Query("update MarkGroup g set g.leftCount = g.libraryCount - g.markedCount "
            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateLeftCount(int examId, String subjectCode, int number);

    @Modifying
    @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(int examId, String subjectCode, int number);

    @Modifying
    @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(int examId, String subjectCode, int number, String picList);

    @Modifying
    @Query("update MarkGroup g set g.title=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
    void updateTitle(int examId, String subjectCode, int number, String title);

    @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(int examId, String subjectCode, int 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(int examId, String subjectCode, int 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(int examId, String subjectCode, int 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(int examId, String subjectCode, Date time);

}
