package com.qmth.teachcloud.mark.service;

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

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.entity.BasicExam;
import com.qmth.teachcloud.common.entity.BasicExamStudent;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ScanStatus;
import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
import com.qmth.teachcloud.mark.bean.UpdateTimeVo;
import com.qmth.teachcloud.mark.bean.archivescore.ArchiveStudentQuery;
import com.qmth.teachcloud.mark.bean.archivescore.ArchiveStudentVo;
import com.qmth.teachcloud.mark.bean.archivescore.MarkStudentScoreVo;
import com.qmth.teachcloud.mark.bean.archivescore.ScoreReportVo;
import com.qmth.teachcloud.mark.bean.omredit.OmrEditDomain;
import com.qmth.teachcloud.mark.bean.scananswer.AnswerQueryDomain;
import com.qmth.teachcloud.mark.bean.scananswer.AnswerQueryVo;
import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamCheckInfoVo;
import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamInfoVo;
import com.qmth.teachcloud.mark.bean.student.AbsentManualUpdateVo;
import com.qmth.teachcloud.mark.bean.student.StudentQuery;
import com.qmth.teachcloud.mark.bean.student.StudentVo;
import com.qmth.teachcloud.mark.dto.mark.manage.Task;
import com.qmth.teachcloud.mark.dto.mark.score.SheetUrlDto;
import com.qmth.teachcloud.mark.dto.mark.score.StudentObjectiveDetailDto;
import com.qmth.teachcloud.mark.dto.mark.score.StudentScoreDetailDto;
import com.qmth.teachcloud.mark.entity.MarkPaper;
import com.qmth.teachcloud.mark.entity.MarkStudent;
import com.qmth.teachcloud.mark.entity.ScanStudentPaper;
import com.qmth.teachcloud.mark.params.MarkHeaderResult;

/**
 * <p>
 * 考试考生库 服务类
 * </p>
 *
 * @author xf
 * @since 2023-09-22
 */
public interface MarkStudentService extends IService<MarkStudent> {

    List<String> listClassByExamIdAndCourseCode(Long examId, String paperNumber);

    void updateSubjectiveStatusAndScore(Long studentId, SubjectiveStatus status, Double score, String scoreList);

    void updateSubjectiveStatusAndScore(Long examId, String paperNumber, SubjectiveStatus status, Double score,
            String scoreList);

    ScanExamInfoVo getScanExamInfo(BasicExam exam, String courseCode, String coursePaperId);

    IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college, String majorName,
            String className, String teacher, Integer filter, String status, Boolean breach, Double startScore, Double endScore,
            Double subjectiveStartScore, Double subjectiveEndScore, Double objectiveStartScore, Double objectiveEndScore,
            Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, String orderType,
            String orderField, Integer pageNumber, Integer pageSize);

    List<SheetUrlDto> buildSheetUrls(Long studentId);

    ScanExamCheckInfoVo checkInfo(BasicExam exam, String courseCode, String coursePaperId);

    /**
     * 根据考生当前绑定的paper刷新考生状态，需要在外部调用处对考生上锁
     */
    void updateStudentByPaper(@NotNull Long userId, @NotNull Long studentId, @NotNull boolean updateOmrTask);

    MarkStudent findByExamIdAndCoursePaperIdAndStudentCode(Long examId, String coursePaperId, String studentCode);

    MarkStudent findByExamIdAndPaperNumberAndStudentCode(Long examId, String paperNumber, String studentCode);

    StudentObjectiveDetailDto getObjectiveInspectedTask(Long studentId);

    Boolean saveObjectiveInspectedTask(Long studentId, String answers);

    int countUploadedByExamIdAndPaperNumber(Long examId, String paperNumber);

    boolean updateScanInfo(MarkStudent student);

    List<MarkStudent> listAbsentOrBreachMarkTaskStudent(Long examId, String paperNumber);

    List<MarkStudent> listUnMarkTaskStudent(Long examId, String paperNumber, Integer groupNumber, int pageSize);

    boolean saveUploadStudent(MarkStudent student);

    void calculateObjectiveScore(MarkStudent student);

    void updateStudentAndPaper(SysUser user, Long studentId, List<ScanStudentPaper> studentPaperList);

    StudentVo findOne(StudentQuery query);

    int countByExamIdAndSecretNumber(Long examId, String secretNumber);

    List<MarkStudent> listByExamIdAndCoursePaperId(Long examId, String coursePaperId);

    IPage<AnswerQueryVo> query(AnswerQueryDomain query);

    List<String> summary(AnswerQueryDomain query);

    UpdateTimeVo omrEdit(Long userId, OmrEditDomain domain);

    long countByExamIdAndPaperNumber(Long examId, String paperNumber, String paperType);

    AbsentManualUpdateVo absentManualUpdate(Long examId, String coursePaperId, String studentCode, ScanStatus status);

    UpdateTimeVo confirm(Long examId, String coursePaperId, String studentCode, Boolean omrAbsent);

    List<Long> findIdByExamIdAndPaperNumber(Long examId, String paperNumber);

    Task getSubjectiveInspectedTask(Long studentId);

    void saveSubjectiveInspectedTask(MarkHeaderResult markResult);

    IPage<ArchiveStudentVo> studentList(ArchiveStudentQuery query);

    void scoreExport(ArchiveStudentQuery query, HttpServletResponse response);

    ScoreReportVo scoreReport(ArchiveStudentQuery query);

    void exportUnexist(Long examId, String courseCode, String coursePaperId, HttpServletResponse response);

    int countByExamIdAndPaperNumberAndMarkStatus(Long examId, String paperNumber, SubjectiveStatus status);

    void updateCheckInfo(Long studentId, Long userId);

    int countOmrAbsentStudent(Long examId, String paperNumber, String paperType, boolean isOmrAbsentConfirm);

    void scoreReportDownload(JSONObject jsonObject, HttpServletResponse response);

    void deleteByExamIdAndPaperNumber(Long examId, String paperNumber);

    boolean calcObjectiveScore(Long examId, String paperNumber);

    IPage<MarkStudent> pageByExamAndPaperNumber(Long examId, String paperNumber, int pageNumber, int pageSize);

    void updateObjectiveScoreAndScoreList(MarkStudent markStudent);

    boolean updateAssignConfirm(Long studentId, boolean assignConfirm);

    int getAssignedCount(Long examId, Boolean checked, String courseCode, String coursePaperId, MarkPaperStatus status,
            DataPermissionRule dpr);

    int countAbsentByExamIdAndPaperNumber(Long examId, String paperNumber);

    List<MarkStudent> listScanCollegeByExamIdAndCourseCodeAndCoursePaperId(Long examId, String courseCode,
            String coursePaperId, String status, DataPermissionRule dpr);

    int countUnexistByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType);

    void updateStudentAnswer(@NotNull Long studentId);

    List<MarkStudentScoreVo> listMarkStudentScoreList(Long examId, String paperNumber);

    void trackExport(Long examId, String paperNumber, HttpServletResponse response);

    void sheetExport(Long examId, String paperNumber, HttpServletResponse response);

    void updateByBasicExamStudent(BasicExamStudent basicExamStudent, MarkPaper markPaper, Set<String> secretNumberSet);

    void deleteByExamIdAndPaperNumberAndStudentCode(Long examId, String paperNumber, String studentCode);

    Integer maxCardNumber(Long examId, String paperNumber, String paperType);

    void scoreDownload(ArchiveStudentQuery query, HttpServletResponse response);
}
