package com.ym.mec.biz.dal.dao;

import com.ym.mec.biz.dal.dto.*;
import com.ym.mec.biz.dal.entity.CourseSchedule;
import com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment;
import com.ym.mec.biz.dal.entity.CourseScheduleStudentPaymentDto;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.common.dal.BaseDAO;

import org.apache.ibatis.annotations.Param;

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

public interface CourseScheduleStudentPaymentDao extends BaseDAO<Long, CourseScheduleStudentPayment> {

    /**
     * @return int
     * @Author: Joburgess
     * @Date: 2019/10/10
     * @params [courseScheduleStudentPayments]
     * @describe 批量插入
     */
    int batchInsert(List<CourseScheduleStudentPayment> courseScheduleStudentPayments);

    /**
     * @param courseScheduleStudentPayments:
     * @return int
     * @describe 批量更新
     * @author Joburgess
     * @date 2020/1/10
     */
    int batchUpdate(@Param("courseScheduleStudentPayments") List<CourseScheduleStudentPayment> courseScheduleStudentPayments);

    /**
     * @return java.util.List<com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment>
     * @Author: Joburgess
     * @Date: 2019/10/15
     * @params [ids]
     * @describe 根据课程编号批量获取学生缴费信息
     */
    List<CourseScheduleStudentPayment> findByCourseScheduleIds(@Param("ids") List<Long> ids);

    /**
     * 删除学生对应的课程
     *
     * @param userId
     * @param courseScheduleList
     * @return
     */
    int deleteStudentCourseSchedule(@Param("userId") Integer userId, @Param("courseScheduleIdList") List<Long> courseScheduleIdList);

    /**
     * @param courseScheduleIds: 课程编号列表
     * @return int
     * @describe 批量删除课程对应的学生缴费记录
     * @author Joburgess
     * @date 2019/10/31
     */
    int deleteByCourseSchedule(@Param("courseScheduleIds") List<Long> courseScheduleIds);

    /**
     * @param params: 班级编号
     * @return java.util.List<com.ym.mec.biz.dal.dto.StudentAttendanceStatisticsResp>
     * @describe 获取指定班级中的学生
     * @author Joburgess
     * @date 2019/10/28
     */
    List<StudentAttendanceStatisticsResponse> findStudentByClassGroup(Map<String, Object> params);

    int countStudentByClassGroup(Map<String, Object> params);

    /**
     * @param classGroupId: 班级编号
     * @param userId:       学生编号
     * @return java.math.BigDecimal
     * @describe 统计学生剩余课时的费用
     * @author Joburgess
     * @date 2019/11/15
     */
    BigDecimal countSurplusCourseFee(@Param("classGroupId") Integer classGroupId,
                                     @Param("userId") Integer userId);

    /**
     * @param classGroupId: 班级编号
     * @return java.math.BigDecimal
     * @describe 统计所有课时的购买费用
     * @author Joburgess
     * @date 2019/11/27
     */
    BigDecimal countAllCourseFee(@Param("classGroupId") Integer classGroupId);

    /**
     * @param ids: 学生课程缴费信息编号
     * @return int
     * @describe 删除用户在指定班级上的课程
     * @author Joburgess
     * @date 2019/12/3
     */
    int batchDeleteWithID(@Param("ids") List<Integer> ids);


//    int batchDeleteWithCourseAndUser(@Param("courseScheduleIds") List<Integer> courseScheduleIds,
//                                     @Param("userId") Integer userId);

    /**
     * @param classGroupId:
     * @param userId:
     * @return java.util.List<java.lang.Integer>
     * @describe 获取用户在指定班级上缴费记录编号
     * @author Joburgess
     * @date 2019/12/3
     */
    List<Integer> findNotStartCourseStudentPaymentIdsWithClassGroupAndStudent(@Param("classGroupId") Integer classGroupId,
                                                                              @Param("userId") Integer userId);
    /**
     * @param classGroupId:
     * @param userId:
     * @return java.util.List<java.lang.Integer>
     * @describe 获取用户在指定班级上缴费记录编号
     * @author Joburgess
     * @date 2019/12/3
     */
    List<CourseScheduleStudentPayment> findNotStartCourseStudentPaymentsWithClassGroupAndStudent(@Param("classGroupId") Integer classGroupId,
                                                                              @Param("userId") Integer userId);

