package com.ym.mec.web.controller;

import com.ym.mec.biz.dal.dto.*;
import com.ym.mec.biz.dal.entity.Organization;
import com.ym.mec.biz.dal.entity.Student;
import com.ym.mec.biz.dal.page.*;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.entity.HttpResponseResult;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.QueryInfo;
import io.swagger.annotations.*;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

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

@Api(tags = "学生管理")
@RestController
@RequestMapping("studentManage")
public class StudentManageController extends BaseController {

    @Autowired
    private StudentManageService studentManageService;
    @Autowired
    private StudentRegistrationService studentRegistrationService;
    @Autowired
    private MusicGroupStudentFeeService musicGroupStudentFeeService;
    @Autowired
    private StudentCourseHomeworkService studentCourseHomeworkService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private StudentService studentService;

    @ApiOperation(value = "获取学生请假异常列表")
    @GetMapping("/queryStudentErrorLeaveList")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentErrorLeaveList')")
    public Object queryStudentErrorLeaveList(StudentErrorLeaveQueryInfo queryInfo){
        queryInfo.setOrganIds(organizationService.getEmployeeOrgan(queryInfo.getOrganIds()));
        return succeed(studentManageService.queryStudentErrorLeaveList(queryInfo));
    }

    @ApiOperation(value = "获取学生请假课程列表")
    @GetMapping("/queryStudentLeaveCourseList")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentLeaveCourseList')")
    public Object queryStudentLeaveCourseList(StudentErrorLeaveQueryInfo queryInfo){
        return succeed(studentManageService.queryStudentLeaveCourseList(queryInfo));
    }

    @ApiOperation(value = "获取学生列表")
    @PostMapping("/queryStudentList")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentList')")
    public Object queryStudentList(@RequestBody StudentManageQueryInfo queryInfo){
        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
        queryInfo.setIsExport(false);
        return succeed(studentManageService.findStudentsByOrganId(queryInfo));
    }

    @ApiOperation(value = "获取学生列表")
    @GetMapping("/queryStudent")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudent')")
    public Object queryStudent(StudentActivityQueryInfo queryInfo){
        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
        return succeed(studentManageService.queryStudent(queryInfo));
    }

    @ApiOperation(value = "获取学生列表（基本信息）")
    @GetMapping("/queryStudentBasicInfo")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentBasicInfo')")
    public Object queryStudentBasicInfo(UserBasicQueryInfo queryInfo){
        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
        return succeed(studentService.queryStudentBasicInfo(queryInfo));
    }

    @ApiOperation(value = "获取61活动学生列表")
    @GetMapping("/queryChildrenDayStudentList")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryChildrenDayStudentList')")
    public Object queryChildrenDayStudentList(StudentManageQueryInfo queryInfo){
        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
        return succeed(studentService.queryPage(queryInfo));
    }

    @ApiOperation(value = "修改学员排课资格")
    @PostMapping("/updateChildrenDayStudent")
    @PreAuthorize("@pcs.hasPermissions('studentManage/updateChildrenDayStudent')")
    public Object updateChildrenDayStudent(ActivityCourseDetailDto activityCourseDetailDto){
        studentManageService.updateChildrenDayStudent(activityCourseDetailDto);
        return succeed();
    }

    @ApiOperation(value = "获取指定分部学生列表")
    @GetMapping("/queryOrganStudentList")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryOrganStudentList')")
    public Object queryOrganStudentList(StudentManageQueryInfo queryInfo){
        if(StringUtils.isBlank(queryInfo.getOrganId())){
            return failed("请指定分部");
        }
        queryInfo.setIsExport(false);
        return succeed(studentManageService.findStudentsByOrganId(queryInfo));
    }

    @ApiOperation(value = "学员注册")
    @PostMapping("/register")
    @PreAuthorize("@pcs.hasPermissions('studentManage/register')")
    public Object studentRegister(Student student){
        return succeed(studentManageService.studentRegister(student));
    }

    @ApiOperation(value = "修改学员信息")
    @PostMapping("/studentUpdate")
    @PreAuthorize("@pcs.hasPermissions('studentManage/studentUpdate')")
    public Object studentUpdate(Student student){
        return succeed(studentManageService.studentUpdate(student));
    }

