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

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

import org.apache.ibatis.annotations.Param;

import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dto.Mapper;
import com.ym.mec.biz.dal.dto.MusicGroupRegAndMoneyDto;
import com.ym.mec.biz.dal.dto.NoClassMusicStudentDto;
import com.ym.mec.biz.dal.dto.OrderStatisDto;
import com.ym.mec.biz.dal.dto.RegisterDto;
import com.ym.mec.biz.dal.dto.StudentApplyDetailDto;
import com.ym.mec.biz.dal.dto.StudentClassInfoDto;
import com.ym.mec.biz.dal.dto.StudentFeeDetailDto;
import com.ym.mec.biz.dal.dto.StudentInfo;
import com.ym.mec.biz.dal.dto.StudentMusicDetailDto;
import com.ym.mec.biz.dal.dto.StudentMusicGroupDto;
import com.ym.mec.biz.dal.dto.StudentOrganDto;
import com.ym.mec.biz.dal.dto.StudentRegisterInstrumentsDetailDto;
import com.ym.mec.biz.dal.dto.StudentRegisterPerDto;
import com.ym.mec.biz.dal.dto.SubjectApplyDetailDto;
import com.ym.mec.biz.dal.dto.UserGroupDto;
import com.ym.mec.biz.dal.entity.MusicGroup;
import com.ym.mec.biz.dal.entity.MusicGroupSubjectPlan;
import com.ym.mec.biz.dal.entity.StudentInstrument;
import com.ym.mec.biz.dal.entity.StudentRegistration;
import com.ym.mec.biz.dal.entity.Subject;
import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
import com.ym.mec.biz.dal.enums.StudentMusicGroupStatusEnum;
import com.ym.mec.common.dal.BaseDAO;

public interface StudentRegistrationDao extends BaseDAO<Long, StudentRegistration> {

    StudentRegistration lock(@Param("id") Long id);

    StudentRegistration lockWithUserAndMusic(@Param("userId") Integer userId,
                                             @Param("musicGroupId") String musicGroupId);

    /**
     * 获取乐团学员报名详情
     *
     * @param params
     * @return
     */
    List<StudentApplyDetailDto> queryStudentDetailPage(Map<String, Object> params);

    /**
     * 获取乐团学员报名详情条数
     *
     * @param params
     * @return
     */
    int queryStudentDetailCount(Map<String, Object> params);

    /**
     * 根据乐团编号获取缴费学员人数
     *
     * @param musicGroupId
     * @return
     */
    List<Map<Integer, Integer>> countPayNum(@Param("musicGroupId") String musicGroupId);

    /**
     * 学生报名缴费金额详情
     *
     * @param studentId
     * @param musicGroupId
     * @return
     */
    StudentFeeDetailDto queryFeeDetail(@Param("studentId") Integer studentId, @Param("musicGroupId") String musicGroupId);

    /**
     * 获取乐团声部未分配的班级的学生
     *
     * @param musicGroupId    乐团id
     * @param actualSubjectId 科目id
     * @return
     */
    List<StudentRegistration> getNoClassStuBySubjectId(@Param("musicGroupId") String musicGroupId, @Param("actualSubjectId") String actualSubjectId);

    /**
     * 获取乐团声部未分配学生数
     *
     * @param musicGroupId
     * @return
     */
    List<MusicGroupSubjectPlan> getNoClassStuCountByMusicGroupId(@Param("musicGroupId") String musicGroupId);

    /**
     * 根据乐团id和user_id 更新
     *
     * @param studentRegistration
     * @return
     */
    Integer updateByUserIdAndMusicGroupId(@Param("studentRegistration") StudentRegistration studentRegistration);

    /**
     * 查询学生信息
     *
     * @param userId
     * @return
     */
    StudentInfo queryStudentInfo(Integer userId);