    /**
     * @param groupId:
     * @param groupType:
     * @return int
     * @describe 统计团体下为开始课程学生数量
     * @author Joburgess
     * @date 2020.09.27
     * @describe 统计团体下为开始课程学生数量
     * @author Joburgess
     * @date 2020.09.27
     */
    int countNotStartCourseStudentNumWithGroup(@Param("groupId") String groupId,
                                               @Param("groupType") GroupType groupType);

    /**
     * @param vipGroupId: 小课编号
     * @param teachMode:  教学形式
     * @return java.math.BigDecimal
     * @describe 获取小课指定形式下最后一节课的课程单价
     * @author Joburgess
     * @date 2019/12/5
     */
    BigDecimal findVipGroupCoursePrice(@Param("vipGroupId") Integer vipGroupId,
                                       @Param("teachMode") String teachMode);

    int deleteStudentCourseScheduleByUserId(@Param("courseScheduleId") Long courseScheduleId, @Param("userIdList") List<Integer> userIdList);

    /**
     * 根据乐团编号删除记录
     *
     * @param musicGroupId
     * @return
     */
    int deleteByMusicGroupId(@Param("musicGroupId") String musicGroupId, @Param("groupType") GroupType groupType);

    /**
     * 根据乐团编号，和groupTYpe获取学员剩余课程数
     *
     * @param musicGroupIds
     * @param userId
     * @param groupType
     * @return
     */
    List<Map<String, Integer>> findStudentCourseNum(@Param("musicGroupIds") Set<String> musicGroupIds, @Param("userId") Integer userId, @Param("groupType") String groupType);

    /**
     * @param groupType:
     * @param groupId:
     * @return int
     * @describe 统计指定乐团下学员课程数量
     * @author Joburgess
     * @date 2019/12/23
     */
    int countStudentCourseNumWithGroup(@Param("groupType") GroupType groupType,
                                       @Param("groupId") String groupId);

    /**
     * 根据乐团，vip状态获取编号
     *
     * @return
     */
    Set<Integer> queryMusicStudentPer(Integer tenantId);

    /**
     * 根据乐团，vip状态获取编号
     *
     * @return
     */
    Set<Integer> queryVipStudentPer(Integer tenantId);

    /**
     * @param courseIds: 统计课程上的学生人数
     * @return java.util.List<java.util.Map < java.lang.Integer, java.lang.Integer>>
     * @describe
     * @author Joburgess
     * @date 2020/1/8
     */
    List<Map<Long, Long>> countCourseStudentNum(@Param("courseIds") List<Long> courseIds);

    /**
     * @param courseScheduleId:
     * @param userId:
     * @return int
     * @describe 检测学生是否存在指定课程的缴费记录
     * @author Joburgess
     * @date 2020/1/10
     */
    int checkStudentHaveCourse(@Param("courseScheduleId") Long courseScheduleId,
                               @Param("userId") Integer userId);

    /**
     * @param courseScheduleId: 课程编号
     * @return java.util.List<com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment>
     * @describe 查询指定课程的学生缴费记录
     * @author Joburgess
     * @date 2020/1/10
     */
    List<CourseScheduleStudentPayment> findByCourseSchedule(@Param("courseScheduleId") Long courseScheduleId);

    /**
     * @param mainMergeCourseId:
     * @return java.util.List<com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment>
     * @describe 获取合并课程的学员缴费记录
     * @author Joburgess
     * @date 2021/1/21 0021
     */
    List<CourseScheduleStudentPayment> findByMainMergedCourse(@Param("mainMergeCourseId") Long mainMergeCourseId);

    /**
     * @param groupId:
     * @return java.util.List<com.ym.mec.biz.dal.dto.VipGroupGiveCourseSortDto>
     * @describe 获取小课需要调整的缴费记录
     * @author Joburgess
     * @date 2020/1/10
     */
    List<VipGroupGiveCourseSortDto> findVipGroupSortCourseByGroup(@Param("groupId") String groupId);

    /**
     * 获取课程学员数量
     *
     * @param courseScheduleId
     * @return
     */
    Integer countStudentNum(Integer courseScheduleId);

    /**
     * @param courseScheduleId:
     * @return int
     * @describe 统计课程学员数量
     * @author Joburgess
     * @date 2021/2/9 0009
     */
    int countCourseOnlyStudentNum(@Param("courseScheduleId") Long courseScheduleId);

