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

import java.util.List;
import java.util.Set;

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.ExamSubject;
import cn.com.qmth.stmms.biz.exam.model.ExamSubjectPK;
import cn.com.qmth.stmms.common.enums.ExamSubjectStatus;
import cn.com.qmth.stmms.common.enums.LibraryStatus;

public interface ExamSubjectDao extends PagingAndSortingRepository<ExamSubject, ExamSubjectPK>,
        JpaSpecificationExecutor<ExamSubject> {

    @Query("select s from ExamSubject s where s.pk.examId=?1")
    public List<ExamSubject> findByExamId(int examId);

    @Query("select s.level from ExamSubject s where s.pk.examId=?1 and s.level is not null group by s.level")
    public List<String> findDistinctLevel(int examId);

    @Query("select s.category from ExamSubject s where s.pk.examId=?1 and s.category is not null group by s.category")
    public List<String> findDistinctCategory(int examId);

    @Query("select count(s) from ExamSubject s where s.pk.examId=?1 and s.subjectiveScore <> 0 and s.libraryCount >0")
    public long countByExamId(int examId);

    @Query("select s from ExamSubject s where s.pk.examId=?1 and s.pk.code=?2")
    public ExamSubject findByExamIdAndCode(int examId, String code);

    @Query("select s from ExamSubject s where s.pk.examId=?1 and s.libraryCount>?2 and s.subjectiveScore>?3")
    public List<ExamSubject> findByExamIdAndLibraryCountGtAndSubjectiveScoreGt(int examId, int libraryCountGt,
            double subjectiveScoreGt);

    @Query("select s from ExamSubject s where s.pk.examId=?1 and s.status=?2 and s.libraryCount>?3 and s.subjectiveScore>?4")
    public List<ExamSubject> findByExamIdAndStatusAndLibraryCountGtAndSubjectiveScoreGt(int examId,
            ExamSubjectStatus status, int libraryCountGt, double subjectiveScoreGt);

    @Query("select s from ExamSubject s where s.pk.examId=?1 and s.status=?2 and s.libraryCount>?3 and s.leftCount>?4 and s.subjectiveScore>?5")
    public List<ExamSubject> findByExamIdAndStatusAndLibraryCountGtAndLeftCountGtAndSubjectiveScoreGt(int examId,
            ExamSubjectStatus status, int libraryCountGt, int leftCountGt, double subjectiveScoreGt);

    @Query("select s from ExamSubject s where s.pk.examId=?1 and s.status in ?2")
    public List<ExamSubject> findByExamIdAndStatus(int examId, Set<ExamSubjectStatus> status);

    @Query("select s from ExamSubject s where s.status in ?1")
    public List<ExamSubject> findByStatus(Set<ExamSubjectStatus> status);

    @Query("select count(s) from ExamSubject s where s.pk.examId=?1 and s.status in ?2")
    public long countByExamIdAndStatus(int examId, Set<ExamSubjectStatus> status);

    @Modifying
    @Query("update ExamSubject s set s.status=?2 where s.pk.examId=?1")
    public void updateStatusByExamId(int examId, ExamSubjectStatus status);

    @Modifying
    @Query("update ExamSubject s set s.libraryCount=?3, s.leftCount=?3-s.markedCount where s.pk.examId=?1 and s.pk.code=?2")
    public void updateLibraryCountByExamIdAndCode(int examId, String code, int libraryCount);

    @Modifying
    @Query("update ExamSubject s set s.markedCount=?3, s.leftCount=s.libraryCount-?3 where s.pk.examId=?1 and s.pk.code=?2")
    public void updateMarkedCountByExamIdAndCode(int examId, String code, int markedCount);

    @Modifying
    @Query("update ExamSubject s set s.libraryCount=(select count(l) from MarkLibrary l where l.examId=?1 and l.subjectCode=s.pk.code) where s.pk.examId=?1")
    public void updateLibraryCountByExamId(int examId);

    @Modifying
    @Query("update ExamSubject s set s.markedCount=(select count(l) from MarkLibrary l where l.examId=?1 and l.subjectCode=s.pk.code and l.status=?2) where s.pk.examId=?1")
    public void updateMarkedCountByExamId(int examId, LibraryStatus status);

    @Modifying
    @Query("update ExamSubject s set s.leftCount=s.libraryCount-s.markedCount where s.pk.examId=?1")
    public void updateLeftCountByExamId(int examId);

    @Query("select sum(s.libraryCount) as count from ExamSubject s where s.pk.examId=?1 and s.libraryCount>?2 and s.subjectiveScore>?3")
    public Long sumLibraryCountByExamIdAndLibraryCountGtAndSubjectiveScoreGt(int examId, int libraryCountGt,
            double subjectiveScoreGt);

    @Modifying
    @Query("update ExamSubject s set s.totalScore=s.objectiveScore+s.subjectiveScore where s.pk.examId=?1")
    public void updateTotalScoreByExamId(int examId);

    @Modifying
    @Query("delete ExamSubject s where s.pk.examId=?1")
    void deleteByExamId(int examId);

    @Query(value = "select s.* from eb_exam_subject s where 1=1 and s.exam_id = ?1 and s.`code` in ( " +
            "select f.subject_code  from m_library f where 1=1 and f.marker_id = ?2 and f.`status`=?3 GROUP BY f.subject_code)",nativeQuery = true)
    List<ExamSubject> findExamSubjectByMarkerId(int examId,int markerId,int status);
}
