package com.ssj.service.mapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ssj.bean.conch.conch.domain.HomeworkRecord;
import com.ssj.bean.conch.conch.domain.SconStudentTermtainData;
import com.ssj.bean.conch.conch.dto.HomeworkCheckStatusDto;
import com.ssj.bean.sys.homework.domain.HomeworkCount;
import com.ssj.bean.sys.homework.domain.HomeworkPicture;
import com.ssj.bean.sys.homework.domain.KnowledgeWrongQuestionCount;
import com.ssj.bean.sys.homework.domain.StudentWeeklyReport;
import com.ssj.service.conch.conch.dto.RankDTO;
import com.ssj.service.conch.parents.dto.HomeworkAccuracyRateDto;
import com.ssj.service.conch.parents.v2.dto.KnowHowDetailDTO;
import com.ssj.service.conch.parents.v2.dto.MonthlyReportDTO;
import com.ssj.service.conch.parents.v2.dto.StudentWeeklyReportDTO;
import com.ssj.service.conch.parents.v2.dto.WrongBookQuestionDTO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Mapper
public interface HomeworkMapper {

    /**
     * 查询所有记录中最早的创建时间
     *
     * @return 最早的创建时间
     */
    Date findMinCreateTime();

    /**
     * 分页统计指定时间区间内作业数据
     *
     * @param page             分页条件
     * @param beginDateTimeStr 开始时间
     * @param endDateTimeStr   结束时间
     *
     * @return 数据列表
     */
    List<HomeworkCount> countHomeworkData(@Param("page") Page<HomeworkCount> page, @Param("beginDateTimeStr") String beginDateTimeStr, @Param("endDateTimeStr") String endDateTimeStr);

    /**
     * 统计指定作业批改数据
     *
     * @param homeworkId 作业id
     *
     * @return 统计数据
     */
    HomeworkCount countHomeworkDataByHomeworkId(@Param("homeworkId") String homeworkId);

    /**
     * 查询学生作业正确率列表
     *
     * @param vipId        学生
     * @param beginTimeStr 开始时间
     * @param endTimeStr   结束时间
     * @return 正确率列表
     */
    List<HomeworkAccuracyRateDto> findHomeworkAccuracyRateList(@Param("vipId") String vipId, @Param("beginTimeStr") String beginTimeStr, @Param("endTimeStr") String endTimeStr);

    /**
     * 查询小塾的作业记录
     *
     * @param vipId
     * @param beginTime
     * @param endTime
     * @return
     */
    List<HomeworkRecord> findConchHomeworkRecord(@Param("vipId") String vipId,
                                                 @Param("beginTime") String beginTime,
                                                 @Param("endTime") String endTime);

    /**
     * 查询某个作业记录
     * @param homeworkId
     * @return
     */
    HomeworkRecord findOneConchHomeworkRecord(@Param("homeworkId") String homeworkId);

    /**
     * 查询待处理的任务
     * @param vipId
     * @param beginTime
     * @param endTime
     * @return
     */
    List<HomeworkRecord> findConchHandleTask(@Param("vipId") String vipId,
                                             @Param("beginTime") String beginTime,
                                             @Param("endTime") String endTime);

    /**
     * 分页统计指定时间区间内作业数据
     * @param page 分页条件
     * @param beginDateTimeStr 开始时间
     * @param endDateTimeStr 结束时间
     * @return 数据列表
     */
    List<HomeworkCount> countMonthlyHomeworkData(@Param("page") Page<Object> page, @Param("beginDateTimeStr") String beginDateTimeStr, @Param("endDateTimeStr") String endDateTimeStr);

    /**
     * 根据学生id和月份查询月统计数据
     * @param vipId 学生id
     * @param grade 年级
     * @param month 月份
     * @return 月统计数据
     */
    HomeworkCount findByVipIdAndMonth(@Param("vipId") String vipId, @Param("grade") String grade, @Param("month") String month);

    /**
     * 查询最早一份作业所处的月份
     * @return 月份（格式：2019-09）
     */
    String findMinHomeworkMonth();

    /**
     * 查询需要推送周报通知的学生id
     * @param page 分页
     * @param beginDateTimeStr 开始时间
     * @param endDateTimeStr 结束时间
     * @return 学生id列表
     */
    List<String> findVipIdNeedPushWeeklyNotify(@Param("page") Page<Object> page, @Param("beginDateTimeStr") String beginDateTimeStr, @Param("endDateTimeStr") String endDateTimeStr);