    /**
     * 查询用户指定乐团的报名信息
     *
     * @param userId       用户编号
     * @param musicGroupId 乐团编号
     * @return
     */
    StudentRegistration queryByUserIdAndMusicGroupId(@Param("userId") Integer userId, @Param("musicGroupId") String musicGroupId);


    /**
     * 查询手机是否已注册
     *
     * @param musicGroupId
     * @param parentsPhone
     * @return
     */
    StudentRegistration getByPhoneAndMusicGroupId(@Param("musicGroupId") String musicGroupId, @Param("parentsPhone") String parentsPhone);

    /**
     * 查询用户是否存在
     *
     * @param phone
     * @return
     */
    SysUser getSysUserByPhone(String phone);

    /**
     * 获取班级学生
     *
     * @param musicGroupId
     * @param classGroupId
     * @return
     */
    List<StudentRegistration> findClassGroupStu(@Param("musicGroupId") String musicGroupId, @Param("classGroupId") Integer classGroupId);

    /**
     * 查询乐团的学生
     *
     * @param musicGroupId
     * @param actualSubjectId
     * @return
     */
    List<StudentRegistration> findMusicGroupNoClassGroupStudent(@Param("musicGroupId") String musicGroupId, @Param("actualSubjectId") Integer actualSubjectId);

    /**
     * 批量调剂学生专业
     *
     * @param userId
     * @param subId
     * @return
     */
    int batchUpdateSubject(@Param("userId") Integer userId, @Param("subId") Integer subId, @Param("musicGroupId") String musicGroupId);

    /**
     * 根据id list 查询报名学生
     *
     * @param idList
     * @return
     */
    List<StudentRegistration> findStudentListByIdList(@Param("idList") List<Long> idList);

    /**
     * 批量插入
     *
     * @param studentRegistrationList
     * @return
     */
    int batchInsert(@Param("list") List<StudentRegistration> studentRegistrationList);


    /**
     * 根据userId 和班级id查询学生
     *
     * @param userId
     * @param classGroupId
     * @return
     */
    StudentRegistration findStudentByClassGroupIdAndUserId(@Param("userId") Integer userId, @Param("classGroupId") Integer classGroupId);

    /**
     * 查询乐团声部下的学生
     *
     * @return
     */
    List<StudentRegistration> findMusicGroupStudent(@Param("musicGroupId") String musicGroupId, @Param("actualSubjectId") String actualSubjectId);

    /**
     * 查询乐团userIdList的学生
     *
     * @param musicGroupId
     * @param userIdList
     * @return
     */
    List<StudentRegistration> findStudentListByUserIdList(@Param("musicGroupId") String musicGroupId, @Param("userIdList") List<Integer> userIdList);

    /**
     * @param ids
     * @return
     */
    int batchOpenPay(@Param("ids") String ids, @Param("paymentStatus") PaymentStatusEnum paymentStatus);

    /**
     * 乐团添加学员
     *
     * @param studentRegistration
     */
    void insertBasic(StudentRegistration studentRegistration);

    /**
     * 获取乐团已缴费学员列表
     *
     * @param musicGroupId
     * @return
     */
    List<StudentRegistration> queryStudentByMusicGroupId(String musicGroupId);

    /**
     * 更新成团学员标记
     *
     * @param musicGroupId
     * @return
     */
    void updateOriginalFlag(String musicGroupId);

    /**
     * 统计乐团不同声部报名人数
     *
     * @param musicGroupId
     * @return
     */
    List<Map<Integer, Integer>> countApplyNum(String musicGroupId);

    /**
     * 根据家长手机号获取用户编号
     *
     * @param parentPhones
     * @return
     */
    List<Map<Integer, String>> findParentId(String parentPhones);

    /**
     * 查询学生数
     *
     * @return
     */
    Map<String, Integer> queryStudentNum(@Param("organId") String organId);

    /**
     * 根据乐团编号获取当前乐团所有已报名学员
     *
     * @param musicGroupId
     * @return
     */
    List<Map<Integer, String>> findMapByMusicGroupId(@Param("musicGroupId") String musicGroupId, @Param("paymentStatus") Integer paymentStatus);

