package com.ym.mec.biz.service;

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

import com.ym.mec.biz.dal.dto.StudentRecoverInfoDto;
import com.ym.mec.biz.dal.dto.StudentVipGroupDetailDto;
import com.ym.mec.biz.dal.dto.TeacherBasicDto;
import com.ym.mec.biz.dal.dto.TeachingRecordBaseInfo;
import com.ym.mec.biz.dal.dto.VipBuyResultDto;
import com.ym.mec.biz.dal.dto.VipGroupApplyBaseInfoDto;
import com.ym.mec.biz.dal.dto.VipGroupApplyDto;
import com.ym.mec.biz.dal.dto.VipGroupBuyParamsDto;
import com.ym.mec.biz.dal.dto.VipGroupCostCountDto;
import com.ym.mec.biz.dal.dto.VipGroupCostCountParamsDto;
import com.ym.mec.biz.dal.dto.VipGroupManageDetailDto;
import com.ym.mec.biz.dal.dto.VipGroupPayInfoDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.entity.StudentApplyRefunds.StudentApplyRefundsStatus;
import com.ym.mec.biz.dal.enums.AuditStatusEnum;
import com.ym.mec.biz.dal.page.StudentVipGroupQueryInfo;
import com.ym.mec.biz.dal.page.VipGroupAttendanceQueryInfo;
import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
import com.ym.mec.biz.dal.page.VipGroupSalaryQueryInfo;
import com.ym.mec.biz.dal.page.VipGroupTeachingRecordQueryInfo;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.BaseService;

public interface VipGroupService extends BaseService<Long, VipGroup> {

    /**
     * @describe 创建vip课
     * @author Joburgess
     * @date 2019/10/30
     * @param vipGroup: VIP课申请信息
     * @return void
     */
    String createVipGroup(VipGroupApplyDto vipGroup);

    /**
     * @describe 获取教务与教师共有分部
     * @author Joburgess
     * @date 2020.07.08
     * @param eduTeacherId:
     * @param teacherId:
     * @return java.util.List<com.ym.mec.biz.dal.entity.Organization>
     */
    List<Organization> getPublicOrgans(Integer eduTeacherId, Integer teacherId);

    /**
     * @describe 检测vip课程是否超过范围
     * @author Joburgess
     * @date 2020/1/16
     * @param vipGroupId: 小课编号
     * @return void
     */
    void checkVipCourseIsInScore(Long vipGroupId);

    /**
     * @describe 删除vip课程组
     * @author Joburgess
     * @date 2020.07.08
     * @param vipGroupId:
     * @return void
     */
    void deleteVipGroup(Long vipGroupId);

    /**
     * @describe 新增vip课程计划
     * @author Joburgess
     * @date 2019/11/11
     * @param vipGroupApplyDto:
     * @return void
     */
    void appendVipGroupCourseSchedules(VipGroupApplyDto vipGroupApplyDto);

    /**
     * @describe vip课程审核
     * @author Joburgess
     * @date 2019/10/22
     * @param vipGroupId: vip课编号
     * @param auditStatus: 审核状态
     * @return void
     */
    void vipApplyAudit(Long vipGroupId,AuditStatusEnum auditStatus,String reason);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [queryInfo]
     * @return com.ym.mec.common.page.PageInfo
     * @describe 获取可购买vip课列表
     */
    PageInfo findStudentVipGroupList(StudentVipGroupQueryInfo queryInfo);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/9
     * @params [queryInfo]
     * @return com.ym.mec.common.page.PageInfo
     * @describe 获取vip课列表
     */
    PageInfo<VipGroup> findVipGroups(VipGroupQueryInfo queryInfo);

    /**
     * @describe 获取vip课教学记录
     * @author Joburgess
     * @date 2019/10/21
     * @param queryInfo: 查询条件
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    Map<String, Object> findVipGroupTeachingRecord(VipGroupTeachingRecordQueryInfo queryInfo);

    /**
     * @describe 获取vip课教学记录基本信息
     * @author Joburgess
     * @date 2019/10/21
     * @param vipGroupId: vip课编号
     * @return com.ym.mec.biz.dal.dto.TeachingRecordBaseInfo
     */
    TeachingRecordBaseInfo findTeachingRecordBaseInfo(Long vipGroupId);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/9
     * @params [queryInfo]
     * @return com.ym.mec.common.page.PageInfo
     * @describe 获取vip课学员
     */
    PageInfo findVipGroupStudents(VipGroupQueryInfo queryInfo);

