package com.ym.mec.biz.service;

import com.ym.mec.biz.dal.dto.*;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType;
import com.ym.mec.biz.dal.enums.AuditStatusEnum;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.TeachModeEnum;
import com.ym.mec.biz.dal.enums.YesOrNoEnum;
import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
import com.ym.mec.biz.dal.page.StudentCourseScheduleRecordQueryInfo;
import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.QueryInfo;
import com.ym.mec.common.service.BaseService;
import org.springframework.web.bind.annotation.RequestBody;

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

public interface CourseScheduleService extends BaseService<Long, CourseSchedule> {
	
	/**
	 * 查询课程信息
	 * @param courseScheduleId
	 * @return
	 */
	CourseSchedule queryById(Long courseScheduleId);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/10
	 * 根据课程ID获取当前课程的信息
	 */
	TeacherAttendanceDto getCurrentCourseDetail(Long courseID);

	/**
	 * @describe 根据课程编号删除课程计划及对应的学生缴费、教师课酬记录、教师签到记录
	 * @author Joburgess
	 * @date 2019/10/31
	 * @param courseScheduleIds: 课程计划编号列表
	 * @return int
	 */
	void batchDeleteCourseSchedules(List<Long> courseScheduleIds);

	void batchDeleteCourseSchedulesWithoutCheck(List<CourseSchedule> courseScheduleList);

	/**
	 * @describe 删除乐团下所有未上的课时
	 * @author Joburgess
	 * @date 2019/11/16
	 * @param musicGroupId:
	 * @return void
	 */
	void batchDeleteMusicGroupNotStartCourse(String musicGroupId,GroupType groupType);

	void batchDeleteMusicGroup(String musicGroupId,GroupType groupType);

	/**
	 * @describe 删除指定乐团下指定状态的课程
	 * @author Joburgess
	 * @date 2019/11/26
	 * @param musicGroupId: 乐团编号
	 * @param userId: 用户编号
	 * @param groupType: 乐团类型
	 * @return void
	 */
	void batchDeleteMusicGroupCourseWithStudent(String musicGroupId, Integer userId, GroupType groupType);


	/**
	 * @describe 判断该课程是否只能进行正常签到
	 * @author Joburgess
	 * @date 2019/11/5
	 * @param startClassTime: 课程开始时间
	 * @param userId: 教师编号
	 * @param checkSchool: 是否判断教学点
	 * @param schoolId: 学校编号
	 * @return com.ym.mec.biz.dal.enums.YesOrNoEnum
	 */
	YesOrNoEnum enableOnlyNormalAttendance(Date startClassTime,Long userId,boolean checkSchool,Integer schoolId);

	/**
	 * @describe 检测是否可以忽略正常签到时间限制
	 * @author Joburgess
	 * @date 2020.10.21
	 * @param startClassTime: 当前课程开始时间
	 * @param teacherId: 当前课程上课教师编号
	 * @param schoolId：当前课程教学点编号
	 * @return boolean
	 */
	boolean enableIgnoreAttendanceTime(Date startClassTime, Integer teacherId, Integer schoolId);
	
	/**
	 * 给班级加课
	 * @param classGroupId 班级编号
	 * @param coursesTimes 增加的课次
	 * @param startDate 排课开始时间
	 * @param startDate 排课结束时间
	 * @param teachingArrangementList 教学安排（周几，几点-几点）
	 * @param teachMode 教学模式
	 * @param type 课程类型
	 * @param schoolId 教学点
	 * @param isJumpHoliday 是否跳过节假日
	 * @return
	 */
	boolean batchAddCourseSchedule(Integer classGroupId, int coursesTimes, Date startDate, Date groupEndDate, Date groupStartDate, List<CourseTimeDto> teachingArrangementList,
			TeachModeEnum teachMode, CourseScheduleType type, Integer schoolId, boolean isJumpHoliday);
	