    /**
     * 根据乐团编号获取当前乐团所有已报名学员
     *
     * @param musicGroupId
     * @return
     */
    List<Map<Integer, String>> findIdMapByMusicGroupId(@Param("musicGroupId") String musicGroupId, @Param("paymentStatus") Integer paymentStatus);

    /**
     * 乐团开启缴费
     *
     * @param musicGroupId
     * @param paymentStatus
     * @return
     */
    int musicGroupOpenPay(@Param("musicGroupId") String musicGroupId, @Param("paymentStatus") PaymentStatusEnum paymentStatus);

    /**
     * 删除班级学生
     *
     * @param classGroupId
     * @return
     */
    int deleteClassGroup(@Param("classGroupId") Integer classGroupId);

    int findMusicGroupStudentNum(@Param("musicGroupId") String musicGroupId);

    /**
     * 更新用户证件信息
     *
     * @return
     */
    int updateUser(@Param("id") Integer id,
                   @Param("name") String name,
                   @Param("realName") String realName,
                   @Param("idCardNo") String idCardNo,
                   @Param("gender") Integer gender,
                   @Param("certificateType") String certificateType);

    /**
     * 获取乐团在读人数
     *
     * @param musicGroupIds
     * @return
     */
    List<Map<String, Integer>> countNormalNum(String musicGroupIds);

    /**
     * 获取乐团在读人数
     *
     * @param musicGroupId
     * @return
     */
    List<Integer> queryNormalUserList(String musicGroupId);

    /**
     * 获取学员基本信息
     *
     * @param mobile
     * @return
     */
    StudentRegistration queryUserByPhone(String mobile);

    /**
     * 批量修改学生年级班级
     *
     * @param studentRegistration
     */
    void updateCurrentClass(StudentRegistration studentRegistration);

    /**
     * 获取乐团学员购买方式
     *
     * @param musicGroupId
     * @return
     */
    List<Map<Long, String>> queryPurchaseTypeMap(String musicGroupId);

    /**
     * 获取学员注册比例
     *
     * @return
     */
    List<StudentRegisterPerDto> queryStudentPer(@Param("userIds") Set<Integer> userIds);

    /**
     * 获取学员注册比例
     *
     * @return
     */
    List<StudentRegisterPerDto> queryStudentPer1(@Param("tenantId") Integer tenantId, @Param("month")String month);

    /**
     * 获取乐团报名信息和学校信息
     *
     * @param musicGroupId
     * @param userId
     * @return
     */
    StudentRegistration findStudentByMusicGroupIdAndUserId(@Param("musicGroupId") String musicGroupId, @Param("userId") Integer userId);

    /**
     * 获取学员所在乐团
     *
     * @param studentId
     * @return
     */
    List<String> queryStudentMusicGroup(Integer studentId);

    String getSubjectIds(Integer userId);

    /**
     * 获取乐团下所有学员身上的声部列表
     *
     * @param musicGroupId
     * @return
     */
    List<Subject> findMusicGroupAllStudentSubjects(@Param("musicGroupId") String musicGroupId);

    /**
     * 获取学员详情页，包含所在乐团信息
     *
     * @param studentId
     * @return
     */
    StudentMusicDetailDto getStudentDetail(Integer studentId);

    /**
     * 获取乐团的学生
     *
     * @param musicGroupId
     * @return
     */
    List<StudentRegistration> getMusicGroupStu(@Param("musicGroupId") String musicGroupId);

    /**
     * 获取老师对应乐团的学生
     *
     * @param musicGroupId
     * @param teacherId
     * @return
     */
    List<StudentRegistration> getMusicGroupStu4Teacher(@Param("musicGroupId") String musicGroupId, @Param("teacherId") Integer teacherId);

    StudentRegistration getStudentRegister(@Param("musicGroupId") String musicGroupId, @Param("studentId") Integer studentId);

