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

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
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.ExamStudent;

public interface ExamStudentDao
        extends PagingAndSortingRepository<ExamStudent, Integer>, JpaSpecificationExecutor<ExamStudent> {

    public List<ExamStudent> findByExamId(int examId, Pageable pageable);

    public List<ExamStudent> findByExamIdAndUploadAndAbsent(int examId, boolean upload, boolean absent,
            Pageable pageable);

    public List<ExamStudent> findByExamIdAndUpload(int examId, boolean upload, Pageable pageable);

    public List<ExamStudent> findByExamIdAndCampusName(int examId, String campusName, Pageable pageable);

    public List<ExamStudent> findByExamIdAndExamNumber(int examId, String examNumber);

    @Query("select count(s) from ExamStudent s where s.examId=?1 and s.campusName=?2")
    public long countByExamIdAndCampusName(int examId, String campusName);

    @Query("select count(distinct s.campusName) from ExamStudent s where s.examId=?1")
    public long countCampusNameByExamId(int examId);

    @Query("select s from ExamStudent s where s.examId=?1 group by s.subjectCode")
    public List<ExamStudent> findDistinctSubjectByExamId(int examId, Pageable pageable);

    @Query("select s from ExamStudent s where s.examId=?1 and s.campusName=?2 group by s.subjectCode")
    public List<ExamStudent> findDistinctSubjectByExamIdAndCampusName(int examId, String campusName);

    @Query("select s.campusName from ExamStudent s where s.examId=?1 group by s.campusName")
    public List<String> findDistinctCampusName(int examId);

    @Query("select s from ExamStudent s where s.examId=?1 group by s.campusName")
    public Page<ExamStudent> findDistinctCampusName(int examId, Pageable pageable);

    @Query("select s.packageCode from ExamStudent s where s.examId=?1 group by s.packageCode")
    public List<String> findDistinctPackageCode(int examId);

    @Modifying
    @Query("update ExamStudent s set s.subjectiveScore=?2, s.subjectiveScoreList=?3 where s.id=?1")
    public void updateSubjectiveScore(int id, double score, String scoreList);

    @Modifying
    @Query("update ExamStudent s set s.exception=?2 where s.id=?1")
    public void updateException(int id, boolean exception);

    @Modifying
    @Query("update ExamStudent s set s.manualAbsent=?2 where s.id=?1")
    public void updateManualAbsent(int id, boolean manualAbsent);

    @Modifying
    @Query("update ExamStudent s set s.manualAbsent=?3 where s.examId=?1 and s.examNumber=?2")
    public void updateManualAbsent(int examId, String examNumber, boolean manualAbsent);

    @Modifying
    @Query("update ExamStudent s set s.manualAbsent=0 where s.examId=?1")
    public void clearManualAbsent(int examId);

    @Modifying
    @Query("delete from ExamStudent s where s.examId=?1")
    public void deleteByExamId(int examId);

    @Modifying
    @Query("delete from ExamStudent s where s.examId=?1 and s.campusName=?2")
    public void deleteByExamIdAndCampusName(int examId, String campusName);

    public ExamStudent findByExamIdAndSubjectCodeAndStudentCode(Integer examId, String subjectCode, String studentCode);

    public ExamStudent findByExamIdAndSchoolIdAndSubjectCodeAndStudentCode(Integer examId, Integer schoolId,
            String subjectCode, String studentCode);

    public ExamStudent findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(Integer schoolId, String subjectCode,
            String studentCode, String examSeqCode);

    @Query("select sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 0 and 49.9 then 1 else 0 end),"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 50 and 59.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 60 and 69.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 70 and 79.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 80 and 89.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 90 and 100 then 1 else 0 end),"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 0 and 59.9 then 1 else 0 end), "
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 60 and 100 then 1 else 0 end) "
            + " from ExamStudent s where s.examId=?1 and s.subjectCode=?2 and s.upload=?3  and s.absent=?4 ")
    public List<Object[]> statisticsByExamIdAndSubjectCode(Integer examId, String code, Boolean upload, boolean absent);

    @Query("select sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 0 and 49.9 then 1 else 0 end),"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 50 and 59.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 60 and 69.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 70 and 79.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 80 and 89.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 90 and 100 then 1 else 0 end), "
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 0 and 59.9 then 1 else 0 end), "
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 60 and 100 then 1 else 0 end) "
            + " from ExamStudent s where s.examId=?1 and s.subjectCode=?2 ")
    public List<Object[]> statisticsByExamIdAndSubjectCode(Integer examId, String code);

    @Query("select sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 0 and 49.9 then 1 else 0 end),"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 50 and 59.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 60 and 69.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 70 and 79.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 80 and 89.9 then 1 else 0 end) ,"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 90 and 100 then 1 else 0 end),"
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 0 and 59.9 then 1 else 0 end), "
            + "sum(case when ((case when s.objectiveScore is null then 0 else s.objectiveScore end) + (case when s.subjectiveScore is null then 0 else s.subjectiveScore end)) between 60 and 100 then 1 else 0 end) "
            + " from ExamStudent s where s.examId=?1 and s.subjectCode=?2 and s.upload=?3  and s.absent=?4 and s.breach = ?5")
    public List<Object[]> statisticsByAbsentAndBreach(Integer examId, String code, Boolean upload, boolean absent,
            boolean breach);

    public ExamStudent findByExamIdAndSubjectCodeStartingWithAndStudentCode(Integer examId, String subjectCode,
            String studentCode);

    @Query(value = "select s.id from eb_exam_student s where 1=1 and s.id in (select m.student_id from m_library m where 1=1 and m.marker_id in (select m.id from eb_marker m where 1=1 and m.login_name = ?1 ))", nativeQuery = true)
    public List<String[]> findIdsByMarkLogin(String markLogin);

    @Query(value = "select s.id from eb_exam_student s where 1=1 and s.id in (select m.student_id from m_library m where 1=1 and m.marker_id in (select m.id from eb_marker m where 1=1 and m.name = ?1))", nativeQuery = true)
    public List<String[]> findIdsByMarkName(String markName);

}