    /**
     * @param groupId:
     * @param groupType:
     * @return int
     * @describe 根据团体删除班级
     * @author Joburgess
     * @date 2020/2/17
     */
    int deleteByGroup(@Param("groupId") String groupId,
                      @Param("groupType") GroupType groupType);

    /**
     * 获取当前课程的学员列表
     *
     * @param courseScheduleId
     * @return
     */
    List<BasicUserDto> findStudents(Long courseScheduleId);

    /**
     * 获取课程的学员编号列表
     *
     * @param courseScheduleIds
     * @return
     */
    List<Map<Integer, String>> getStudentIdMap(@Param("courseScheduleIds") List<Long> courseScheduleIds);

    Integer findNoPracticeStudentTeacherId(@Param("studentId") Integer studentId);

    /**
     * 从指定时间开始查询学的线上可数
     *
     * @return
     */
    List<StudentCourseTimesDto> queryStudentNotStartCourseTimesOfOnline();

    List<StudentTeacherCourseDto> findAllStudentCourseInfo(Integer tenantId);

    /**
     * @param courseScheduleIds:
     * @return java.util.List<java.util.Map < java.lang.Long, java.math.BigDecimal>>
     * @describe 统计每节课的收款
     * @author Joburgess
     * @date 2020.05.09
     */
    List<Map<Long, BigDecimal>> findCoursePayment(@Param("courseScheduleIds") List<Long> courseScheduleIds);

    /**
     * 获取学员指定课程类型的剩余课时数
     *
     * @param studentId
     * @param courseScheduleType
     * @return
     */
    int countStudentNotStartCourseNumWithCourseType(@Param("studentId") Integer studentId,
                                                    @Param("courseScheduleType") CourseSchedule.CourseScheduleType courseScheduleType);
    List<Map<Integer, Integer>> countStudentsNotStartCourseNumWithCourseType(@Param("studentIds") List<Integer> studentIds,
                                                    @Param("courseScheduleType") CourseSchedule.CourseScheduleType courseScheduleType);

    /**
     * 批量操作节拍器状态
     *
     * @param courseScheduleId
     * @param userId
     */
    void adjustPlayMidi(@Param("courseScheduleId") long courseScheduleId, @Param("userId") String userId, @Param("content") String content);

    /**
     * 获取用户的节拍器信息
     *
     * @param userIds
     * @param courseScheduleId
     * @return
     */
    List<Map<Integer, String>> queryMidiByUserIdsAndCourseId(@Param("userIds") Set<String> userIds, @Param("courseScheduleId") String courseScheduleId);

    /**
     * 获取用户的曲目下载信息
     *
     * @param userIds
     * @param courseScheduleId
     * @return
     */
    List<Map<Integer, String>> queryExamSongByUserIdsAndCourseId(@Param("userIds") Set<String> userIds, @Param("courseScheduleId") String courseScheduleId);

    /**
     * 获取单个用户的midi
     *
     * @param courseScheduleId
     * @param userId
     * @return
     */
    String getMidiByCourseIdAndUserId(@Param("courseScheduleId") String courseScheduleId, @Param("userId") String userId);

    /**
     * 获取单个用户的examDownloadJson
     *
     * @param courseScheduleId
     * @param userId
     * @return
     */
    String getExamJsonByCourseIdAndUserId(@Param("courseScheduleId") Long courseScheduleId, @Param("userId") Integer userId);

    /**
     * @param groupType:
     * @param groupIds:
     * @return java.util.List<java.util.Map < java.lang.String, java.math.BigDecimal>>
     * @describe 统计课程组下的课程单价
     * @author Joburgess
     * @date 2020.06.11
     */
    List<Map<String, BigDecimal>> findGroupCoursesUnitPrice(@Param("groupType") GroupType groupType,
                                                            @Param("groupIds") List<String> groupIds);

    /**
     * 获取未进入教室的学员列表
     *
     * @param roomId
     * @param courseScheduleId
     * @return
     */
    List<RongyunBasicUserDto> queryNoJoinStu(@Param("roomId") String roomId, @Param("courseScheduleId") String courseScheduleId);

    /**
     * @param batchNo:
     * @return java.util.List<com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment>
     * @describe 根据批次号获取学员课程缴费记录
     * @author Joburgess
     * @date 2020.10.30
     */
    List<CourseScheduleStudentPayment> findByBatchNo(@Param("batchNo") String batchNo);