    /**
     * 获取分部乐团在读学生数
     *
     * @return
     */
    List<OrderStatisDto> getOrganNormalStudent(Integer tenantId);

    /**
     * @param userIds:
     * @return java.util.List<com.ym.mec.biz.dal.dto.UserGroupDto>
     * @describe 获取学员关联乐团记录
     * @author qnc99
     * @date 2020/11/24 0024
     */
    List<UserGroupDto> getUserGroups(@Param("userIds") List<Integer> userIds);


    /**
     * 获取乐团未交费的学生
     *
     * @param musicGroupId
     * @return
     */
    List<StudentRegistration> getNoPaymentStudent(@Param("musicGroupId") String musicGroupId);

    /**
     * 获取乐团声部学生数量
     *
     * @return
     */
    Integer getMusicGroupSubjectStudentNum(@Param("musicGroupId") String musicGroupId, @Param("subjectIds") String subjectIds);

    /**
     * 查询用户所在乐团信息
     *
     * @param userId
     * @return
     */
    List<StudentMusicGroupDto> queryStudentMusicGroupInfo(@Param("userId") Integer userId, @Param("musicGroupId") String musicGroupId);

    /**
     * 获取学员剩余课程费用
     *
     * @param classGroupId
     * @param studentIds
     * @return
     */
    List<Map<Integer, BigDecimal>> querySurplusCourseFeeByClassGroupId(@Param("classGroupId") Integer classGroupId, @Param("studentIds") String studentIds);

    /**
     * 根据学员编号列表和乐团编号获取学员注册列表
     *
     * @param studentIds
     * @param musicGroupId
     * @return
     */
    List<StudentRegistration> queryByUserIdsAndMusicGroupId(@Param("studentIds") String studentIds, @Param("musicGroupId") String musicGroupId);

    /**
     * 批量删除注册信息
     *
     * @param ids
     * @return
     */
    int batchDelete(@Param("ids") List<Long> ids);

    /**
     * 获取学员声部名称
     *
     * @param musicGroupId
     * @param studentId
     * @return
     */
    String getStudentSubjectName(@Param("musicGroupId") String musicGroupId, @Param("studentId") Integer studentId);

    /**
     * 获取学员声部名称
     *
     * @param musicGroupId
     * @param studentIds
     * @return
     */
    List<Map<Integer, String>> getStudentSubjectNameByStuIds(@Param("musicGroupId") String musicGroupId, @Param("studentIds") Collection<Integer> studentIds);

    /**
     * 将学员报名缴费状态更新至已缴费
     *
     * @param calenderId
     */
    void updatePaymentStatusByClaenderId(Long calenderId);

    /**
     * @param studentIds:
     * @return java.util.List<com.ym.mec.biz.dal.entity.MusicGroup>
     * @describe 查询学员在读进行中乐团
     * @author Joburgess
     * @date 2021/1/29 0029
     */
    List<MusicGroup> getStudentNormalMusicGroups(@Param("studentIds") Set<Integer> studentIds);

    /**
     * @param userId:
     * @return com.ym.mec.biz.dal.entity.MusicGroup
     * @describe 获取学员最后加入的在读进行中乐团
     * @author Joburgess
     * @date 2021/2/28 0028
     */
    MusicGroup getUserLastNormalMusicGroup(@Param("userId") Integer userId);

    /**
     * @param studentIds:
     * @return java.util.List<com.ym.mec.biz.dal.entity.StudentRegistration>
     * @describe 查询学员在读进行中乐团报名信息
     * @author Joburgess
     * @date 2021/2/25 0025
     */
    List<StudentRegistration> getStudentNormalRegistration(@Param("studentIds") Set<Integer> studentIds);

    StudentRegistration getByUserIdAndMusicGroupId(@Param("musicGroupId") String musicGroupId, @Param("userId") Integer userId);

    List<NoClassMusicStudentDto> queryNoClassMusicStudents(Map<String, Object> params);

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


