package jnpf.cultivate.service;


import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.dto.statistics.CultivateUserExamCountDTO;
import jnpf.model.cultivate.dto.statistics.ExamStatisticsForOrgDTO;
import jnpf.model.cultivate.dto.statistics.ExamStatisticsForPersonDTO;
import jnpf.model.cultivate.dto.statistics.FtbCultivateStatisticsDTO;
import jnpf.model.cultivate.po.exam.FtbCultivateExam;
import jnpf.model.cultivate.po.exam.FtbCultivateExamUser;
import jnpf.model.cultivate.po.exam.FtbCultivateExamUserDetail;
import jnpf.model.cultivate.req.exam.*;
import jnpf.model.cultivate.resp.*;
import jnpf.model.cultivate.v2.exam.vo.V2TestPaperVo;
import jnpf.model.cultivate.vo.position.web.FtbCultivatePositionExamPersonVO;
import jnpf.model.cultivate.vo.position.web.FtbCultivatePositionExamVO;
import jnpf.model.personnels.dto.authoritys.PermissionsCacheDTO;
import jnpf.permission.entity.PositionEntity;
import jnpf.permission.model.position.PositionGradesInfoBoundVO;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public interface FtbCultivateExamUserService extends IService<FtbCultivateExamUser> {


    /**
     * 根据考试ID 分页查询考试的用户考试列表
     *
     * @param req
     * @return
     */
    PageInfo<ExamListUserVo> getPageList(QueryExamUserReq req);


    /**
     * 查询用户考试详情
     *
     * @param userExamId 用户考试ID
     * @return
     */
    FtbCultivateExamUser getInfo(String userExamId);


    /**
     * 删除用户考试
     *
     * @param userExamId 用户考试ID
     */
    void deleteData(String userExamId);

    /**
     * 检查是否可以删除用户考试
     *
     * @param userExamId 用户考试ID
     * @return
     */
    CanDeleteMsg checkUserExamCanDelete(String userExamId);

    /**
     * 批阅用户考试
     *
     * @param req
     */
    void readOver(ReadOverExamReq req);

    /**
     * 查看用户的考试 试卷详情
     *
     * @param userExamId          用户考试ID
     * @param isQueryQuestionList 是否用户的题目列表 true:是 false:否
     * @return
     */
    UserExamDetailVo getUserExamDetail(String userExamId, Boolean isQueryQuestionList);

    /**
     * 排行榜
     *
     * @param examId 考试ID
     * @return
     */
    PageInfo<UserRankingVo> rankIngList(String examId, QueryExamRankListReq req);

    /**
     * 开始考试
     *
     * @param userExamId 用户考试ID
     * @return
     */
    FtbCultivateExamUser startExam(String userExamId);

    /**
     * 查询用户的完成的题目
     *
     * @param examId     考试ID
     * @param userExamId 用户考试ID
     * @param userId     用户ID
     */
    List<FtbCultivateExamUserDetail> queryExamUserQuestion(String examId, String userExamId, String userId);


    /**
     * 提交试卷
     *
     * @param userExamId 用户考试ID
     * @param req
     */

    SubExamVo subExam(String userExamId, SubExamQuestionReq req);

    /**
     * 查询我的考试列表
     *
     * @param req
     * @return
     */
    PageInfo<AppExamListVo> queryMyExamList(QueryExamListReq req);

    /**
     * 根据用户ID 查询考试列表
     *
     * @param userId 用户ID
     * @return
     */
    PageInfo<AppExamListVo> queryExamListForUserId(String userId, CultivatePage page);

    /**
     * 等待我批阅的考试列表
     *
     * @param req
     * @return
     */
    PageInfo<AppExamListVo> queryWaitMyReadOver(QueryExamListReq req);

    /**
     * 查询我已经完成批阅
     *
     * @param req
     * @return
     */
    PageInfo<AppExamListVo> queryMyCompleteReadOver(QueryExamListReq req);

    /**
     * 查询下属逾期未考的，仅仅常规考试
     *
     * @param req
     * @return
     */
    PageInfo<AppExamListVo> expireExam(QueryExpireListReq req);

    /**
     * 清除下属逾期未考的，仅仅常规考试
     *
     * @param userExamIds
     */

    void clearExpireExam(String userExamIds);

    /**
     * 触发岗位学习考试
     *
     * @param triggerExamDto
     * @return
     */
    Boolean triggerPositionExam(TriggerExamDto triggerExamDto);


    /**
     * 取消 岗位学习考试
     * 取消学习了 但是未完成考试的
     *
     * @param innerExamDto
     * @return
     */
    Boolean cancelPositionExam(InnerExamDto innerExamDto);

    /**
     * 根据用户查询完成的考试
     *
     * @param userId
     * @return
     */
    List<UserExamDetailVo> queryCompleteExamListForUserId(String userId);

    /**
     * 重新开始考试
     *
     * @param userExamId 用户考试ID
     * @return
     */
    FtbCultivateExamUser reStartExam(String userExamId);

    /**
     * 查询用户的总的考试数量和已经完成的考试数量
     *
     * @param userIds
     * @return
     */
    Map<String, UserExamCount> queryExamTotalAndCompleteNumForUserIds(List<String> userIds);

    /**
     * 数据看板 考试统计
     *
     * @param req
     * @return
     */
    ExamStatisticsVo statistics(FtbCultivateStatisticsDTO req);

    /**
     * 数据看板 考试统计
     *
     * @param req
     * @return
     */
    ExamStatisticsVo statisticsNew(FtbCultivateStatisticsDTO req);

    /**
     * 根据用户ID 和岗位ID 查询用户的考试列表
     *
     * @param dto
     * @return
     */
    PageInfo<PositionExamDto> queryExamListForUserIdAndPostId(QueryUserExamListDto dto);

    /**
     * 检测并修改过期考试
     *
     * @return
     */
    Integer checkAndUpdateExpireUserExamStatus();

    /**
     * 查询我下属 等待、完成 、过期数量
     *
     * @return
     */
    MyBlowExamNum queryMyBlowExamNum();

    /**
     * 考试排行榜
     *
     * @param dto
     * @return
     */
    List<UserRankingVo> statisticsExamRankingList(FtbCultivateStatisticsDTO dto);

    /**
     * 考试排行榜 (web端 不要再按照用户权限过滤了)
     *
     * @param dto
     * @return
     */
    List<UserRankingVo> statisticsExamRankingListNoPower(FtbCultivateStatisticsDTO dto);

    /**
     * 根据用户ID 查询用户的组织
     *
     * @param userId 用户id
     * @return
     */
    List<PositionGradesInfoBoundVO> queryUserOrganization(String userId);

    /**
     * 根据用户id批量查询用户的岗位信息
     * @param userIds 用户ID 集合
     * @return
     */
     Map<String,List<PositionGradesInfoBoundVO>> queryUserOrganizationByUserIds(List<String> userIds) ;

    /**
     * 根据考试Id查考试已经完成的人数
     *
     * @param examId 考试id
     * @return
     */
    Long queryCompleteNumForExamId(String examId);

    /**
     * 查询用户考试记录基本信息
     *
     * @param userExamId 用户考试记录ID
     * @return
     */
    UserExamDetailVo queryBaseUserExamInfo(String userExamId);

    /**
     * 根据考试id查询排行版
     *
     * @param examId 考试id
     * @return
     */
    UserRankingVo queryMyRank(String examId);

    /**
     * 删除考试，同时创建考试
     *
     * @param id 删除id并重新创建考试
     */
    void deleteAndCreateExam(String id);

    /**
     * 培训功能优化,统计组织下用户考试合格率、合格人数、考试总人数
     *
     * @param dto
     * @return
     */
    ExamCultivateCountVo queryCultivateCount(CultivateUserExamCountDTO dto, List<String> userIds);

    /**
     * 根据岗位id统计 考试人数，优秀人数 合格人数 不合格人数
     *
     * @param positionId 岗位id
     * @return
     */
    ExamCultivateForPositionVo queryCultivateCountForPositionId(String positionId);

    /**
     * 查询指定用户的考试列表
     * @param req
     * @return
     */
    PageInfo<MyExamListVo> queryExamList(QueryCultivateExamReq req);

    /**
     * 考试按照组织维度统计信息
     * @param dto 查询信息
     * @return
     */
    List<ExamStatisticsForOrgVo> queryExamStatisticsForOrg(ExamStatisticsForOrgDTO dto, List<String> userIds);

    /**
     * 考试按照个人维度统计信息
     * @param dto 查询信息
     * @return
     */
    PageInfo<ExamStatisticsForPersonVo> queryExamStatisticsForPerson(ExamStatisticsForPersonDTO dto);

    /**
     * 根据岗位ID统计合格率
     *
     * @param positionId
     * @return
     */
    BigDecimal queryExamStatisticsForPositionId(String positionId);

    /**
     * 处理考试用户的岗位数据，兼容老数据
     */

    void dealExamUserPositionForOldData();

    /**
     * 查询考试是否完成
     *
     * @param userId     用户ID
     * @param positionId 岗位ID
     * @param settings   是否开启合格设置 1是 0 否
     * @return [1:已经完成考试      2:未完成考试, 3:考试未合格]
     */
    Integer queryExamIsCompleteForUserIdAndPostion(String userId, String positionId, Integer settings);

    /**
     * 查询
     * @param str 用户考试记录id
     * @param learningMapSetting   是否开启合格设置 1是 0 否
     * @return （0待考试，1待批阅，2已逾期，3合格，4不合格 5优秀）
     */
    Integer queryExamIsCompleteForUserIdAndPostionWithNew(String str, Integer learningMapSetting);

    /**
     * Web端发起重考
     *
     * @param req
     */
    void webRestartExam(WebRestartExamReq req);
    /**
     * 视为作弊提交试卷
     *
     * @param cheatType 作弊类型 1-超过切屏次数视为作弊,2-超过考试时间无交互视为作弊
     * @param userExamId 用户考试ID
     * @param req
     * @return
     */
    void setCheat(String userExamId, Integer cheatType, SubExamQuestionReq req) throws Exception;

    /**
     * 用户考试的批阅人权限
     */
    void refreshUserExamPower();

    /**
     * app批阅考试查询考试信息（简单）
     *
     * @param userExamId 用户考试记录id
     * @return
     */
    UserExamDetailVo queryUserExamSimpleMsg(String userExamId);

    /**
     * Web端考试历史试卷列表
     * @param req
     * @return
     */
    PageInfo<ExamListUserVo> webHistoryExamUserList(WebHistoryQueryExamUserReq req);

    /**
     * 隐藏我的考试记录
     * @param userExamId 用户考试记录ID
     */
    void hiddenMyExamRecord(String userExamId);

    /**
     * 查询考试合格率和考试合格人数
     *
     * @param dbPostId
     * @param userIdsByGradesId
     * @return
     */
    FtbCultivatePositionExamVO queryExamPassingInformation(String dbPostId, List<String> userIdsByGradesId);

    /**
     * 批量查询一个岗位的指定人员的考试信息
     * @param userIds 用户id集合
     * @param positionId 岗位id
     * @param exmIds 考试id
     * @return
     */
    FtbCultivatePositionExamPersonVO queryTheListOfQualifiedPersons(List<String> userIds, String positionId, List<String> exmIds);

    /**
     * 查询是否有完成的考试 如果有完成的考试就生成
     * @param id 考试id
     * @param versionBatch 批次
     * @return
     */
    List<FtbCultivateExamUser>  queryCompleteExamUserListForExamIdAndBatch(String id, String versionBatch);

    /**
     * 根据考试ID查询待考试的列表
     * @param examId 考试ID
     * @return
     */
    List<WaitReadOverNumVo> queryWaitReadOverNum(String examId);

    /**
     * 检查用户是否完成考试
     * @param positionId 岗位ID
     * @param userId 用户ID
     * @return
     */
    CompleteExamVo checkIsCompleteExamForUserId(String positionId, String userId);

    /**
     * 查询我的岗位考试列表（完成考试合格且需要考试合格才能鉴定 却未鉴定的岗位）
     * @loginUserId 用户ID
     * @return
     */
    List<PositionEntity> queryAlertPostionIdentify(String loginUserId);

    /**
     * 岗位完成鉴定
     * @param userId 用户id
     * @param positionId 岗位ID
     */
    void completeIdentifyCallBack(String userId, String positionId);


    /**
     * 岗位学习的考试 或者 是否是考试合格才能触发鉴定 发生变化时回调
     * @param positionId 岗位学ID
     * @param examId 考试ID
     * @param examIdentifyConfig 是否是考试合格才能触发鉴定,0-否 1-是
     */
    void positionConfigChangeCallBack(String positionId, String examId,Integer examIdentifyConfig);

    /**
     * 查询用户的权限信息
     * @param userId 用户id
     * @param permissionsCacheDTO 权限信息
     * @param localOrganizeIds 用户当前组织集合
     * @return
     */
    List<String> getPowerUserIdsForPermission(String userId, PermissionsCacheDTO permissionsCacheDTO, List<String> localOrganizeIds) ;


    /**
     * 查询任务考试结果
     *
     * @param taskId 任务id
     * @param userId 用户ID
     * @return
     *         -1：没有考试记录
     *         0:未完成考试
     *         1：已经完成考试(待批阅，未出考试结果)
     *         3合格
     *         4不合格
     *         5优秀
     */
    Integer queryExamResultForTask(String taskId, String userId);

    /***
     * 查询任务考试结果
     * @param taskId 任务id
     * @param userId 用户id
     * @return
     */
    List<FtbCultivateExamUser> queryExamResultForTaskInfo(String taskId, String userId);

    /**
     * 统计通过的任务考试数量
     * @param taskIds 任务集合ID
     * @return
     */
    Map<String, Integer> groupPassCountNum(List<String> taskIds);

    /**
     * 批量统计所有的任务考试数量
     * @param taskIds
     * @return
     */
    Map<String, Integer> groupAllCountNum(List<String> taskIds);

    /**
     * 删除任务考试记录（用户任务终止和任务删除）
     * @param taskId 任务id
     */
    void deleteTaskExamUserRecord(String taskId);

     Boolean checkMyIsRevierverDynamic(FtbCultivateExam exam, FtbCultivateExamUser examUser, String userId, PermissionsCacheDTO permissionsCacheDTO);


    void batchFillExamUserInfo(List<AppExamListVo> examUserList);

    void fillExtraInfo(String loginUserId, List<AppExamListVo> list);

    void fillRelationPositionName(List<AppExamListVo> list) ;

    Map<String, Integer> groupAllCountNumV2(List<String> taskIds);

    /**
     * 统计通过的任务考试数量
     * @param taskIds 任务集合ID
     * @return
     */
    Map<String, Integer> groupPassCountNumV2(List<String> taskIds);
}