    /**
     * 查询需要推送月报通知的学生id
     * @param page 分页
     * @param month 月份
     * @return 学生id列表
     */
    List<String> findVipIdNeedPushMonthlyNotify(@Param("page") Page<Object> page, @Param("month") String month);

    /**
     * 根据学生id查询作业积分排行
     * @param vipId 学生id
     */
    RankDTO findByVipId(@Param("vipId") String vipId);

    /**
     * 查询老师作业列表的质检中状态
     * @param homeworkIds
     * @param teacherId
     * @param teacherType
     * @return
     */
    List<HomeworkCheckStatusDto> findHomeworkCheckStatus (@Param("homeworkIds") List<String> homeworkIds,
                                                          @Param("teacherId") String teacherId,
                                                          @Param("type") int teacherType);

    /**
     * 统计周报作业数据
     * @param page 分页
     * @param beginDateTime 开始日期
     * @param endDateTime 结束日期
     * @return 周报数据列表
     */
    List<StudentWeeklyReport> countWeeklyHomeworkData(@Param("page") Page<Object> page, @Param("beginDateTime") String beginDateTime, @Param("endDateTime") String endDateTime);

    /**
     * 查询周报历史记录（只查询最近30周）
     * @param vipId 学生id
     * @return 历史记录列表
     */
    List<StudentWeeklyReportDTO> findWeeklyReportHistory(@Param("vipId") String vipId);

    /**
     * 查询月报历史记录（只查询最近12月）
     * @param vipId 学生id
     * @return 历史记录列表
     */
    List<MonthlyReportDTO> findMonthlyReportHistory(@Param("vipId") String vipId);

    /**
     * 根据给定知识点id列表，统计指定学生存在错题的知识点数量
     * @param vipId 学生id
     * @param type 5查询类型为打印图片，2查询类型为打印原题
     * @param knowledgeIdList 知识点id列表
     * @param version 知识点版本
     * @param beginDateTimeStr 开始时间
     * @param endDateTimeStr 结束时间
     * @return 存在错题的知识点数量
     */
    int countWrongQuestion(@Param("vipId") String vipId, @Param("type") Integer type,
                           @Param("knowledgeIdList") List<String> knowledgeIdList,
                           @Param("version") int version, @Param("beginDateTimeStr") String beginDateTimeStr,
                           @Param("endDateTimeStr") String endDateTimeStr);

    /**
     * 根据知识点列表查询错题题目的id
     *
     * @param page 分页
     * @param vipId 学生id
     * @param knowHowDetailList 知识点列表
     * @param beginDateTimeStr 开始时间
     * @param endDateTimeStr 结束时间
     * @return 题目id列表
     */
    List<String> findWrongQuestionId(@Param("page") IPage<WrongBookQuestionDTO> page, @Param("vipId") String vipId,
                                     @Param("knowHowDetailList") List<KnowHowDetailDTO> knowHowDetailList,
                                     @Param("beginDateTimeStr") String beginDateTimeStr,
                                     @Param("endDateTimeStr") String endDateTimeStr);

    /**
     * 根据学生id、科目、开始日期查询周报
     * @param vipId 学生id
     * @param subject 科目
     * @param beginDate 开始日期（如：2019-11-11）
     * @return 周报
     */
    StudentWeeklyReport findWeeklyReportByVipIdAndSubjectAndBeginDate(@Param("vipId") String vipId,
                                                                      @Param("subject") String subject,
                                                                      @Param("beginDate") String beginDate);

    /**
     * 查询错题涉及的考点
     * @param vipId 学生id
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @param knowHowDetailIdSet 知识点id集合
     * @return 考点id列表
     */
    List<String> findWrongQuestionHowDetailKdId(@Param("vipId") String vipId, @Param("beginTime") String beginTime,
                                                @Param("endTime") String endTime,
                                                @Param("knowHowDetailIdSet") Set<String> knowHowDetailIdSet);

    /**
     * 查询月报数据
     * @return 月报数据列表
     */
    List<HomeworkCount> findMonthlyReport(IPage<Object> page);

    /**
     * 统计每个学生每个知识点的错题情况
     *
     *
     * @param homeworkId 作业id
     * @param pageSize 查询记录数
     *
     * @return 统计结果
     */
    List<KnowledgeWrongQuestionCount> countWrongQuestionGroupByKnowledge(@Param("homeworkId") String homeworkId,
                                                                         @Param("pageSize") int pageSize);

    /**
     * 单科作业批改详情查询作业图片记录
     * @param homeworkId
     * @return
     */
    List<HomeworkPicture> findHomeworkCorrectDetailByHomeworkId(@Param("homeworkId") String homeworkId);