    /**
     * @describe 获取还有课程余额的学员
     * @author Joburgess
     * @date 2019/11/16
     * @param queryInfo:
     * @return com.ym.mec.common.page.PageInfo
     */
    PageInfo findHaveCourseBalanceStudents(VipGroupQueryInfo queryInfo);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [vipGroupId]
     * @return com.ym.mec.biz.dal.dto.VipGroupManageDetailDto
     * @describe 获取vip课详情
     */
    VipGroupManageDetailDto getVipGroupDetail(Long vipGroupId);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [vipGroupId]
     * @return com.ym.mec.biz.dal.dto.VipGroupManageDetailDto
     * @describe 获取vip课详情
     */
    VipGroupManageDetailDto getVipGroupDetailForAudit(Long vipGroupId);

    /**
     * @describe 计算vip课程购买总价,及老师课酬
     * @author Joburgess
     * @date 2019/10/23
     * @param vipGroup: vip课程
     * @param teacherId: 要计算课酬的老师的编号
     * @param onlineClassesUnitPrice: 线上课程单价
     * @param offlineClassesUnitPrice: 线下课程单价
     * @return java.util.Map
     */
    <K extends VipGroup> Map<String, BigDecimal> countVipGroupPredictFee(K vipGroup,
                                                     Integer teacherId,
                                                     BigDecimal onlineClassesUnitPrice,
                                                     BigDecimal offlineClassesUnitPrice);

    /**
     * @describe 计算vip课程购买总价,及老师课酬-只是学生人数统计方式不同
     * @author Joburgess
     * @date 2019/10/23
     * @param vipGroup: vip课程
     * @param teacherId: 要计算课酬的老师的编号
     * @return java.util.Map
     */
    <K extends VipGroup> Map<String, BigDecimal> countVipGroupCoursePredictFee(K vipGroup,
                                                                         Integer teacherId,
                                                                               Long courseId);


    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [queryInfo]
     * @return com.ym.mec.common.page.PageInfo
     * @describe 获取vip课考勤记录
     */
    PageInfo findVipGroupAttendances(VipGroupAttendanceQueryInfo queryInfo);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [vipGroupId]
     * @return com.ym.mec.biz.dal.dto.StudentVipGroupDetailDto
     * @describe 学生端获取vip课详情
     */
    StudentVipGroupDetailDto getVipGroupShowDetail(Long vipGroupId);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [vipGroupCostCountParamsDto]
     * @return com.ym.mec.biz.dal.dto.VipGroupCostCountDto
     * @describe vip课程费用计算
     */
    VipGroupCostCountDto vipGroupCostCount(VipGroupCostCountParamsDto vipGroupCostCountParamsDto);

    /**
     * @describe 更新vip课班级人数及状态
     * @author Joburgess
     * @date 2019/10/20
     * @param vipGroupId: vip课编号
     * @param num: 人数
     * @param updateVipStatus: 是否修改VIP课状态
     * @return void
     */
    void updateVipGroupStudentNumAndStatus(Long vipGroupId, ClassGroup classGroup, Integer num, boolean updateVipStatus);

    /**
     * @describe 课程购买成功后，创建课程相关信息
     * @author Joburgess
     * @date 2019/11/12
     * @param vipGroupId: vip课编号
     * @return void
     */
    void createVipGroupCourseScheInfo(Long vipGroupId,ClassGroup classGroup);

    /**
     * @describe 检测能否购买vip课
     * @author Joburgess
     * @date 2019/12/2
     * @param vipGroupId:
     * @return void
     */
    void enableBuyVipGroup(Integer vipGroupId, Integer userId);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [vipGroupBuyParams]
     * @return void
     * @describe 购买vip课程
     */
    Map buyVipGroup(VipGroupBuyParamsDto vipGroupBuyParams) throws Exception;

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [callbackParams]
     * @return void
     * @describe 支付回调接口
     */
    void orderCallback(StudentPaymentOrder order);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [vipGroupId, studentId]
     * @return void
     * @describe 申请退课
     */
    void applyRefund(Long vipGroupId);

    /**
     * @describe 给指定学生退课
     * @author Joburgess
     * @date 2019/11/15
     * @param vipGroupId: vip课程
     * @param studentId: 学生编号
     * @return void
     */
    void applyRefundForStudent(Long vipGroupId, Integer studentId, BigDecimal amount);