	/**
	 * 批量调整
	 * @param batchInsertCoursesDto
	 * @return
	 */
	boolean batchUpdateCourseSchedule(BatchInsertCoursesDto batchInsertCoursesDto);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 批量插入课程计划
	 */
	void batchAddCourseSchedule(List<CourseSchedule> courseSchedules);

	/**
	 * @describe 创建乐团课课程计划
	 * @author Joburgess
	 * @date 2019/10/24
	 * @param courseSchedules: 课程计划列表
	 * @return void
	 */
	void createCourseSchedules(CreateCourseScheduleDto createCourseScheduleDto);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 批量更新课程计划
	 */
	void batchUpdateCourseSchedule(List<CourseSchedule> courseSchedules, String musicGroupID);


	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 根据日期获取当日排课信息
	 */
	Map getStudentCourseSchedulesWithDate(Date classDate);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 根据日期获取当日排课信息
	 */
	List<CourseScheduleDto> getTeacherCourseSchedulesWithDate(Integer userId, Date classDate, String type);

	/**
	 * @describe 根据日期获取
	 * @author Joburgess
	 * @date 2019/12/26
	 * @param userId:
	 * @param classDate:
	 * @return java.util.List<com.ym.mec.biz.dal.dto.CourseScheduleDto>
	 */
	List<CourseScheduleDto> getTeacherHistoryCourseSchedulesWithDate(Integer userId, Date classDate);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 根据日期获取当日排课信息
	 */
	PageInfo getCourseSchedulesWithDateByEdu(CourseScheduleQueryInfo queryInfo);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 根据月份获取乐团在该月有课的日期
	 */
	List<Date> getCourseScheduleDateByMonth(Long musicGroupID, Date month);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 根据学生获取乐团在该月有课的日期
	 */
	List<Date> getCourseScheduleDateByStudent(Date month, Integer isAttend);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/17
	 * 获取教师在该月有课的日期
	 */
	List<Date> getCourseScheduleDateByTeacher(Date month, String type);

	/**
	 * @describe
	 * @author Joburgess
	 * @date 2019/12/26
	 * @param month:
	 * @return java.util.List<java.util.Date>
	 */
	List<Date> getHistoryCourseScheduleDateByTeacher(Integer userId,Date month);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/10/11
	 * @params [month]
	 * @return java.util.List<java.util.Date>
	 * @describe 获取
	 */
	List<Date> getCourseScheduleDates(Date month, String organIdList, String type);

	/**
	 * @describe 课程调整
	 * @author Joburgess
	 * @date 2019/11/7
	 * @param newCourseSchedules: 课程计划列表
	 * @return void
	 */
	void courseAdjust(List<CourseSchedule> newCourseSchedules);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/23
	 * 课时调整
	 */
	void classStartDateAdjust(List<CourseSchedule> newCourseSchedules);

	/**
	 * @describe 小课课程批量调整
	 * @author Joburgess
	 * @date 2019/12/11
	 * @param vipGroupCourseAdjustInfo: 调整信息
	 * @return void
	 */
	void vipCourseAdjust(VipGroupCourseAdjustInfoDto vipGroupCourseAdjustInfo);

	/**
	 * @describe 课程顺延
	 * @author Joburgess
	 * @date 2020/1/2
	 * @param coursePostPoneInfo:
	 * @return void
	 */
	void coursePostpone(CoursePostponeDto coursePostPoneInfo);

	/**
	 * @describe vip课批量新增-后端处理
	 * @author Joburgess
	 * @date 2019/12/12
	 * @param vipGroupCourseAdjustInfoDto: 加课信息
	 * @return void
	 */
	void batchAppendVipGroupCourses(VipGroupCourseAdjustInfoDto vipGroupCourseAdjustInfoDto);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/24
	 * 课程交换
	 */
	void courseSwap(Long courseScheduleId1, Long courseScheduleId2);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/10/14
	 * @params [day1, day2]
	 * @return void
	 * @describe 对调两天的课程
	 */
	void courseSwapWithDay(Date day1, Date day2);

