package com.ym.mec.web.controller;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.ClassGroupDao;
import com.ym.mec.biz.dal.dao.ClassGroupTeacherMapperDao;
import com.ym.mec.biz.dal.dao.EmployeeDao;
import com.ym.mec.biz.dal.dao.VipGroupDao;
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.*;
import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
import com.ym.mec.biz.dal.page.StudentAttendanceQueryInfo;
import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
import com.ym.mec.biz.service.CourseScheduleComplaintsService;
import com.ym.mec.biz.service.CourseScheduleService;
import com.ym.mec.biz.service.MusicGroupService;
import com.ym.mec.biz.service.StudentAttendanceService;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.entity.HttpResponseResult;
import com.ym.mec.common.exception.BizException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author Joburgess
 * @Date 2019/9/10
 */
@RequestMapping("courseSchedule")
@Api(tags = "课程计划服务")
@RestController
public class CourseScheduleController extends BaseController {

    @Autowired
    private CourseScheduleService courseScheduleService;
    @Autowired
    private StudentAttendanceService studentAttendanceService;
    @Autowired
    private ClassGroupTeacherMapperDao classGroupTeacherMapperDao;
    @Autowired
    private CourseScheduleComplaintsService courseScheduleComplaintsService;
    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private MusicGroupService musicGroupService;
    
    @Autowired
    private ClassGroupDao classGroupDao;
    
    @Autowired
    private EmployeeDao employeeDao;
    @Autowired
    private VipGroupDao vipGroupDao;

    @ApiOperation(value = "课表详情")
    @GetMapping("/query")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/query')")
    public Object query(Long courseScheduleId){
        return succeed(courseScheduleService.queryById(courseScheduleId));
    }

