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

import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.CourseViewTypeEnum;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.HttpResponseResult;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.redis.service.RedisCache;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;
import com.ym.mec.util.http.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class MusicGroupSchoolTermCourseDetailServiceImpl extends BaseServiceImpl<Integer, MusicGroupSchoolTermCourseDetail>  implements MusicGroupSchoolTermCourseDetailService {
	
	@Autowired
	private MusicGroupSchoolTermCourseDetailDao musicGroupSchoolTermCourseDetailDao;
	@Autowired
	private MusicGroupSchoolTermStudentCourseDetailDao musicGroupSchoolTermStudentCourseDetailDao;
	@Autowired
	private StudentRegistrationDao studentRegistrationDao;
	@Autowired
	private MusicGroupDao musicGroupDao;
	@Autowired
	private CourseScheduleDao courseScheduleDao;
	@Autowired
	private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
	@Autowired
	private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
	@Autowired
	private SysConfigDao sysConfigDao;
	@Autowired
	private SysTenantConfigService sysTenantConfigService;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private StudentDao studentDao;
	@Autowired
	private MemberRankSettingDao memberRankSettingDao;
	@Autowired
	private MemberFeeSettingDao memberFeeSettingDao;
	@Autowired
	private OrganizationDao organizationDao;
	@Autowired
	private MusicGroupPaymentCalenderService musicGroupPaymentCalenderService;
	@Autowired
	private MusicGroupPaymentCalenderDetailService musicGroupPaymentCalenderDetailService;
	@Autowired
	private RedisCache<String, Object> redisCache;

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Override
	public BaseDAO<Integer, MusicGroupSchoolTermCourseDetail> getDAO() {
		return musicGroupSchoolTermCourseDetailDao;
	}

    @Override
    public MusicGroupSchoolTermCourseDetail findByMusicGroupId(String musicGroupId) {
		return musicGroupSchoolTermCourseDetailDao.findByCourseDateAndMusicGroupId(musicGroupId,null,0);
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public HttpResponseResult upset(MusicGroupSchoolTermCourseDetail musicGroupSchoolTermCourseDetail) {
		Date startCourseDate = musicGroupSchoolTermCourseDetail.getStartCourseDate();
		String musicGroupId = musicGroupSchoolTermCourseDetail.getMusicGroupId();
		MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
		if(musicGroup.getCourseViewType() != CourseViewTypeEnum.MEMBER_FEE){
			throw new BizException("操作失败：该功能只适用于系统收费团");
		}
		//校验当前乐团是否所有学员都在班
		String notClassName = studentRegistrationDao.getNotClassName(musicGroupId);
		if(StringUtils.isNotEmpty(notClassName)){
			throw new BizException("操作失败：{} 学员未在以下任何班级",notClassName);
		}
		MusicGroupSchoolTermCourseDetail courseDetail = musicGroupSchoolTermCourseDetailDao.
				findByCourseDateAndMusicGroupId(musicGroupId,null,0);
		Date date = DateUtil.stringToDate(DateUtil.format(new Date(),DateUtil.ISO_EXPANDED_DATE_FORMAT),DateUtil.ISO_EXPANDED_DATE_FORMAT);
		if(startCourseDate != null){
			MusicGroupSchoolTermCourseDetail courseDetail1 = musicGroupSchoolTermCourseDetailDao.findByCourseDateAndMusicGroupId(musicGroupId,startCourseDate,1);
			if(courseDetail1 != null){
				throw new BizException("操作失败：所选时间段已排课，请勿重复操作");
			}
			if(DateUtil.daysBetween(date, startCourseDate) < 0){
				//如果所选时间小于当前时间
				throw new BizException("操作失败：开课时间不得小于当前时间");
			}
		}
		if(courseDetail != null){
			if(startCourseDate != null){
				//如果是重新选择的预排课时间
//				if(DateUtil.daysBetween(startCourseDate, courseDetail.getStartCourseDate()) != 0){
					//清空预排课
					if(musicGroupSchoolTermCourseDetail.getCleanPreCourseFlag()){
						//删除乐团预排的课程
						courseScheduleStudentPaymentDao.deletePreCourse(musicGroupId);
						courseScheduleTeacherSalaryDao.deletePreCourse(musicGroupId);
						courseScheduleDao.deletePreCourse(musicGroupId);
						courseDetail.setStartCourseDate(startCourseDate);
						getCourseDetail(courseDetail);
						musicGroupSchoolTermCourseDetailDao.update(courseDetail);
						//删除学员排课时长
						musicGroupSchoolTermStudentCourseDetailDao.deleteByDetailId(courseDetail.getId(),null);
						//生成学员可排课时长
						MusicGroupSchoolTermStudentCourseDetail studentCourseDetail = new MusicGroupSchoolTermStudentCourseDetail();
						studentCourseDetail.setMusicGroupSchoolTermCourseDetailId(courseDetail.getId());
						studentCourseDetail.setMemberCourseMinutes(courseDetail.getTotalCourseTime());
						//获取乐团所有在读学员
						List<Integer> studentIds = studentRegistrationDao.queryNormalUserList(musicGroupId);
						if(studentIds == null || studentIds.size() == 0){
							throw new BizException("操作失败：该乐团没有在读学员");
						}
						musicGroupSchoolTermStudentCourseDetailDao.init(studentCourseDetail,studentIds);
					}else {
						return BaseController.failed(HttpStatus.MULTI_STATUS, "修改开课日期会清空预排课，请再次确认");
					}
//				}
			}else {
				//如果所选时间小于当前时间
				if(DateUtil.daysBetween(date, courseDetail.getStartCourseDate()) < 0){
					throw new BizException("开课时间不得小于当前时间，请重新配置");
				}
			}
		}else {
			if(startCourseDate != null){
				courseDetail = new MusicGroupSchoolTermCourseDetail();
				courseDetail.setMusicGroupId(musicGroupId);
				courseDetail.setCourseFlag(false);
				courseDetail.setStartCourseDate(startCourseDate);
				getCourseDetail(courseDetail);
				musicGroupSchoolTermCourseDetailDao.insert(courseDetail);
				//生成学员可排课时长
				MusicGroupSchoolTermStudentCourseDetail studentCourseDetail = new MusicGroupSchoolTermStudentCourseDetail();
				studentCourseDetail.setMusicGroupSchoolTermCourseDetailId(courseDetail.getId());
				studentCourseDetail.setMemberCourseMinutes(courseDetail.getTotalCourseTime());
				studentCourseDetail.setTenantId(musicGroup.getTenantId());
				//获取乐团所有在读学员
				List<Integer> studentIds = studentRegistrationDao.queryNormalUserList(musicGroupId);
				if(studentIds == null || studentIds.size() == 0){
					throw new BizException("操作失败：该乐团没有在读学员");
				}
				musicGroupSchoolTermStudentCourseDetailDao.init(studentCourseDetail,studentIds);
			}
		}
		return BaseController.succeed(courseDetail);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void musicSchoolTermPush(Integer tenantId) {
		String remindCourseTime = sysTenantConfigService.getTenantConfigValue(SysConfigService.REMIND_COURSE_TIME,tenantId);
		if(StringUtils.isNotEmpty(remindCourseTime)){
			//获取当前学期截止前14天的乐团，并提醒教务老师排课
			List<String> musicGroupIds = musicGroupSchoolTermCourseDetailDao.queryPushCourseTermMusicIds(remindCourseTime,tenantId);
			if(musicGroupIds.size() > 0){
				List<MusicGroup> musicGroupList = musicGroupDao.getMusicGroupByIds(musicGroupIds);
				List<Integer> educationIds = musicGroupList.stream().map(e -> e.getEducationalTeacherId()).collect(Collectors.toList());
				Map<Integer, String> educationPhoneMap = MapUtil.convertMybatisMap(teacherDao.queryPhoneByIds(StringUtils.join(educationIds,",")));
				for (MusicGroup musicGroup : musicGroupList) {
					Map<Integer,String> userMap = new HashMap<>(1);
					userMap.put(musicGroup.getEducationalTeacherId(),educationPhoneMap.get(musicGroup.getEducationalTeacherId()));
					sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS,
							MessageTypeEnum.SYSTEM_REMIND_EDUCATION_COURSE_TIME,
							userMap,
							null,
							0,
							null,
							null,
							musicGroup.getName());
					Map<Integer,String> userMap1 = new HashMap<>(1);
					userMap1.put(musicGroup.getEducationalTeacherId(),musicGroup.getEducationalTeacherId().toString());
					sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
							MessageTypeEnum.SYSTEM_REMIND_EDUCATION_COURSE_TIME,
							userMap1,
							null,
							0,
							null,
							"SYSTEM",
							musicGroup.getName());
				}
			}
		}
		//提醒会员续费
		String pushMemberRenewAgain = sysTenantConfigService.getTenantConfigValue(SysConfigService.PUSH_MEMBER_RENEW_AGAIN,tenantId);
		String memberName = "黄金会员";
		MemberRankSetting memberRankSetting = memberRankSettingDao.get(1);
		if(memberRankSetting != null){
			memberName = memberRankSetting.getName();
		}
		if(StringUtils.isNotEmpty(pushMemberRenewAgain)){
			List<Integer> studentIdList = studentDao.queryPushMemberRenew(pushMemberRenewAgain, tenantId);
			if(studentIdList.size() > 0){
				Map<Integer, String> studentPhoneMap = MapUtil.convertMybatisMap(teacherDao.queryPhoneByIds(StringUtils.join(studentIdList,",")));
				Map<Integer,String> userMap = new HashMap<>(studentIdList.size());
				Map<Integer,String> userMap1 = new HashMap<>(studentIdList.size());
				for (Integer studentId : studentIdList) {
					userMap.put(studentId,studentPhoneMap.get(studentId));
					userMap1.put(studentId,studentId.toString());
				}
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS,
						MessageTypeEnum.STUDENT_MEMBER_RENEW_MESSAGE,
						userMap,
						null,
						0,
						null,
						null,memberName,pushMemberRenewAgain);

				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
						MessageTypeEnum.STUDENT_MEMBER_RENEW_MESSAGE,
						userMap1,
						null,
						0,
						null,
						"STUDENT",memberName,pushMemberRenewAgain);
			}
		}
	}

	private MusicGroupSchoolTermCourseDetail getCourseDetail(MusicGroupSchoolTermCourseDetail courseDetail){
		Date startCourseDate = courseDetail.getStartCourseDate();
		//一个学期默认为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){
				courseDetail.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));
				courseDetail.setStartSchoolTerm(DateUtil.stringToDate(year1 + "-09-01 00:00:00"));
			}
			courseDetail.setEndSchoolTerm(DateUtil.getLastDayOfMonth(DateUtil.stringToDate(year + "-02-01 00:00:00")));
		}else {
			courseDetail.setStartSchoolTerm(DateUtil.stringToDate(year + "-03-01 00:00:00"));
			courseDetail.setEndSchoolTerm(DateUtil.stringToDate(year + "-08-31 00:00:00"));
		}
//		courseDetail.setStartSchoolTerm(startCourseDate);
		//计算可排课时长
//		int week = LocalDateTime.ofInstant(startCourseDate.toInstant(),DateUtil.zoneId).getDayOfWeek().getValue();
		int week = DateUtil.date2Week1(startCourseDate);
		int weekSize = DateUtil.getWeekDays(startCourseDate, courseDetail.getEndSchoolTerm(), week).size();
		int i = weekSize * 4 * 45;
		Integer tenantId = TenantContextHolder.getTenantId();
		String configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.MEMBER_GROUP_TERM_GIVE_COURSE_TIME,tenantId);
		if(StringUtils.isEmpty(configValue)){
			throw new BizException("请配置会员团每学期赠送课程分钟数");
		}
		Integer giveCourseTime = Integer.parseInt(configValue);
		courseDetail.setTotalCourseTime(i > giveCourseTime?giveCourseTime:i);
		courseDetail.setStartCourseDate(startCourseDate);
		return courseDetail;
	}
}