    @ApiOperation(value = "乐团管理--乐团详情--获取学员列表")
    @GetMapping("/queryMusicGroupStudent")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryMusicGroupStudent')")
    public Object queryMusicGroupStudent(MusicGroupStudentQueryInfo queryInfo){
        return succeed(studentManageService.queryMusicGroupStudent(queryInfo));
    }

    @ApiOperation(value = "乐团管理--乐团详情--学员列表--获取学员可排课时长 数据数")
    @GetMapping("/countStudentSubTotalCourseTimes")
    @PreAuthorize("@pcs.hasPermissions('studentManage/countStudentSubTotalCourseTimes')")
    public HttpResponseResult<Integer> countStudentSubTotalCourseTimes(StudentSubTotalCourseTimesQueryInfo queryInfo){
        return succeed(studentManageService.countStudentSubTotalCourseTimes(queryInfo));
    }

    @ApiOperation(value = "乐团管理--乐团详情--学员列表--获取学员可排课时长")
    @GetMapping("/queryStudentSubTotalCourseTimes")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentSubTotalCourseTimes')")
    public HttpResponseResult<PageInfo<StudentSubTotalCourseTimesDto>> queryStudentSubTotalCourseTimes(StudentSubTotalCourseTimesQueryInfo queryInfo){
        return succeed(studentManageService.queryStudentSubTotalCourseTimes(queryInfo));
    }

    @ApiOperation(value = "乐团修改--学员缴费记录--可新增学员列表")
    @GetMapping("/queryCanAddStudent")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryCanAddStudent')")
    public Object queryCanAddStudent(String musicGroupId,String batchNo,String search,Integer subjectId){
        return succeed(studentManageService.queryCanAddStudent(musicGroupId,batchNo,search,subjectId));
    }