	/**
	 * @describe 课程时间调整
	 * @author Joburgess
	 * @date 2020.09.09
	 * @param courseSchedules:
	 * @return
	 */
	void courseAdjustOnlyWithClassDate(@RequestBody List<CourseSchedule> courseSchedules, Integer operatorId);

	/**
	 * @describe 课程时间调整
	 * @author Joburgess
	 * @date 2020.09.0
	 * @return void
	 */
	Map<String, List<CourseSchedule>> courseAdjustOnlyWithClassDateCheck(VipGroupCourseAdjustInfoDto courseAdjustInfo);

	/**
	 * @describe 单节课程冲突检测及时间校正
	 * @author Joburgess
	 * @date 2020.09.09
	 * @param courseSchedule:
	 * @return void
	 */
	boolean checkSingleCourseConflict(CourseSchedule courseSchedule, List<CourseSchedule> adjustCourses, Map<String, List<CourseSchedule>> result);

	/**
	 * @describe 课程时间校正，将冲突课程的时间校正到当天空闲时间段
	 * @author Joburgess
	 * @date 2020.09.09
	 * @param courseSchedule:
	 * @param sameDayCourses:
	 * @return void
	 */
	boolean courseTimeRevise(CourseSchedule courseSchedule, List<CourseSchedule> sameDayCourses);

	/**
	 * @describe 检测数据库不存在的课程是否存在错误
	 * @author Joburgess
	 * @date 2019/10/31
	 * @param courseSchedules: 课程列表
	 * @param postponeFlag: 如果冲突是否顺延
	 * @return void
	 */
	Boolean checkNewCourseSchedules(List<CourseSchedule> courseSchedules,boolean checkExistCourseSchedule,Boolean postponeFlag);

	void checkNewCourseSchedulesWithoutMusicGroup(List<CourseSchedule> courseSchedules,boolean checkExistCourseSchedule);

	/**
	 * @describe 临时课检测
	 * @author 周剑河
	 * @date 2019/12/6
	 * @param courseSchedules: 课程计划列表
	 * @return void
	 */
	List<Long> checkSnapCourseShchedules(List<CourseSchedule> courseSchedules);

	/**
	 * @describe
	 * @author Joburgess
	 * @date 2019/12/23
	 * @param courseSchedules: 生成课程名称
	 * @return void
	 */
	void createCourseScheduleName(List<CourseSchedule> courseSchedules);

	/**
	 * 获取乐团班级未开始的课程
	 *
	 * @param classGroupIds
	 * @param groupType
	 * @return
	 */
	List<CourseSchedule> findClassGroupNoStartCourseSchedules(List<Integer> classGroupIds, GroupType groupType);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/9/30
	 * 获取学生上课记录
	 */
	Object findStudentCourseScheduleRecords(StudentCourseScheduleRecordQueryInfo queryInfo);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/10/3
	 * @params [courseScheduleComplaints]
	 * @return void
	 * @describe 课程投诉
	 */
	void courseScheduleCommplaint(CourseScheduleComplaints courseScheduleComplaints);

	/**
	 * @Author: Joburgess
	 * @Date: 2019/10/3
	 * @params [id] 申诉编号
	 * @params [teacherLiabilityRatio] 老师责任比
	 * @params [studentLiabilityRatio] 学生责任比
	 * @params [status] 审批状态
	 * @return void
	 * @describe 课程投诉审核
	 */
	void courseScheduleCommplaintAudit(Long id, Double teacherLiabilityRatio, Double studentLiabilityRatio, AuditStatusEnum status);

	/**
	 * 更新课程至结束状态
	 * @return
	 */
	boolean updateCourseScheduleToOverStatus();

	/**
	 * 更新课程至进行中状态
	 * @return
	 */
	boolean updateCourseScheduleToUnderway();

