package com.ym.mec.biz.service.impl;

import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.GroupStatusEnum;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.PlatformCashAccountDetailTypeEnum;
import com.ym.mec.biz.service.GroupClassService;
import com.ym.mec.biz.service.SysTenantAccountService;
import com.ym.mec.biz.service.SysUserCashAccountService;
import com.ym.mec.common.exception.BizException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author Joburgess
 * @Date 2020/2/17
 */
@Service
public class GroupClassServiceImpl implements GroupClassService {

    @Autowired
    private GroupDao groupDao;
    @Autowired
    private ClassGroupDao classGroupDao;
    @Autowired
    private ClassGroupTeacherMapperDao classGroupTeacherMapperDao;
    @Autowired
    private ClassGroupTeacherSalaryDao classGroupTeacherSalaryDao;
    @Autowired
    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
    @Autowired
    private CourseScheduleDao courseScheduleDao;
    @Autowired
    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
    @Autowired
    private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
    @Autowired
    private TeacherAttendanceDao teacherAttendanceDao;
    @Autowired
    private StudentAttendanceDao studentAttendanceDao;
    @Autowired
    private PracticeGroupDao practiceGroupDao;
    @Autowired
    private SysUserCashAccountService sysUserCashAccountService;
    @Autowired
    private StudentPaymentOrderDao studentPaymentOrderDao;
    @Autowired
    private CoursesGroupDao coursesGroupDao;
    @Autowired
    private SysTenantAccountService sysTenantAccountService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAllGroupInfo(String groupId, GroupType groupType) {
        groupDao.deleteGroup(groupId,groupType.getCode());
        classGroupDao.deleteByGroup(groupId,groupType);
        classGroupTeacherMapperDao.deleteByGroup(groupId,groupType);
        classGroupTeacherSalaryDao.deleteByGroup(groupId,groupType);
        classGroupStudentMapperDao.deleteByGroup(groupId,groupType);
        courseScheduleDao.deleteByGroup(groupId,groupType);
        courseScheduleTeacherSalaryDao.deleteByGroup(groupId,groupType);
        courseScheduleStudentPaymentDao.deleteByGroup(groupId,groupType);
        teacherAttendanceDao.deleteByGroup(groupId,groupType);
        studentAttendanceDao.deleteByGroup(groupId,groupType);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteGroupOtherInfo(String groupId, GroupType groupType) {
        classGroupDao.deleteByGroup(groupId,groupType);
        classGroupTeacherMapperDao.deleteByGroup(groupId,groupType);
        classGroupTeacherSalaryDao.deleteByGroup(groupId,groupType);
        classGroupStudentMapperDao.deleteByGroup(groupId,groupType);
        courseScheduleDao.deleteByGroup(groupId,groupType);
        courseScheduleTeacherSalaryDao.deleteByGroup(groupId,groupType);
        courseScheduleStudentPaymentDao.deleteByGroup(groupId,groupType);
        teacherAttendanceDao.deleteByGroup(groupId,groupType);
        studentAttendanceDao.deleteByGroup(groupId,groupType);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cleanGroupInfo(String groupId, GroupType groupType) {
        classGroupDao.deleteByGroupWithLogic(groupId,groupType);
        classGroupStudentMapperDao.deleteByGroupWithLogic(groupId,groupType);
        List<CourseSchedule> groupNotStartCourses = courseScheduleDao.findGroupNotStartCourses(groupId, groupType);
        if(CollectionUtils.isEmpty(groupNotStartCourses)){
            return true;
        }
        List<Long> courseIds = groupNotStartCourses.stream().map(CourseSchedule::getId).collect(Collectors.toList());
        courseScheduleDao.batchDeleteCourseSchedules(courseIds);
        courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseIds);
        courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseIds);
        teacherAttendanceDao.batchDeleteByCourseSchedules(courseIds);
        studentAttendanceDao.deleteByCourseSchedules(courseIds);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean hideGroupInfo(String groupId, GroupType groupType) {
        classGroupDao.deleteByGroupWithLogic(groupId,groupType);
        classGroupStudentMapperDao.deleteByGroupWithLogic(groupId,groupType);
        List<CourseSchedule> groupNotStartCourses = courseScheduleDao.findGroupNotStartCourses(groupId, groupType);
        if(CollectionUtils.isEmpty(groupNotStartCourses)){
            return true;
        }
        List<Long> courseIds = groupNotStartCourses.stream().map(CourseSchedule::getId).collect(Collectors.toList());
        courseScheduleDao.batchDeleteCourseSchedulesWithLogic(courseIds);
        courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseIds);
        courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseIds);
        teacherAttendanceDao.batchDeleteByCourseSchedules(courseIds);
        studentAttendanceDao.deleteByCourseSchedules(courseIds);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void cancelGroup(Long groupId, GroupType groupType, BigDecimal refundAmount) {
        if(Objects.isNull(groupId)){
            throw new BizException("请指定课程组");
        }
        if(Objects.isNull(groupType)){
            throw new BizException("请指定课程组类型");
        }
        Date now=new Date();
        if(groupType.equals(GroupType.PRACTICE)){
            PracticeGroup practiceGroup = practiceGroupDao.get(groupId);
            if(Objects.isNull(practiceGroup)){
                throw new BizException("指定的课程组不存在");
            }
            List<StudentPaymentOrder> orders = studentPaymentOrderDao.findOrderByGroup(practiceGroup.getId().toString(), GroupType.PRACTICE, DealStatusEnum.SUCCESS);
            if(CollectionUtils.isEmpty(orders)&&Objects.nonNull(refundAmount)){
                throw new BizException("未获取到订单");
            }
            if(!practiceGroup.getGroupStatus().equals(GroupStatusEnum.NORMAL)||practiceGroup.getCoursesExpireDate().before(now)){
                throw new BizException("当前课程组不可关闭");
            }
            if(Objects.nonNull(refundAmount)&&refundAmount.compareTo(BigDecimal.ZERO)>0){
                if(refundAmount.compareTo(orders.get(0).getExpectAmount())>0){
                    throw new BizException("退款不可大于购买金额");
                }
                sysUserCashAccountService.updateBalance(practiceGroup.getStudentId(), refundAmount, PlatformCashAccountDetailTypeEnum.REFUNDS, "后团关闭网管课");
            }
            cleanGroupInfo(groupId.toString(), GroupType.PRACTICE);
            practiceGroup.setMemo("后台关闭网管课");
            practiceGroup.setGroupStatus(GroupStatusEnum.CANCEL);
            practiceGroup.setUpdateTime(now);
            practiceGroupDao.update(practiceGroup);
        }else if(groupType.equals(GroupType.COMM)){
            CoursesGroup coursesGroup = coursesGroupDao.get(groupId);
            if(Objects.isNull(coursesGroup)){
                throw new BizException("指定的课程组不存在");
            }
            if(coursesGroup.getStatus().equals(GroupStatusEnum.CANCEL)){
                throw new BizException("此课程组已关闭");
            }
            List<CourseSchedule> groupNotStartCourses = courseScheduleDao.findGroupNotStartCourses(groupId.toString(), groupType);
            if(!CollectionUtils.isEmpty(groupNotStartCourses)){
                //剩余课程时长
                Integer totalCourseTime=groupNotStartCourses.size()*coursesGroup.getSingleClassMinutes();
                sysTenantAccountService.update(coursesGroup.getTeacherId(), totalCourseTime, "", SysTenantAccountDetail.TransType.RETURN, "",BigDecimal.ZERO,"关闭课程组");
            }else{
                throw new BizException("此课程组已结束");
            }
            cleanGroupInfo(groupId.toString(), GroupType.COMM);
            coursesGroup.setMemo("主动关闭课程组");
            coursesGroup.setStatus(GroupStatusEnum.CANCEL);
            coursesGroupDao.update(coursesGroup);
        }
    }
}