    /**
     * 获取学生班级未开始的课程
     */
    List<CourseScheduleStudentPayment> getClassGroupNoStartCourse(@Param("classGroupIds") List<Integer> classGroupIds);


    /**
     * @param StudentIds:
     * @return java.util.List<java.util.Map < java.lang.Integer, java.util.Date>>
     * @describe 获取指定学员的最后一节课时间
     * @author Joburgess
     * @date 2020/11/17 0017
     */
    List<Map<Integer, Date>> findStudentLastCourseSchedule(@Param("studentIds") List<Integer> StudentIds);

    List<CourseScheduleStudentPayment> queryAll(Map<String, Object> params);

    int countAll(Map<String, Object> params);

    /**
     * 修改学员曲目下载信息
     *
     * @param roomId
     * @author zouxuan
     */
    int adjustExamSong(@Param("roomId") Long roomId, @Param("userId") Integer userId, @Param("examSongJson") String examSongJson);

    /**
     * @param userIds:
     * @param activityIds:
     * @return java.util.List<com.ym.mec.biz.dal.dto.StudentVipDouble11Dto>
     * @describe 统计学员通过双十一活动排课的数量
     * @author qnc99
     * @date 2020/11/25 0025
     */
    List<StudentVipDouble11Dto> countStudentDouble11CourseTime(@Param("userIds") List<Integer> userIds,
                                                               @Param("specialActivityIds") List<Integer> specialActivityIds);

    /**
     * @return java.util.List<com.ym.mec.biz.dal.entity.CourseScheduleStudentPaymentDto>
     * @describe 获取需要更新课营收的课程
     * @author qnc99
     * @date 2020/12/2 0002
     */
    List<CourseScheduleStudentPaymentDto> findNeedUpdateActualPriceStudentCourses(@Param("groupIds") List<String> groupIds,
                                                                                  @Param("userIds") List<Integer> userIds,
                                                                                  @Param("groupType") GroupType groupType);

    /**
     * 根据课程编号和，学员编号获取列表信息
     *
     * @param courseIds
     * @param studentId
     * @return
     * @author zouxuan
     */
    List<CourseScheduleStudentPayment> queryCourseByIdsAndStudentId(@Param("courseIds") List<Long> courseIds, @Param("studentId") Integer studentId, @Param("courseType") String courseType);

    /**
     * 获取班级学员关联的编号
     *
     * @param classGroupIds
     * @param studentIds
     * @return
     * @zouxuan
     */
    List<Long> queryStudentNotStartByClassIdsAndStudentIds(@Param("classGroupIds") List<Integer> classGroupIds, @Param("studentIds") List<Integer> studentIds);

    /**
     * 获取指定列表中学员的费用列表
     *
     * @param studentPaymentIds
     * @param studentId
     * @return
     * @author zouxuan
     */
    List<CourseScheduleStudentPayment> queryByIdsAndStudentId(@Param("studentPaymentIds") List<Long> studentPaymentIds, @Param("studentId") Integer studentId, @Param("courseType") String courseType);

    /**
     * @param groupId:
     * @param groupType:
     * @return java.math.BigDecimal
     * @describe 统计课程组已经开始的课程的应缴费用
     * @author qnc99
     * @date 2020/12/8 0008
     */
    BigDecimal countFinishCoursePriceWithMusicGroup(@Param("groupId") String groupId,
                                                    @Param("groupType") GroupType groupType,
                                                    @Param("userId") Integer userId);

    /**
     * @param studentId:
     * @param monday:
     * @return com.ym.mec.biz.dal.entity.CourseSchedule
     * @describe 获取学生指定日期之前指定类型的最后一节课
     * @author Joburgess
     * @date 2020/12/25 0025
     */
    CourseSchedule getStudentHistoryLastCourse(@Param("studentId") Integer studentId,
                                               @Param("monday") String monday,
                                               @Param("groupId") String groupId,
                                               @Param("courseType") CourseSchedule.CourseScheduleType courseType);

    /**
     * 获取学员对应课程类型剩余课程价值
     *
     * @param studentId
     * @param classGroupId
     * @param courseType
     * @return
     */
    BigDecimal querySubCoursePriceMap(@Param("studentId") Integer studentId, @Param("classGroupId") Integer classGroupId, @Param("courseType") String courseType);