	/**
	 * @describe 获取老师指定班级的排课
	 * @author Joburgess
	 * @date 2019/10/18
	 * @param queryInfo: 参数
	 * @return com.ym.mec.common.page.PageInfo
	 */
	PageInfo queryTeacherClassCourseSchedule(CourseScheduleQueryInfo queryInfo);


	PageInfo queryTeacherVipClassCourseSchedule(CourseScheduleQueryInfo queryInfo);

	/**
	 * @describe 获取点名详情界面头部信息
	 * @author Joburgess
	 * @date 2019/10/24
	 * @param courseScheduleId: 课程编号
	 * @return com.ym.mec.biz.dal.dto.CourseAttendanceDetailHeadInfoDto
	 */
	CourseAttendanceDetailHeadInfoDto findCourseAttendanceDetailHeadInfo(Long courseScheduleId);

	/**
	 * @describe 检测指定乐团下所有班级是否已排课
	 * @author Joburgess
	 * @date 2019/10/18
	 * @param musicGroupId: 乐团编号
	 * @return void
	 */
	void checkMusicGroupClassCourse(String musicGroupId);

	/**
	 * @describe 根据课程计划编号获取当前课次
	 * @author Joburgess
	 * @date 2019/10/20
	 * @param courseSchedules:
	 * @return java.util.Map<java.lang.Integer,java.lang.Integer>
	 */
	Map<Integer, Integer> findCourseScheduleCurrentTimes(List<Integer> courseSchedules);

	/**
	 * 查询班级未开始的课程
	 *
	 * @param classGroupId
	 * @return
	 */
	List<CourseSchedule> findNoStartCoursesByClassGroupId(Integer classGroupId);

	/**
	 * 学生有课提醒
	 * @return
	 */
	void studentCoursesScheduleRemind();

	/**
	 * 学生上课提醒
	 */
	void studentSignInRemind();

	/**
	 * 老师课程提醒
	 */
	void teacherCoursesScheduleRemind();

	/**
	 * 老师上课提醒
	 */
	void teacherSignInRemind();

	/**
	 * @describe 获取班级的课程计划
	 * @author Joburgess
	 * @date 2019/11/5
	 * @param classGroupId: 班级编号
	 * @return java.util.List<com.ym.mec.biz.dal.entity.CourseSchedule>
	 */
	List<CourseSchedule> findCourseScheduleByClassGroup(Integer classGroupId);

	/**
	 * @describe
	 * @author Joburgess
	 * @date 2019/11/14
	 * @param queryInfo:
	 * @return com.ym.mec.common.page.PageInfo
	 */
	Object findVipGroupCourseSchedules(VipGroupQueryInfo queryInfo);


	/**
	 * @describe 根据参数生成课程计划日期
	 * @author Joburgess
	 * @date 2019/12/23
	 * @param courseGenerateDto: 排课信息
	 * @return java.util.List<com.ym.mec.biz.dal.entity.CourseSchedule>
	 */
	List<CourseSchedule> createCourses(CourseGenerateDto courseGenerateDto, boolean excludePastCourse);

	/**
	 * @describe 终极课表获取接口
	 * @author Joburgess
	 * @date 2019/12/27
	 * @param queryInfo: 查询条件
	 * @return java.util.List<com.ym.mec.biz.dal.dto.CourseScheduleEndDto>
	 */
	PageInfo<CourseScheduleEndDto> endFindCourseSchedules(EndCourseScheduleQueryInfo queryInfo);

	/**
	 * @describe 陪练课程调整
	 * @author Joburgess
	 * @date 2020/2/9
	 * @param courseSchedule:
	 * @return void
	 */
	void practiceCourseAdjust(CourseSchedule courseSchedule);

	/**
	 * 陪练课老师调整
	 * @param courseScheduleId
	 * @param teacherId
	 */
    void practiceCourseTeacherAdjust(Long courseScheduleId,Integer teacherId);