    @ApiOperation(value = "乐团管理--乐团详情--学员列表--查看班级")
    @GetMapping("/queryStudentClassGroup")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentClassGroup')")
    @ApiImplicitParams({@ApiImplicitParam(name = "teacherId", value = "学生编号", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String")})
    public Object queryStudentClassGroup(String musicGroupId,Integer teacherId){
        if(StringUtils.isEmpty(musicGroupId) || teacherId == null){
            return failed("参数校验失败");
        }
        return succeed(studentManageService.queryStudentClassGroup(musicGroupId,teacherId));
    }

    @ApiOperation(value = "乐团管理--乐团详情--学员列表，汇总数据接口")
    @GetMapping("/musicGroupStudentsSum")
    @PreAuthorize("@pcs.hasPermissions('studentManage/musicGroupStudentsSum')")
    public Object musicGroupStudentsSum(String musicGroupId){
        return succeed(studentManageService.musicGroupStudentsSum(musicGroupId));
    }

    @ApiOperation(value = "乐团管理--乐团详情--点名总览")
    @GetMapping("/queryMusicGroupStudentsSign")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryMusicGroupStudentsSign')")
    public Object queryMusicGroupStudentsSign(StudentSignQueryInfo queryInfo){
        return succeed(studentManageService.queryMusicGroupStudentsSign(queryInfo));
    }

    @ApiOperation(value = "根据学生ID获取学生基本报名信息")
    @GetMapping("/findStudentBaseInfo")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentBaseInfo')")
    public Object findStudentBaseInfo(@ApiParam(value = "学生编号", required = true) Integer userId){
        return succeed(studentManageService.findStudentManageBaseInfo(userId));
    }

    @ApiOperation(value = "根据学生ID获取其所在的乐团")
    @GetMapping("/findStudentMusicGroups")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentMusicGroups')")
    public Object findStudentMusicGroups(@ApiParam(value = "学生编号", required = true) Integer userId){
        return succeed(studentManageService.findStudentMusicGroupsByUserId(userId));
    }

    @ApiOperation("获取学生所在乐团列表名称")
    @GetMapping(value = "/queryUserMusicInfos")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryUserMusicInfos')")
    public Object queryUserMusicInfos(Integer userId) {
        return succeed(studentManageService.queryUserMusicInfos(userId));
    }

    @ApiOperation(value = "根据乐团获取排课列表")
    @GetMapping("/findStudentCourses")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentCourses')")
    public Object findStudentCourses(StudentManageCourseQueryInfo queryInfo){
        return succeed(studentManageService.findStudentCourseList(queryInfo));
    }

    @ApiOperation(value = "获取学生签到列表")
    @GetMapping("/findStudentAttendances")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentAttendances')")
    public Object findStudentAttendances(StudentManageAttendanceQueryInfo queryInfo){
        return succeed(studentManageService.findStudentAttendances(queryInfo));
    }

    @ApiOperation(value = "获取学生vip课程")
    @GetMapping("/findStudentVipGroups")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentVipGroups')")
    public Object findStudentVipGroups(StudentManageCourseQueryInfo queryInfo){
        return succeed(studentManageService.findStudentVipGroups(queryInfo));
    }

    @ApiOperation(value = "获取学生vip班级列表")
    @GetMapping("/findStudentVipGroupClass")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentVipGroupClass')")
    public Object findStudentVipGroupClass(StudentManageVipClassQueryInfo queryInfo){
        return succeed(studentManageService.findStudentVipGroupClass(queryInfo));
    }

    @ApiOperation(value = "获取用户默认账户基本信息")
    @GetMapping("/getUserCashAccountBaseInfo")
    @PreAuthorize("@pcs.hasPermissions('studentManage/getUserCashAccountBaseInfo')")
    public Object getUserCashAccountBaseInfo(Integer userId){
        return succeed(studentManageService.getStudentAccountBaseInfo(userId));
    }

    @ApiOperation(value = "获取学员扣费记录列表")
    @GetMapping("/queryStudentPayment")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryStudentPayment')")
    public Object queryStudentPayment(TeacherPaymentRecordInfo queryInfo){
        return succeed(studentManageService.queryStudentPayment(queryInfo));
    }

    /**
     * 获取学员基本信息
     * @param mobile
     * @return
     */
    @GetMapping(value = "/queryUserByPhone")
    @PreAuthorize("@pcs.hasPermissions('studentManage/queryUserByPhone')")
    public Object queryUserByPhone(String mobile) {
        return succeed(studentRegistrationService.queryUserByPhone(mobile));
    }

    /**
     * 修改学员缴费金额和缴费周期
     * @return
     */
    @PostMapping(value = "/updateStudentFee")
    @PreAuthorize("@pcs.hasPermissions('studentManage/updateStudentFee')")
    public Object updateStudentFee(UpdateStudentFeeDto studentFeeDto) {
        musicGroupStudentFeeService.updateStudentFee(studentFeeDto);
        return succeed();
    }

    /**
     * 修改学员缴费周期锁定状态
     * @return
     */
    @PostMapping(value = "/updateStudentFeeIsLock")
    @PreAuthorize("@pcs.hasPermissions('studentManage/updateStudentFeeIsLock')")
    public Object updateStudentFeeIsLock(UpdateStudentFeeDto studentFeeDto) {
        musicGroupStudentFeeService.updateStudentFeeIsLock(studentFeeDto);
        return succeed();
    }

    /**
     * 获取学员缴费日历信息
     * @return
     */
    @GetMapping(value = "/findMusicGroupStudentFee")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findMusicGroupStudentFee')")
    public Object findMusicGroupStudentFee(Integer studentId,String musicGroupId) {
        if(studentId == null || StringUtils.isEmpty(musicGroupId)){
            throw new BizException("参数校验异常");
        }
        return succeed(musicGroupStudentFeeService.findByUser(studentId,musicGroupId));
    }

    /**
     * 获取课程学员作业列表
     * @return
     */
    @GetMapping(value = "/findStudentCourseHomeworks")
    @PreAuthorize("@pcs.hasPermissions('studentManage/findStudentCourseHomeworks')")
    public Object findStudentCourseHomeworks(QueryInfo queryInfo) {
        return succeed(studentCourseHomeworkService.findStudentCourseHomeworks(queryInfo));
    }

    /**
     * 获取课程学员作业列表
     * @return
     */
    @GetMapping(value = "/sumStudentAttendance")
    @PreAuthorize("@pcs.hasPermissions('studentManage/sumStudentAttendance')")
    public Object sumStudentAttendance(Integer courseScheduleId) {
        return succeed(studentManageService.sumStudentAttendance(courseScheduleId));
    }

    @ApiOperation(value = "获取运营指标列表")
    @GetMapping("/getOperatingStudents")
    @PreAuthorize("@pcs.hasPermissions('studentManage/getOperatingStudents')")
    public Object getOperatingStudents(StudentOperatingQueryInfo queryInfo){
        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
        return succeed(studentManageService.getOperatingStudents(queryInfo));
    }

    @ApiOperation(value = "新增会员试用")
    @PostMapping("/updateMemberExperience")
    @PreAuthorize("@pcs.hasPermissions('studentManage/updateMemberExperience')")
    public HttpResponseResult updateMemberExperience(String studentIds, Integer rankId, Date endTime){
        studentService.updateMemberExperience(studentIds,rankId,endTime);
        return succeed();
    }

    @ApiOperation(value = "初始化教师编号")
    @GetMapping("/initTeacherId")
    @PreAuthorize("@pcs.hasPermissions('studentManage/initTeacherId')")
    public HttpResponseResult initTeacherId(){
        studentService.initTeacherId();
        return succeed();
    }

    @ApiOperation(value = "修改学员的指导老师")
    @PostMapping("/batchUpdateAdviser")
    @PreAuthorize("@pcs.hasPermissions('studentManage/batchUpdateAdviser')")
    public Object batchUpdateAdviser(Integer teacherId,String studentIds){
        studentService.batchUpdateAdviser(teacherId,studentIds);
        return succeed();
    }

    @ApiOperation(value = "检查乐团是否能补招")
    @GetMapping("/checkCanReg")
    @PreAuthorize("@pcs.hasPermissions('studentManage/checkCanReg')")
    public HttpResponseResult<Boolean> checkCanReg(String musicGroupId) {
        List<String> musicGroupIds = new ArrayList<>();
        musicGroupIds.add(musicGroupId);
        Map<String, Boolean> viewMap = studentRegistrationService.checkMusicGroupsRegOrPayStatus(new ArrayList<>(musicGroupIds));
        if (viewMap.size() > 0) {
            return succeed(true);
        }
        return succeed(false);
    }

    @ApiOperation(value = "云教练学员数据预览")
    @GetMapping("/getCloudStudyStudentOverView")
    public HttpResponseResult<Object> getCloudStudyStudentOverView(String organIds) throws Exception {
        List<Integer> organIdsList;
        if(StringUtils.isNotBlank(organIds)){
            organIdsList = Arrays.stream(organIds.split(",")).map(id->Integer.valueOf(id)).collect(Collectors.toList());
        }else{
            List<Organization> organizations = organizationService.queryEmployeeOrgan();
            if(CollectionUtils.isEmpty(organizations)){
                return succeed();
            }
            organIdsList = organizations.stream().map(Organization::getId).collect(Collectors.toList());
        }
        
        List<Integer> ingnoreOrganIdList = Arrays.asList(36,39,41,42,43,44,45,46,47,48,49,50,52,54,56);
        
        organIdsList.removeAll(ingnoreOrganIdList);
        
        Map<String,Object> result = new HashMap<String, Object>();
        
        List<IndexCloudStudyListDto> list = studentService.getCloudStudyStudentOverViewList(organIdsList);
        Collections.sort(list, new Comparator<IndexCloudStudyListDto>() {

			@Override
			public int compare(IndexCloudStudyListDto o1, IndexCloudStudyListDto o2) {
				if(o1.getVipStudentRate() == o2.getVipStudentRate()){
					return 0;
				}
				if(o1.getVipStudentRate() > o2.getVipStudentRate()){
					return -1;
				}
				return 1;
			}
        	
		});
        
        result.put("list", list);
        
        CloudStudyStudentDataDto cloudStudyStudentDataDto = studentService.getCloudStudyStudentOverView(organIdsList);

        cloudStudyStudentDataDto.setCloudStudyLivelyStudentNum(list.stream().collect(Collectors.summingInt(IndexCloudStudyListDto :: getActiveStudentNum)));
        cloudStudyStudentDataDto.setTotalStudentNum(list.stream().collect(Collectors.summingInt(IndexCloudStudyListDto :: getTotalStudentNum)));
        cloudStudyStudentDataDto.setEffectiveVipStudentNum(list.stream().collect(Collectors.summingInt(IndexCloudStudyListDto :: getEffectiveVipStudentNum)));
        cloudStudyStudentDataDto.setWaitActivateVipStudentNum(list.stream().collect(Collectors.summingInt(IndexCloudStudyListDto :: getWaitActivateVipStudentNum)));
        cloudStudyStudentDataDto.setEffectiveStudentNum(list.stream().collect(Collectors.summingInt(IndexCloudStudyListDto :: getEffectiveStudentNum)));
        cloudStudyStudentDataDto.setVipStudentNum(list.stream().collect(Collectors.summingInt(IndexCloudStudyListDto :: getVipStudentNum)));

        result.put("overView", cloudStudyStudentDataDto);
        
        return succeed(result);
    }

    @ApiOperation(value = "云教练学员数据预览列表")
    @GetMapping("/getCloudStudyStudentOverViewList")
    @PreAuthorize("@pcs.hasPermissions('studentManage/getCloudStudyStudentOverViewList')")
    public HttpResponseResult<List<IndexCloudStudyListDto>> getCloudStudyStudentOverViewList(String organIds) throws Exception {
        List<Integer> organIdsList;
        if(StringUtils.isNotBlank(organIds)){
            organIdsList = Arrays.stream(organIds.split(",")).map(id->Integer.valueOf(id)).collect(Collectors.toList());
        }else{
            List<Organization> organizations = organizationService.queryEmployeeOrgan();
            if(CollectionUtils.isEmpty(organizations)){
                return succeed();
            }
            organIdsList = organizations.stream().map(Organization::getId).collect(Collectors.toList());
        }
        
        return succeed(studentService.getCloudStudyStudentOverViewList(organIdsList));
    }

    @ApiOperation(value = "分部云教练学员数据预览")
    @GetMapping("/organStudentOverView")
    @PreAuthorize("@pcs.hasPermissions('studentManage/organStudentOverView')")
    public HttpResponseResult<PageInfo<EduOrganStudentDataDto>> organStudentOverView(OrganCloudStudyStudentDataQueryInfo queryInfo) throws Exception {
        String organIds = organizationService.getEmployeeOrgan("");
        List<Integer> collect = Arrays.stream(organIds.split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
        List<Integer> ids = collect.stream().filter(id -> !OrganizationService.EXCLUDE_ORGAN_IDS.contains(id)).collect(Collectors.toList());
        return succeed(studentService.queryOrganStudentOverView(ids, queryInfo));
    }

    @ApiOperation(value = "云教练学员数据")
    @GetMapping("/organStudentData")
    @PreAuthorize("@pcs.hasPermissions('studentManage/organStudentData')")
    public HttpResponseResult<StatDto> organStudentData(StudentQueryInfo queryInfo){
        return succeed(studentService.organStudentData(queryInfo));
    }

    @ApiOperation(value = "云教练活动统计")
    @GetMapping("/countCloudTeacherActive")
    @PreAuthorize("@pcs.hasPermissions('studentManage/countCloudTeacherActive')")
    public Object countCloudTeacherActive(CloudTeacherActiveQueryInfo queryInfo) throws Exception {
        String organIds = organizationService.getEmployeeOrgan("");
        queryInfo.setPage(1);
        queryInfo.setRows(49999);
        List<Integer> collect = Arrays.stream(organIds.split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
        List<Integer> ids = collect.stream().filter(id -> !OrganizationService.EXCLUDE_ORGAN_IDS.contains(id)).collect(Collectors.toList());
        return succeed(studentService.countCloudTeacherActive(ids, queryInfo));
    }

    @ApiOperation(value = "云教练活动统计详情")
    @GetMapping("/countCloudTeacherActiveDetail")
    @PreAuthorize("@pcs.hasPermissions('studentManage/countCloudTeacherActiveDetail')")
    public Object countCloudTeacherActiveDetail(CloudTeacherActiveQueryInfo queryInfo) throws Exception {
        return succeed(studentService.countCloudTeacherActiveDetail(queryInfo));
    }
}