    /**
     * 获取课程的人数
     *
     * @param courseIds
     * @return
     */
    List<CourseSchedule> getCourseScheduleStudentNum(@Param("courseIds") List<Long> courseIds);

    List<CourseScheduleStudentPayment> getWithClassGroupIds(@Param("classGroupIds") List<Integer> classGroupIds,
                                                            @Param("studentId") Integer studentId);

    List<CourseScheduleStudentPayment> getWithGroup(@Param("groupId") String groupId,
                                                    @Param("groupType") GroupType groupType,
                                                    @Param("studentIds") List<Integer> studentIds);

    /**
     * 获取学生VIP课的教务老师
     *
     * @return
     */
    String getStudentEduTeacher(@Param("studentId") Integer studentId);

    /**
     * 删除关联的预排课课程
     * @param musicGroupId
     */
    void deletePreCourse(String musicGroupId);

    /**
     * @describe 查询出指定学员中有小课的学员
     * @author Joburgess
     * @date 2021/8/17 0017
     * @param studentIds:
     * @return java.util.Set<java.lang.String>
     */
    Set<Integer> getHasVipCourseStudentIds(@Param("studentIds") List<Integer> studentIds);

    /**
     * @describe 查询分部还有小课和网管课的学员数量
     * @author Joburgess
     * @date 2021/8/18 0018
     * @param studentIds:
     * @return java.util.List<java.util.Map<java.lang.Integer,java.lang.Integer>>
     */
    int getHasVPCourseStudentNum(@Param("organId") Integer organId);
    List<Map<Integer, Integer>> getOrganHasVPCourseStudentNum(@Param("organIds") List<Integer> organIds);

    /**
     * 获取课程学员列表
     * @param courseScheduleId
     * @return
     */
    List<BasicUserDto> getCourseStudents(@Param("courseScheduleId") Long courseScheduleId);

    /**
    * @description: 当前分部是否有vip，网管课
     * @param organId
    * @return boolean
    * @author zx
    * @date 2021/11/5 11:30
    */
    Boolean hasCourse(@Param("organId") String organId, @Param("tenantId") Integer tenantId);

    /**
    * @description:  报表中心学员小课记录导出
     * @param organId
    * @return java.util.List<com.ym.mec.biz.dal.dto.StudentVipPracticeExportDto>
    * @author zx
    * @date 2021/11/5 11:54 
    */
    List<StudentVipPracticeExportDto> exportStudentVipPractice(@Param("organId") String organId, @Param("tenantId") Integer tenantId);

    List<BaseNameDto> queryLastOverTeacher(@Param("studentIds") List<Integer> studentIds, @Param("groupType") String groupType);

    List<Mapper> queryUserMusicGroupCourseNumByClassTime(@Param("groupType") GroupType groupType, @Param("musicGroupIds") Set<String> musicGroupIds,
			@Param("userId") Integer userId, @Param("startDate") Date startDate, @Param("endDate") Date endDate);

	Boolean hasStudentMusicTheoryCourseInfo(@Param("organId") String organId, @Param("tenantId") Integer tenantId, @Param("groupType") String groupType);

    List<ExportStudentCourseInfoDto> queryStudentCourseInfo(@Param("organId") String organId, @Param("tenantId") Integer tenantId, @Param("groupType") String groupType);

    /**
    * @description: 获取学员第一个课程组编号
     * @param groupType
    * @return int
    * @author zx
    * @date 2022/3/16 10:32
    */
    List<Map<Integer,Integer>> findUserFirstVipMap(@Param("groupType") String groupType, @Param("studentIds") List<Integer> studentIds);

    /**
    * @description: 获取学员声部班老师
     * @param studentIds
    * @return java.util.List<com.ym.mec.biz.dal.dto.BaseNameDto>
    * @author zx
    * @date 2022/3/16 18:57
    */
    List<BaseNameDto> queryClassTeacher(@Param("studentIds") List<Integer> studentIds);

    List<BaseNameDto> queryFirstNotStartTeacher(@Param("studentIds") List<Integer> studentIds, @Param("groupType") String groupType);

    List<ExportVipStudentCourseManageDto> queryVipStudentCourseManage(@Param("organId") String organId, @Param("tenantId") Integer tenantId);
    
    /**
     * 查询有剩余课程学生列表
     * @param organIds
     * @return
     */
    List<StudentOrganDto> queryRemainCourseStudent(@Param("organIds") List<Integer> organIds);

}