    List<StudentClassInfoDto> getStudentClassInfo(@Param("studentIds") List<Integer> studentIds);

    /**
     * 获取乐团已缴费学员数量
     *
     * @param musicGroupId
     * @return
     */
    Integer getPaymentStudentNum(@Param("musicGroupId") String musicGroupId);

    /**
     * 查找报名中的学员
     *
     * @param musicGroupId
     * @param studentIds
     * @return
     */
    StudentRegistration findApplyStudent(@Param("musicGroupId") String musicGroupId, @Param("studentIds") List<Integer> studentIds);

    /**
     * 乐团全部学生退团
     *
     * @param musicGroupId
     * @return
     */
    int quitAllStudent(@Param("musicGroupId") String musicGroupId, @Param("remark") String remark);

    /**
     * @param groupIds:
     * @return java.util.List<com.ym.mec.biz.dal.entity.StudentRegistration>
     * @describe 获取指定乐团中的注册学员
     * @author Joburgess
     * @date 2021/5/24 0024
     */
    List<StudentRegistration> findByMusicGroupIds(@Param("groupIds") List<String> groupIds,
                                                  @Param("musicGroupStatus") StudentMusicGroupStatusEnum musicGroupStatus);

    /**
     * 获取支付中的缴费和审核的人数
     *
     * @param musicGroupId
     * @param payingStatus
     * @return
     */
    List<Map<Integer, Integer>> countPayingNum(@Param("musicGroupId") String musicGroupId, @Param("payingStatus") Integer payingStatus);

    /**
     * 获取预报名或者报名的列表
     *
     * @param params
     * @return
     */
    List<RegisterDto> getRegisterOrPreList(Map<String, Object> params);


    /**
     * 获取预报名或者报名总数
     *
     * @param params
     * @return
     */
    int getRegisterOrPreCount(Map<String, Object> params);

    /**
     * 获取最小预报名时间和最小支付时间
     *
     * @return
     */
    RegisterDto getRegisterOrPreMinTime(@Param("musicGroupId") String musicGroupId);


    /**
     * 获取报名总人数
     *
     * @param musicGroupId
     * @return
     */
    int getRegisterNum(@Param("musicGroupId") String musicGroupId);

    /**
     * 获取某时间段的缴费人数
     *
     * @return
     */
    int getFirstPayNum(@Param("musicGroupId") String musicGroupId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);

    /**
     * 获取不在指定班级类型的学员列表
     * @param musicGroupId
     * @return
     */
    String getNotClassName(@Param("musicGroupId") String musicGroupId);

    /**
     * 是否有其他会员收费团
     * @param musicGroupId
     * @param userId
     * @return
     */
    boolean checkHasMemberGroup(@Param("musicGroupId") String musicGroupId, @Param("userId") Integer userId);

    /**
     * 获取报名缴费的相关人数
     *
     * @param musicGroupIds
     * @return
     */
    List<MusicGroupRegAndMoneyDto> getRegisters(@Param("musicGroupIds") List<String> musicGroupIds);

    /**
     * 获取已缴费审核中的人数
     * @param musicGroupId
     * @return
     */
    int countPayAndCheckNum(@Param("musicGroupId") String musicGroupId);

    /**
     * 获取所有在会员团，但是没有会员，并且没有待生效的学员
     * @param memberEndAutoQuitMusic
     * @return
     */
    List<StudentRegistration> queryMemberEndAutoQuitMusic(@Param("memberEndAutoQuitMusic") String memberEndAutoQuitMusic,
                                                          @Param("educationUserId") Integer educationUserId,
                                                          @Param("organIds") String organIds);

    /**
     * 获取所有在会员团，但是没有会员，并且没有待生效的学员
     * @param memberEndAutoQuitMusic
     * @return
     */
    List<Map<Integer, Integer>> queryOrganMemberEndAutoQuitMusic(@Param("memberEndAutoQuitMusic") String memberEndAutoQuitMusic,
                                                          @Param("educationUserId") Integer educationUserId,
                                                          @Param("organIds") Set<Integer> organIds);
    
