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

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.CourseScheduleDao;
import com.ym.mec.biz.dal.dao.MusicGroupTrainPlanDao;
import com.ym.mec.biz.dal.dto.WaitCourseTrainPlanDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.service.MusicGroupTrainPlanService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MusicGroupTrainPlanServiceImpl extends BaseServiceImpl<Integer, MusicGroupTrainPlan>  implements MusicGroupTrainPlanService {
	
	@Autowired
	private MusicGroupTrainPlanDao musicGroupTrainPlanDao;
	@Autowired
	private CourseScheduleDao courseScheduleDao;
	@Autowired
	private ClassGroupDao classGroupDao;
	@Autowired
	private SysUserFeignService sysUserFeignService;

	@Override
	public BaseDAO<Integer, MusicGroupTrainPlan> getDAO() {
		return musicGroupTrainPlanDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int add(MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto) {
		//获取学期时间
		getCourseDetail(musicGroupTrainPlanSaveDto);
		List<String> plans = musicGroupTrainPlanSaveDto.getPlans();
		if(plans == null || plans.size() == 0){
			throw new BizException("请录入课程规划");
		}
		//获取当前班级的课程类型课程数
		int courseNum = courseScheduleDao.countCourseByClassAndType(musicGroupTrainPlanSaveDto);
		int planNum = musicGroupTrainPlanDao.countPlanNum(musicGroupTrainPlanSaveDto);
		if((planNum + plans.size()) > courseNum){
			throw new BizException("课程规划不得超过课程数");
		}
		return musicGroupTrainPlanDao.add(musicGroupTrainPlanSaveDto);
	}

	@Override
	public Map<String,Object> queryPlanPage(MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto) {
		getCourseDetail(musicGroupTrainPlanSaveDto);
		//课程时间列表
		List<String> classDates = courseScheduleDao.queryClassDateList(musicGroupTrainPlanSaveDto);
		Map<String,Object> paramMap = new HashMap<>();
		paramMap.put("classGroupId",musicGroupTrainPlanSaveDto.getClassGroupId());
		paramMap.put("courseScheduleType",musicGroupTrainPlanSaveDto.getCourseScheduleType());
		paramMap.put("startSchoolTerm",musicGroupTrainPlanSaveDto.getStartSchoolTerm());
		paramMap.put("endSchoolTerm",musicGroupTrainPlanSaveDto.getEndSchoolTerm());
		paramMap.put("tenantId",musicGroupTrainPlanSaveDto.getTenantId());
		//课程规划
		List<MusicGroupTrainPlan> musicGroupTrainPlans = musicGroupTrainPlanDao.findAll(paramMap);
		Map<String,Object> resultMap = new HashMap<>(2);
		resultMap.put("classDates",classDates);
		resultMap.put("musicGroupTrainPlans",musicGroupTrainPlans);
		return resultMap;
	}

	@Override
	public List<ClassGroup> queryPlanCourseNum(MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto) {
		List<ClassGroup> classGroups;
		if(musicGroupTrainPlanSaveDto.getStudentFlag()){
			SysUser sysUser = sysUserFeignService.queryUserInfo();
			if(sysUser == null){
				throw new BizException("请登录");
			}
			classGroups = classGroupDao.queryStudentClassGroups(musicGroupTrainPlanSaveDto.getMusicGroupId(),sysUser.getId());
		}else {
			classGroups = classGroupDao.findClassGroups(musicGroupTrainPlanSaveDto.getMusicGroupId());
		}
		if(classGroups.size() == 0){
			return null;
		}
		List<Integer> classGroupIdList = classGroups.stream().map(e -> e.getId()).collect(Collectors.toList());
		getCourseDetail(musicGroupTrainPlanSaveDto);
		Map<Integer, Long> totalNumMap = MapUtil.convertIntegerMap(courseScheduleDao.countTotalNumByClassGroupIds(classGroupIdList, musicGroupTrainPlanSaveDto.getStartSchoolTerm(),musicGroupTrainPlanSaveDto.getEndSchoolTerm()));
		Map<Integer, Long> currentNumMap = MapUtil.convertIntegerMap(courseScheduleDao.countExpendNumByClassGroupIds(classGroupIdList, musicGroupTrainPlanSaveDto.getStartSchoolTerm(),musicGroupTrainPlanSaveDto.getEndSchoolTerm()));
		for (ClassGroup classGroup : classGroups) {
			int totalClassTimes = 0;
			int currentClassTimes = 0;
			if (totalNumMap.containsKey(classGroup.getId())) {
				totalClassTimes = totalNumMap.get(classGroup.getId()).intValue();
			}
			if (currentNumMap.containsKey(classGroup.getId())) {
				currentClassTimes = currentNumMap.get(classGroup.getId()).intValue();
			}
			classGroup.setTotalClassTimes(totalClassTimes);
			classGroup.setCurrentClassTimes(currentClassTimes);
		}
		return classGroups;
	}

    @Override
    public List<String> queryCourseType(MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto) {
		getCourseDetail(musicGroupTrainPlanSaveDto);
		List<String> strings = courseScheduleDao.queryCourseTypeByClassGroupIds(musicGroupTrainPlanSaveDto);
		return strings;
    }

	@Override
	public Map<String, Object> queryExceptionPlan(MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto) {
		getCourseDetail(musicGroupTrainPlanSaveDto);
		Map<String,Object> resultMap = new HashMap<>(2);
		//获取乐团当前学期每个班级不同课程类型数量
		List<WaitCourseTrainPlanDto> waitCourseTrainPlanDtos = musicGroupTrainPlanDao.queryWaitCourseTrainPlan(musicGroupTrainPlanSaveDto);
		resultMap.put("waitCourseTrainPlanDtos",waitCourseTrainPlanDtos);
		List<WaitCourseTrainPlanDto> queryWaitCourseTrainPlan1 = musicGroupTrainPlanDao.queryWaitCourseTrainPlan1(musicGroupTrainPlanSaveDto);
		resultMap.put("waitCourseTrainPlanDtos1",queryWaitCourseTrainPlan1);
		return resultMap;
	}

	private MusicGroupTrainPlanSaveDto getCourseDetail(MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto){
		String year = musicGroupTrainPlanSaveDto.getYear();
		if(StringUtils.isEmpty(year)){
			throw new BizException("请录入年份");
		}
		Integer term = musicGroupTrainPlanSaveDto.getTerm();
		if(term == null){
			throw new BizException("请录入学期");
		}
		if(term == 0){
			musicGroupTrainPlanSaveDto.setStartSchoolTerm(DateUtil.stringToDate(year + "-03-01 00:00:00"));
			musicGroupTrainPlanSaveDto.setEndSchoolTerm(DateUtil.stringToDate(year + "-08-31 00:00:00"));
		}else {
			musicGroupTrainPlanSaveDto.setStartSchoolTerm(DateUtil.stringToDate(year + "-09-01 00:00:00"));
			year = DateUtil.getYear(DateUtil.addYears(musicGroupTrainPlanSaveDto.getStartSchoolTerm(), 1));
			musicGroupTrainPlanSaveDto.setEndSchoolTerm(DateUtil.getLastDayOfMonth(DateUtil.stringToDate(year + "-02-01 00:00:00")));
		}
		return musicGroupTrainPlanSaveDto;
	}

	@Override
	public MusicGroupTrainPlanSaveDto getSchoolTerm(CourseSchedule courseSchedule){
		MusicGroupTrainPlanSaveDto musicGroupTrainPlanSaveDto = new MusicGroupTrainPlanSaveDto();
		Date startCourseDate = courseSchedule.getClassDate();
		//一个学期默认为6个月，9月1日—2月28、29日，3月1日—8月31日
		Integer month = Integer.parseInt(DateUtil.getMonth(startCourseDate));
		String year = DateUtil.getYear(startCourseDate);
		if(month >= 9 || month <= 2){
			if(month >= 9){
				musicGroupTrainPlanSaveDto.setStartSchoolTerm(DateUtil.stringToDate(year + "-09-01 00:00:00"));
				year = DateUtil.getYear(DateUtil.addYears(startCourseDate, 1));
			}else {
				String year1 = DateUtil.getYear(DateUtil.addYears(startCourseDate, -1));
				musicGroupTrainPlanSaveDto.setStartSchoolTerm(DateUtil.stringToDate(year1 + "-09-01 00:00:00"));
			}
			musicGroupTrainPlanSaveDto.setEndSchoolTerm(DateUtil.getLastDayOfMonth(DateUtil.stringToDate(year + "-02-01 00:00:00")));
		}else {
			musicGroupTrainPlanSaveDto.setStartSchoolTerm(DateUtil.stringToDate(year + "-03-01 00:00:00"));
			musicGroupTrainPlanSaveDto.setEndSchoolTerm(DateUtil.stringToDate(year + "-08-31 00:00:00"));
		}
		musicGroupTrainPlanSaveDto.setMusicGroupId(courseSchedule.getMusicGroupId());
		musicGroupTrainPlanSaveDto.setClassGroupId(courseSchedule.getClassGroupId());
		musicGroupTrainPlanSaveDto.setCourseScheduleType(courseSchedule.getType().getCode());
		musicGroupTrainPlanSaveDto.setCourseClassTime(courseSchedule.getStartClassTime());
		return musicGroupTrainPlanSaveDto;
	}

	@Override
	public List<MusicGroupTrainPlan> queryPlan(MusicGroupTrainPlanSaveDto schoolTerm) {
		schoolTerm.setTenantId(TenantContextHolder.getTenantId());
		return musicGroupTrainPlanDao.queryPlan(schoolTerm);
	}
}