    @ApiOperation(value = "终极课表获取")
    @GetMapping("/superFindCourseSchedules")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/superFindCourseSchedules')")
    public Object superFindCourseSchedules(EndCourseScheduleQueryInfo queryInfo){
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            return failed("用户信息获取失败");
        }
        if(!sysUser.getIsSuperAdmin()){
            Employee employee = employeeDao.get(sysUser.getId());
            if (org.apache.commons.lang3.StringUtils.isEmpty(queryInfo.getOrganIdList())) {
                queryInfo.setOrganIdList(employee.getOrganIdList());
            }else if(org.apache.commons.lang3.StringUtils.isEmpty(employee.getOrganIdList())){
                return failed("用户所在分部异常");
            }else {
                List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
                if(!list.containsAll(Arrays.asList(queryInfo.getOrganIdList().split(",")))){
                    return failed("非法请求");
                }
            }
        }
        return succeed(courseScheduleService.endFindCourseSchedules(queryInfo));
    }

    @ApiOperation(value = "排课")
    @PostMapping("/batchAddCourseSchedule")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchAddCourseSchedule')")
    public Object batchAddCourseSchedule(@RequestBody CreateCourseScheduleDto createCourseScheduleDto){
        if(Objects.isNull(createCourseScheduleDto.getMusicGroupID())){
            throw new BizException("请指定乐团");
        }
        
        MusicGroup musicGroup = musicGroupService.get(createCourseScheduleDto.getMusicGroupID());
        if(musicGroup == null){
        	return failed("乐团信息不存在");
        }
        
        List<ClassGroupTeacherMapper> byMusicGroup = classGroupTeacherMapperDao.findByMusicGroup(createCourseScheduleDto.getMusicGroupID());
        Map<Integer, List<ClassGroupTeacherMapper>> teacherByClassGroup = byMusicGroup.stream().collect(Collectors.groupingBy(ClassGroupTeacherMapper::getClassGroupId));

        createCourseScheduleDto.getCourseSchedules().forEach(courseSchedule -> {
            List<ClassGroupTeacherMapper> classGroupTeacherMappers = teacherByClassGroup.get(courseSchedule.getClassGroupId());
            if(CollectionUtils.isEmpty(classGroupTeacherMappers)){
                throw new BizException("乐团老师设置有误");
            }
            if(Objects.isNull(courseSchedule.getTeachMode())){
                courseSchedule.setTeachMode(TeachModeEnum.OFFLINE);
            }
            Integer schoolId = courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE) ? null : musicGroup.getSchoolId();
            courseSchedule.setTeacherId(classGroupTeacherMappers.get(0).getUserId());
            courseSchedule.setActualTeacherId(classGroupTeacherMappers.get(0).getUserId());
            courseSchedule.setSchoolId(schoolId);
            courseSchedule.setMusicGroupId(musicGroup.getId());
            courseSchedule.setGroupType(GroupType.MUSIC);
            courseSchedule.setStatus(CourseStatusEnum.NOT_START);
            courseSchedule.setOrganId(musicGroup.getOrganId());
        });

        courseScheduleService.createCourseSchedules(createCourseScheduleDto);
        return succeed();
    }

    @ApiOperation(value = "批量更新排课")
    @PostMapping("/batchUpdateCourseSchedule/{musicGroupID}")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchUpdateCourseSchedule')")
    public Object batchUpdateCourseSchedule(@RequestBody List<CourseSchedule> courseSchedules,
                                            @ApiParam(value = "乐团编号", required = true) @PathVariable("musicGroupID") String musicGroupID){
        courseScheduleService.batchUpdateCourseSchedule(courseSchedules,musicGroupID);
        return succeed();
    }

    @ApiOperation(value = "批量删除课程")
    @PostMapping(value = "/batchDelete")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchDelete')")
    public Object bathDelete(String courseScheduleIds){
        if(StringUtils.isEmpty(courseScheduleIds)){
            throw new BizException("请指定课程编号");
        }
        long[] ints = Arrays.asList(courseScheduleIds.split(",")).stream().mapToLong(Long::parseLong).toArray();
        Long[] longs = ArrayUtils.toObject(ints);
        courseScheduleService.batchDeleteCourseSchedules(Arrays.asList(longs));
        return succeed();
    }

    @ApiOperation(value = "获取vip课程计划")
    @PostMapping(value = "/findVipGroupCourseSchedules")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/findVipGroupCourseSchedules')")
    public Object findVipGroupCourseSchedules(VipGroupQueryInfo queryInfo){
        return succeed(courseScheduleService.findVipGroupCourseSchedules(queryInfo));
    }

    @ApiOperation(value = "根据月份获取乐团在该月有课的日期")
    @GetMapping("/getCourseScheduleDateByMonth")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/getCourseScheduleDateByMonth')")
        public Object getCourseScheduleDateByMonth(@ApiParam(value = "乐团编号", required = true) @RequestParam Long musicGroupID,
                                                   @ApiParam(value = "月份", required = true) @RequestParam Date month) {
        return succeed(courseScheduleService.getCourseScheduleDateByMonth(musicGroupID,month));
    }

    @ApiOperation(value = "根据课程ID查询正在或即将开始的课程")
    @GetMapping("/getCurrentCourseDetail/{courseID}")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/getCurrentCourseDetail')")
    public Object getCurrentCourseDetail(@ApiParam(value = "课程ID", required = true) @PathVariable("courseID") Long courseID){
        return succeed(courseScheduleService.getCurrentCourseDetail(courseID));
    }

    @ApiOperation(value = "根据班级ID获取当前课程的学生")
    @GetMapping("/getCurrentCourseStudents")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/getCurrentCourseStudents')")
    public Object getCurrentCourseStudents(@RequestBody StudentAttendanceQueryInfo queryInfo){
        return succeed(studentAttendanceService.getCurrentCourseStudents(queryInfo));
    }

    @ApiOperation(value = "课时调整")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/classStartDateAdjust','system')")
    @PostMapping(value = "/classStartDateAdjust",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Object classStartDateAdjust(CourseSchedule courseSchedule){
        CourseSchedule oldCourseSchedule = courseScheduleService.get(courseSchedule.getId());
        if(Objects.isNull(oldCourseSchedule)){
            return failed("未找到指定课程");
        }
        if(Objects.nonNull(oldCourseSchedule.getNewCourseId())&&!oldCourseSchedule.getNewCourseId().equals(oldCourseSchedule.getId())){
            return failed("被合并课程禁止调整");
        }
        if(GroupType.VIP.equals(oldCourseSchedule.getGroupType())){
            VipGroup vipGroup = vipGroupDao.findByCourseSchedule(courseSchedule.getId());
            if(Objects.nonNull(vipGroup)
                    &&!VipGroupStatusEnum.PROGRESS.equals(vipGroup.getStatus())
                    &&!VipGroupStatusEnum.FINISHED.equals(vipGroup.getStatus())){
                throw new BizException("非进行中课程组不允许进行此操作");
            }
        }
        if(Objects.isNull(courseSchedule.getClassGroupId())){
            courseSchedule.setClassGroupId(oldCourseSchedule.getClassGroupId());
        }
        List<CourseSchedule> courseSchedules=new ArrayList<>();
        courseSchedules.add(courseSchedule);
        courseScheduleService.courseAdjust(courseSchedules);
        return succeed();
    }

    @ApiOperation(value = "课程合并")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/courseMerge','system')")
    @PostMapping(value = "/courseMerge",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public HttpResponseResult courseMerge(CourseMergeDto courseMergeInfo){
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            return failed("用户信息获取失败");
        }
        courseMergeInfo.setOperatorId(sysUser.getId());
        courseScheduleService.courseMerge(courseMergeInfo);
        return succeed();
    }

    @ApiOperation(value = "根据班级列表调整课程")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/classGroupTeacherAdjust','system')")
    @PostMapping(value = "/classGroupTeacherAdjust")
    public Object classGroupTeacherAdjust(String classGroupIds,Integer teacherId,Integer targetTeacherId){
        courseScheduleService.classGroupTeacherAdjust(classGroupIds,teacherId,targetTeacherId);
        return succeed();
    }

    @ApiOperation(value = "课时调整-批量")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchClassStartDateAdjust')")
    @PostMapping(value = "/batchClassStartDateAdjust")
    public Object batchClassStartDateAdjust(@RequestBody List<CourseSchedule> courseSchedules){
        courseScheduleService.courseAdjust(courseSchedules);
        return succeed();
    }

    @ApiOperation(value = "课时交换")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/courseSwap')")
    @GetMapping(value = "/courseSwap",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Object courseSwap(Long courseScheduleId1,Long courseScheduleId2){
        if(Objects.isNull(courseScheduleId1)||Objects.isNull(courseScheduleId2)){
            return failed("请指定课程");
        }
        courseScheduleService.courseSwap(courseScheduleId1,courseScheduleId2);
        return succeed();
    }

    @ApiOperation(value = "课程投诉审核")
    @PostMapping(value = "/courseScheduleCommplaintAudit")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/courseScheduleCommplaintAudit')")
	public Object courseScheduleCommplaintAudit(Long id, Double teacherLiabilityRatio, Double studentLiabilityRatio, AuditStatusEnum status) {
		courseScheduleService.courseScheduleCommplaintAudit(id, teacherLiabilityRatio, studentLiabilityRatio, status);
		return succeed();
	}

    @ApiOperation(value = "检测乐团下所有的班级是否都已排课")
    @PostMapping(value = "/checkMusicGroupClassCourse")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/checkMusicGroupClassCourse')")
    public Object checkMusicGroupClassCourse(String musicGroupId){
        courseScheduleService.checkMusicGroupClassCourse(musicGroupId);
        return succeed();
    }

	@ApiOperation(value = "课酬调整")
	@PostMapping("/updateTeacherCoursesSalary")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/updateTeacherCoursesSalary')")
	public Object updateTeacherCoursesSalary(Long courseScheduleId, Integer teacherId, BigDecimal salary, BigDecimal subsidy, String scope) {
		return succeed(musicGroupService.updateTeacherCoursesSalary(courseScheduleId, teacherId, salary, subsidy, scope));
	}

    @ApiOperation(value = "删除乐团下所有未上的课时")
    @GetMapping("/batchDeleteMusicGroupNotStartCourse")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchDeleteMusicGroupNotStartCourse')")
	public Object batchDeleteMusicGroupNotStartCourse(String musicGroupId){
        courseScheduleService.batchDeleteMusicGroup(musicGroupId,GroupType.MUSIC);
        return succeed();
    }

	@ApiOperation(value = "乐团详情--课酬调整--课程教师列表")
	@GetMapping("/queryTeacherSalary")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/queryTeacherSalary')")
	public Object queryTeacherSalary(Long courseScheduleId,Integer teacherId) {
		return succeed(musicGroupService.queryTeacherSalary(courseScheduleId,teacherId));
	}

    @ApiOperation(value = "根据班级获取课程计划")
    @GetMapping("/findCourseScheduleByClassGroup")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/findCourseScheduleByClassGroup')")
	public Object findCourseScheduleByClassGroup(Integer classGroupId){
        return succeed(courseScheduleService.findCourseScheduleByClassGroup(classGroupId));
    }
    
    @ApiOperation(value = "查询课程投诉详情")
	@GetMapping("/queryCourseScheduleComplaintsDetail")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/queryCourseScheduleComplaintsDetail')")
    public Object queryCourseScheduleComplaintsDetail(Long courseScheduleComplaintsId){
    	CourseScheduleComplaints complaints = courseScheduleComplaintsService.get(courseScheduleComplaintsId);
    	if(complaints == null){
    		return failed("参数输入不正确");
    	}
    	
    	SysUser user = sysUserFeignService.queryUserById(complaints.getUserId());
    	complaints.getUser().setUsername(user.getUsername());
    	
    	CourseSchedule courseSchedule = courseScheduleService.get(complaints.getCourseScheduleId());
    	SysUser teacher = sysUserFeignService.queryUserById(courseSchedule.getActualTeacherId());
    	courseSchedule.getTeacher().setUsername(teacher.getUsername());
    	
    	ModelMap model = new ModelMap();
    	model.put("complaints", complaints);
    	model.put("courseSchedule", courseSchedule);
    	
    	return succeed(model);
    }

    @ApiOperation(value = "vip课批量调整(网管课)")
    @PostMapping("/vipCourseAdjust")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/vipCourseAdjust')")
    public Object vipCourseAdjust(@RequestBody VipGroupCourseAdjustInfoDto vipGroupCourseAdjustInfo){
        courseScheduleService.vipCourseAdjust(vipGroupCourseAdjustInfo);
        return succeed();
    }

    @ApiOperation(value = "课程批量调整")
    @PostMapping("/batchUpdateCourseSchedule")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchUpdateCourseSchedule')")
    public Object batchUpdateCourseSchedule(@RequestBody BatchInsertCoursesDto batchInsertCoursesDto){
        courseScheduleService.batchUpdateCourseSchedule(batchInsertCoursesDto);
        return succeed();
    }

    @ApiOperation(value = "vip课批量新增")
    @PostMapping("/batchAppendVipGroupCourses")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchAppendVipGroupCourses')")
    public Object batchAppendVipGroupCourses(@RequestBody VipGroupCourseAdjustInfoDto vipGroupCourseAdjustInfo){
        courseScheduleService.batchAppendVipGroupCourses(vipGroupCourseAdjustInfo);
        return succeed();
    }

    @ApiOperation(value = "批量新增")
    @PostMapping("/batchAddCourses")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchAddCourses')")
    public Object batchAddCourses(@RequestBody BatchInsertCoursesDto batchInsertCoursesDto){
    	if(batchInsertCoursesDto.getClassGroupId() == null){
			if (batchInsertCoursesDto.getType() != CourseScheduleType.VIP && batchInsertCoursesDto.getType() != CourseScheduleType.PRACTICE) {
				return failed("请指定班级");
			}
    		List<ClassGroup> classGroupList = classGroupDao.findClassGroupByMusicGroupIdAndType(batchInsertCoursesDto.getMusicGroupId(), ClassGroupTypeEnum.valueOf(batchInsertCoursesDto.getType().getCode()));
    		if(classGroupList == null || classGroupList.size() == 0){
    			return failed("没有查询到班级信息");
    		}
    		batchInsertCoursesDto.setClassGroupId(classGroupList.get(0).getId());
    	}
		courseScheduleService.batchAddCourseSchedule(batchInsertCoursesDto.getClassGroupId(), batchInsertCoursesDto.getCoursesTimes(),
				batchInsertCoursesDto.getStartDate(), null,null, batchInsertCoursesDto.getTeachingArrangementList(), batchInsertCoursesDto.getTeachMode(),
				batchInsertCoursesDto.getType(), batchInsertCoursesDto.getSchoolId(), batchInsertCoursesDto.getIsJumpHoliday());
        return succeed();
    }

    @ApiOperation(value = "课程顺延")
    @PostMapping("/coursePostpone")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/coursePostpone')")
    public Object coursePostpone(CoursePostponeDto coursePostPoneInfo){
        courseScheduleService.coursePostpone(coursePostPoneInfo);
        return succeed();
    }

    @ApiOperation(value = "陪练课调整")
    @PostMapping("/practiceCourseAdjust")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/practiceCourseAdjust')")
    public Object practiceCourseAdjust(CourseSchedule courseSchedule){
        courseScheduleService.practiceCourseAdjust(courseSchedule);
        return succeed();
    }

    @ApiOperation(value = "陪练课老师调整")
    @PostMapping("/practiceCourseTeacherAdjust")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/practiceCourseTeacherAdjust')")
    public Object practiceCourseTeacherAdjust(Long courseScheduleId,Integer teacherId){
        courseScheduleService.practiceCourseTeacherAdjust(courseScheduleId,teacherId);
        return succeed();
    }

    @ApiOperation(value = "陪练课课程组老师调整")
    @PostMapping("/practiceGroupTeacherAdjust")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/practiceGroupTeacherAdjust')")
    public Object practiceGroupTeacherAdjust(String practiceGroupId, Integer teacherId, Integer subjectId, Integer educationalTeacherId){
        courseScheduleService.practiceGroupTeacherAdjust(practiceGroupId,teacherId,subjectId, educationalTeacherId);
        return succeed();
    }

    @ApiOperation(value = "陪练课课程组老师批量调整")
    @PostMapping("/batchPracticeGroupTeacherAdjust")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchPracticeGroupTeacherAdjust')")
    @Transactional(rollbackFor = Exception.class)
    public Object batchPracticeGroupTeacherAdjust(String practiceGroupId, Integer teacherId, Integer subjectId, Integer educationalTeacherId,Integer oldTeacherId){
        courseScheduleService.batchPracticeGroupTeacherAdjust(practiceGroupId,teacherId,subjectId,educationalTeacherId,oldTeacherId);
        return succeed();
    }

    @ApiOperation(value = "陪练课课程组有效期调整")
    @PostMapping("/updateCoursesExpireDate")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/updateCoursesExpireDate')")
    public Object updateCoursesExpireDate(String practiceGroupId,Date coursesExpireDate){
        courseScheduleService.updateCoursesExpireDate(practiceGroupId,coursesExpireDate);
        return succeed();
    }

    @ApiOperation(value = "清空老师和学生考勤记录")
    @PostMapping("/cleanAttendance")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/cleanAttendance')")
    public Object cleanAttendance(String courseScheduleIds){
        courseScheduleService.cleanAttendance(courseScheduleIds);
        return succeed();
    }

    @ApiOperation(value = "获取课程调整时间轴")
    @PostMapping("/queryCourseAdjustDetail")
    @PreAuthorize("@pcs.hasPermissions('courseSchedule/queryCourseAdjustDetail')")
    public Object queryCourseAdjustDetail(Long courseScheduleId){
        return succeed(courseScheduleService.queryCourseAdjustDetail(courseScheduleId));
    }

    @ApiOperation(value = "冲突课程查找")
    @GetMapping("/courseRepeatCheck")
    public HttpResponseResult courseRepeatCheck(){
        courseScheduleService.courseRepeatCheck();
        return succeed();
    }
}