    /**
     * 统计指定乐团在读的声部人数
     * @param musicGroupId
     * @return
     */
    List<Mapper> countStudentWithSubjectByMusicGroupId(String musicGroupId);

    /**
     * 统计各年级人数
     * @param musicGroupId
     * @return
     */
    List<Mapper> countStudentWithGradeByMusicGroupId(String musicGroupId);
    
    /**
     * 查询学生报名购买的乐器详情
     * @param params
     * @return
     */
    List<StudentRegisterInstrumentsDetailDto> queryStudentRegisterInstrumentsDetailList(Map<String, Object> params);
    
    int queryStudentRegisterInstrumentsDetailCount(Map<String, Object> params);
	
	List<SubjectApplyDetailDto> queryStudentApplyDetail(@Param("musicGroupId") String musicGroupId);

    void cleanMusicMember(@Param("userId") Integer userId, @Param("musicGroupId") String musicGroupId);

    /**
     * 会员结束前15天自动创建乐团缴费
     * @param pushMemberRenew
     * @return
     */
    List<Map<String,String>> queryAutoCreateStudentMap(@Param("pushMemberRenew") String pushMemberRenew, @Param("tenantId") Integer tenantId);

    /**
     * @describe 查询学员乐团名称字典
     * @author Joburgess
     * @date 2021/8/17 0017
     * @param studentIds:
     * @return java.util.List<java.util.Map<java.lang.Integer,java.lang.String>>
     */
    List<Map<Integer, String>> queryStudentMusicGroupNamesMap(@Param("studentIds") List<Integer> studentIds);

    List<Map<Integer, String>> queryStudentMusicGroupEduMap(@Param("studentIds") List<Integer> studentIds);

    List<Map<Integer, String>> queryStudentSchoolNamesMap(@Param("studentIds") List<Integer> studentIds);

    /**
     * 获取进行中在读的学员列表
     * @return
     */
    List<Integer> findStudentIds(Integer tenantId);

    /**
    * @description: 获取乐团在读学员乐保信息
     * @param params
    * @return java.util.List<com.ym.mec.biz.dal.entity.StudentInstrument>
    * @author zx
    * @date 2021/11/9 10:40
    */
    List<StudentInstrument> queryMusicStudentInstrument(Map<String, Object> params);

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

    /**
    * @description: 获取乐团在读和有乐保的人数
     * @param musicGroupIds
    * @return java.util.List<com.ym.mec.biz.dal.entity.MusicGroup>
    * @author zx
    * @date 2021/11/10 17:55
    */
    List<MusicGroup> countInstrument(@Param("musicGroupIds") List<String> musicGroupIds);

    /**
    * @description: 获取分部缴费总金额
     * @param musicGroupId
    * @return java.util.List<java.util.Map<java.lang.Integer,java.math.BigDecimal>>
    * @author zx
    * @date 2021/11/16 10:26
    */
    List<Map<Long,BigDecimal>> querySubjectAmount(String musicGroupId);

    /**
    * @description: 获取学员最近加入的一个乐团编号
     * @param userIds
    * @return java.lang.String
    * @author zx
    * @date 2022/3/16 14:10
    */
    List<Map<Integer,String>> getLastMusicGroupId(@Param("userIds") List<Integer> userIds);

    /**
    * @description: 获取学员最近加入的一个乐团编号
     * @param userIds
    * @return java.lang.String
    * @author zx
    * @date 2022/3/16 14:10
    */
    List<Map<Integer,String>> getLastMusicGroupName(@Param("userIds") List<Integer> userIds);
    
    List<StudentRegistration> queryServiceStudentByMusicGroupStatus(@Param("nextMonday") String nextMonday,@Param("tenantId") Integer tenantId);
    
    List<StudentOrganDto> queryEffectiveStudent(@Param("organIds") List<Integer> organIds);
}