    /**
     * 查询指定月份的月报
     * @param objectPage 分页
     * @param targetMonthStr  月份（如：2019-12），为空则查询所有月份
     * @return 月报集合
     */
    List<HomeworkCount> findMonthlyReportByMonth(@Param("objectPage") Page<Object> objectPage,
                                                 @Param("targetMonthStr") String targetMonthStr);

    /**
     * 统计同年级学生总数（不包含目标学生）和月报得分低于目标学生的学生人数
     * @param vipId 目标学生的学生id
     * @param accuracyRate 目标学生的月报得分
     * @param grade 目标学生的年级
     * @param targetMonthStr 限定月份（如：2019-12）
     * @return 统计结果
     */
    Map<String, Object> countOthersAndAccuracyRateLessThan(@Param("vipId") String vipId,
                                                           @Param("accuracyRate") Integer accuracyRate,
                                                           @Param("grade") String grade,
                                                           @Param("targetMonthStr") String targetMonthStr);

    /**
     * 分页查询错题知识点统计数据
     * @param page 分页
     * @return 错题知识点统计数据列表
     */
    List<KnowledgeWrongQuestionCount> findWrongQuestionKnowledgeCount(@Param("page") Page<Object> page);

    /**
     * 删除错题知识点统计数据（标记为为已掌握）
     * @param homeworkId 作业计时记录id
     * @param knowHowDetailId 知识点id
     * @param knowledgeVersion 知识点版本
     */
    void deleteWrongQuestionKnowledgeCount(@Param("homeworkId") String homeworkId,
                                           @Param("knowHowDetailId") String knowHowDetailId,
                                           @Param("knowledgeVersion") String knowledgeVersion);

    /**
     * 查询昨日新增或昨日有做作业的学生的id和学校
     * @param page 分页
     * @param yesterdayDate 昨日日期
     * @return 学生的id和学校列表
     */
    List<Map<String, Object>> findHomeworkInfoYesterday(Page<Object> page, @Param("yesterdayDate") String yesterdayDate);

    /**
     * 查询学生上周所在年级
     *
     * @param vipId 学生id
     * @param beginDate 开始日期
     * @param endDateTime 结束日期时间
     * @return 年级（如：'三年级'）
     */
    @Select("select grade from scon_homework where vip_id = #{vipId} and create_time between #{beginDate} and #{endDateTime} order by create_time limit 1")
    String findGradeLastWeek(@Param("vipId") String vipId, @Param("beginDate") String beginDate,
                             @Param("endDateTime") String endDateTime);

    /**
     * 查询作业未采集到的知识点
     * @param vipId
     * @param grade
     * @param subject
     * @param semester
     * @param versionType
     * @return
     */
    List<String> findNoLearnKnowledgeList (@Param("vipId") String vipId,
                                           @Param("grade") String grade,
                                           @Param("subject") String subject,
                                           @Param("semester") int semester,
                                           @Param("versionType") int versionType);

    /**
     * 查询定制冲刺知识点
     * @param vipId
     * @param type
     * @return
     */
    List<SconStudentTermtainData> findStudentTermTrainDetailIdByVipId (@Param("vipId") String vipId,
                                                                       @Param("type") int type);

    /**
     * 更新是否需要更新错题知识点统计数据字段
     *  @param homeworkIdSet 作业id
     * @param newNeedUpdateWrongQuestionKnowledgeCount 新needUpdateWrongQuestionKnowledgeCount
     */
    void updateNeedUpdateWrongQuestionKnowledgeCount(@Param("homeworkIdSet") @NotEmpty Set<String> homeworkIdSet,
                                                     @Param("newNeedUpdateWrongQuestionKnowledgeCount") int newNeedUpdateWrongQuestionKnowledgeCount);

    /**
     * 更具作业id删除错题知识点统计数据
     *
     * @param homeworkId 作业id集合
     */
    void deleteWrongQuestionKnowledgeCountByHomeworkId(@Param("homeworkId") @NotBlank String homeworkId);

    /**
     * 删除scon_homework.need_update_wrong_question_knowledge_count=1的错题知识点统计数据
     */
    void deleteWrongQuestionKnowledgeCountWhichNeedUpdate();

    /**
     * 查询作业批改数据统计
     *
     * @param homeworkId 作业id
     *
     * @return 作业批改数据统计
     */
    @Select("select * from scon_homework_count where homework_id = #{homeworkId} and data_type = 1")
    HomeworkCount findHomeworkCountByHomeworkId(@Param("homeworkId") String homeworkId);

}