    /**
     * @describe 对某个学生进行休学
     * @author Joburgess
     * @date 2019/12/18
     * @param vipGroupId: vip课编号
     * @param studentId: 学生编号
     * @return void
     */
    void pauseForStudent(Long vipGroupId, Integer studentId);

    /**
     * @describe 恢复休学的学生
     * @author Joburgess
     * @date 2019/12/18
     * @param studentRecoverInfo:
     * @return void
     */
    void recoverForStudent(StudentRecoverDto studentRecoverInfo);

    /**
     * @describe 获取学生休学信息
     * @author Joburgess
     * @date 2019/12/24
     * @param vipGroupId:
     * @param studentId:
     * @return com.ym.mec.biz.dal.dto.StudentRecoverInfoDto
     */
    StudentRecoverInfoDto getStudentPauseInfo(Long vipGroupId, Integer studentId);

    /**
     * @describe 获取指定学生的剩余课时费用
     * @author Joburgess
     * @date 2019/11/15
     * @param vipGroupId: VIP课编号
     * @param studentId: 学生编号
     * @return java.util.Map<java.lang.String,java.math.BigDecimal>
     */
    Map<String,BigDecimal> getStudentSurplusCourseFee(Long vipGroupId, Integer studentId);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/3
     * @params [studentApplyRefunds]
     * @return void
     * @describe 退课申请审核
     */
    void applyRefundAudit(Long id,StudentApplyRefundsStatus status,String remark,BigDecimal amount);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/11
     * @params [queryInfo]
     * @return com.ym.mec.common.page.PageInfo
     * @describe vip财务记录
     */
    Map<String, Object> findVipGroupSalarys(VipGroupSalaryQueryInfo queryInfo);

    /**
     * @Author: Joburgess
     * @Date: 2019/10/11
     * @params [courseScheduleId]
     * @return java.util.List<java.lang.String>
     * @describe 获取上课签到学员
     */
    List<String> findVipGroupAttendanceStudents(Long courseScheduleId);

    /**
     * @describe 停止vip课
     * @author Joburgess
     * @date 2019/10/21
     * @param vipGroupId: vip课编号
     * @param stopReason: 取消原因
     * @return void
     */
    void stopGroup(Long vipGroupId,String stopReason);

    /**
     * 发放月度奖励
     * @return
     */
    boolean awardedMonthlyRewards();

    /**
     * 根据老师查询vip课教学点
     * @param userId
     * @return
     */
    List<School> querySchoolByUserId(Integer userId);

    /**
     * @describe 更新vip课基本信息
     * @author Joburgess
     * @date 2019/11/11
     * @param vipGroupApplyBaseInfo:
     * @return void
     */
    void updateVipGroupBaseInfo(VipGroupApplyBaseInfoDto vipGroupApplyBaseInfo);

    /**
     * @describe 取消达到报名时间仍未达到报名人数的vip课
     * @author Joburgess
     * @date 2019/11/13
     * @return void
     */
    void stopVipGroupWithNoCreate();

    /**
     * @describe 添加vip课学员
     * @author Joburgess
     * @date 2019/11/15
     * @param vipGroupId:
     * @param studentIds:
     * @return void
     */
    void addVipGroupStudents(Long vipGroupId,List<Integer> studentIds);

    /**
     * 更新vipgroup至完成状态
     */
    void updateVipGroupStatusToFinished();

    /**
     * @describe 获取vip课购买信息
     * @author Joburgess
     * @date 2019/11/29
     * @param vipGroupId: vip课编号
     * @param userId: 用户编号
     * @return void
     */
    VipGroupPayInfoDto getVipGroupPayInfo(Integer vipGroupId,Integer userId);

    /**
     * @describe 获取vip课购买结果信息
     * @author Joburgess
     * @date 2019/11/29
     * @param vipGroupId: 小课编号
     * @return
     */
    VipBuyResultDto findVipBuyResultInfo(Integer vipGroupId);

    /**
     * @describe 根据vip课所在部门与深部获取教师
     * @author Joburgess
     * @date 2019/12/24
     * @param vipGroupId: 小课编号
     * @return java.util.List<com.ym.mec.biz.dal.dto.TeacherBasicDto>
     */
    List<TeacherBasicDto> findTeacherWithVipGroupOrganAndSubject(Long vipGroupId);
}