	/**
	 * 陪练课课程组老师调整
	 * @param practiceGroupId
	 * @param teacherId
	 */
	void practiceGroupTeacherAdjust(String practiceGroupId, Integer teacherId, Integer subjectId, Integer educationalTeacherId);

	/**
	 * 清空老师和学生考勤
	 * @param courseScheduleIds
	 */
    void cleanAttendance(String courseScheduleIds);

	/**
	 * 教师端中间页课程评价数据获取
	 * @param courseScheduleId
	 * @return
	 */
	Object teacherCourseRemarkInfo(Long courseScheduleId);

	/**
	 * 教师端中间页课程评价数据提交
	 * @param teacherRemarkCommitDto
	 * @return
	 */
	void teacherCourseRemarkCommit(TeacherRemarkCommitDto teacherRemarkCommitDto);

	/**
	 * 教师端中间页网络教室头部详情
	 * @param courseScheduleId
	 * @return
	 */
    Object teacherCourseHeadInfo(Long courseScheduleId);

	/**
	 * 教师端中间页网络教室课程进度列表
	 * @param courseScheduleId
	 * @return
	 */
	Object teacherCourseRates(Long courseScheduleId);

	/**
	 * 根据课程组获取课程组老师信息
	 * @param groupType
	 * @param groupId
	 * @return
	 */
	Object getTeacherCourseHeadInfo(GroupType groupType,String groupId,Long courseScheduleId);

	/**
	 * 根据课程组获取课表信息
	 * @param groupType
	 * @param groupId
	 * @return
	 */
	Object queryCourseInfoByGroupId(GroupType groupType, String groupId);

	/**
	 * 教师课时使用记录列表
	 * @return
	 */
    Object teacherCourseMinutes(QueryInfo queryInfo);

	/**
	 * 修改课程组有效期
	 * @param practiceGroupId
	 * @param coursesExpireDate
	 */
	void updateCoursesExpireDate(String practiceGroupId, Date coursesExpireDate);

	/**
	 * 获取当前班级列表的所有未开始的课程
	 * @param classGroupIds
	 * @param teacherId
	 * @param teacherRole
	 * @return
	 */
	List<CourseSchedule> queryNoStartCourseByTeacherId(String classGroupIds, Integer teacherId, String teacherRole);

	/**
	 * 根据班级列表调整课程
	 * @param classGroupIds
	 * @param teacherId
	 * @param targetTeacherId
	 */
	void classGroupTeacherAdjust(String classGroupIds, Integer teacherId, Integer targetTeacherId);

	/**
	 * 网管课批量调整
	 * @param practiceGroupId
	 * @param teacherId
	 * @param subjectId
	 * @param educationalTeacherId
	 */
	void batchPracticeGroupTeacherAdjust(String practiceGroupId, Integer teacherId, Integer subjectId, Integer educationalTeacherId,Integer oldTeacherId);

	/**
	 * 获取课程调整时间轴
	 * @author zouxuan
	 * @param courseScheduleId
	 * @return
	 */
	List<CourseScheduleModifyLog> queryCourseAdjustDetail(Long courseScheduleId);


	/**
	 * @describe 重叠课程查找
	 * @author qnc99
	 * @date 2020/11/25 0025
	 * @return void
	 */
	void courseRepeatCheck();

	/**
	 * @describe 将被合并的课程替换为主课程
	 * @author qnc99
	 * @date 2020/12/7 0007
	 * @param courseSchedules:
	 * @return void
	 */
	List<CourseSchedule> classGroupNotStartMergeCourseReplace(Long classGroupId);

	/**
	 * @describe 课程合并
	 * @author qnc99
	 * @date 2020/11/27 0027
	 * @param courseMergeInfo:
	 * @return void
	 */
	void courseMerge(CourseMergeDto courseMergeInfo);
}
