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

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

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

import com.alibaba.fastjson.JSONObject;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.api.entity.SysUserRole;
import com.ym.mec.biz.dal.dao.MusicGroupDao;
import com.ym.mec.biz.dal.dao.TeacherDao;
import com.ym.mec.biz.dal.dao.TeacherLeaveRecordDao;
import com.ym.mec.biz.dal.entity.CourseSchedule;
import com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType;
import com.ym.mec.biz.dal.entity.Teacher;
import com.ym.mec.biz.dal.entity.TeacherLeaveRecord;
import com.ym.mec.biz.dal.entity.TeacherLeaveRecord.CoursesScheduleHistory;
import com.ym.mec.biz.dal.enums.AuditStatusEnum;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.service.CourseScheduleService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.biz.service.TeacherLeaveRecordService;
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.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.date.DateUtil;
import com.ym.mec.util.json.JsonUtil;

@Service
public class TeacherLeaveRecordServiceImpl extends BaseServiceImpl<Long, TeacherLeaveRecord> implements TeacherLeaveRecordService {

	@Autowired
	private TeacherLeaveRecordDao teacherLeaveRecordDao;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private MusicGroupDao musicGroupDao;

	@Autowired
	private CourseScheduleService courseScheduleService;

	@Autowired
	private SysMessageService sysMessageService;

	@Autowired
	private SysUserFeignService sysUserFeignService;

	@Override
	public BaseDAO<Long, TeacherLeaveRecord> getDAO() {
		return teacherLeaveRecordDao;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean askForLeave(TeacherLeaveRecord teacherLeaveRecord) {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (Objects.isNull(sysUser)) {
			throw new BizException("获取用户信息失败");
		}
		Date date = new Date();

		teacherLeaveRecord.setUserId(sysUser.getId());
		teacherLeaveRecord.setUpdateTime(date);
		teacherLeaveRecord.setCreateTime(date);
		teacherLeaveRecord.setStatus(AuditStatusEnum.ING);
		teacherLeaveRecord.setDays(DateUtil.hoursBetween(teacherLeaveRecord.getStartTime(), teacherLeaveRecord.getEndTime()) / 8d);

		if (StringUtils.isNotBlank(teacherLeaveRecord.getCoursesScheduleJson())) {
			List<CoursesScheduleHistory> coursesScheduleHistoryList = JsonUtil.parseArray(teacherLeaveRecord.getCoursesScheduleJson(),
					CoursesScheduleHistory.class);

			if (coursesScheduleHistoryList != null && coursesScheduleHistoryList.size() > 0) {

				List<CourseSchedule> list = new ArrayList<CourseSchedule>();

				for (CoursesScheduleHistory his : coursesScheduleHistoryList) {
					if (his.getBefore().getType() != CourseScheduleType.VIP) {
						continue;
					}
					if(!teacherLeaveRecord.getEndTime().before(his.getAfter().getStartClassTime())
							&&!teacherLeaveRecord.getStartTime().after(his.getAfter().getEndClassTime())){
						throw new BizException("课程时间与老师请假时间存在冲突");
					}

					list.add(his.getAfter());
				}

				if(list.size() > 0){
					// checkCourseSchedulePlansExitLeaveRecord(list);
				}
			}
		}
		teacherLeaveRecordDao.insert(teacherLeaveRecord);
		Set<Integer> roleIds = new HashSet<>(1);
		roleIds.add(SysUserRole.DEAN_OF_STUDIES);
		Teacher teacher = teacherDao.get(sysUser.getId());
		Set<Integer> userIds = musicGroupDao.queryUserIdByRoleId(roleIds,teacher.getTeacherOrganId());
		if (userIds != null && userIds.size() > 0) {
			Map<String,Object> memo = new HashMap<>(1);
			memo.put("leaveRecordId",teacherLeaveRecord.getId());
			sysMessageService.batchSeoMessage(userIds, MessageTypeEnum.EDUCATION_PUSH_TEACHER_LEAVE_APPLY, JSONObject.toJSONString(memo), sysUser.getRealName());
		}
		return true;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean approve(Long id, Integer userId, AuditStatusEnum status, String remark) {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (Objects.isNull(sysUser)) {
			throw new BizException("获取用户信息失败");
		}
		TeacherLeaveRecord teacherLeaveRecord = teacherLeaveRecordDao.get(id);
		if (teacherLeaveRecord == null) {
			throw new BizException("请假记录不存在");
		}

		if (teacherLeaveRecord.getStatus() != AuditStatusEnum.ING || status == AuditStatusEnum.ING) {
			throw new BizException("审批状态不正确");
		}

		teacherLeaveRecord.setStatus(status);
		teacherLeaveRecord.setRemark(remark);

		teacherLeaveRecordDao.update(teacherLeaveRecord);

		if (StringUtils.isNotBlank(teacherLeaveRecord.getCoursesScheduleJson())&&status==AuditStatusEnum.PASS) {
			List<CoursesScheduleHistory> coursesScheduleHistoryList = JsonUtil.parseArray(teacherLeaveRecord.getCoursesScheduleJson(),
					CoursesScheduleHistory.class);

			if (coursesScheduleHistoryList != null && coursesScheduleHistoryList.size() > 0) {

				List<CourseSchedule> list = new ArrayList<CourseSchedule>();

				for (CoursesScheduleHistory his : coursesScheduleHistoryList) {
					if (his.getBefore().getType() != CourseScheduleType.VIP) {
						continue;
					}
					list.add(his.getAfter());
				}
				// 课时调整
				if (list.size() > 0) {
					courseScheduleService.courseAdjust(list);
				}
			}
		}
		//教师请假结果通知
		Map<Integer,String> map = new HashMap<>(1);
		Teacher teacher = teacherDao.get(teacherLeaveRecord.getUserId());
		map.put(teacher.getId(),teacher.getId() + "");
		sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TEACHER_PUSH_LEAVE_RESULT,
				map,null,0,"7","TEACHER",status.getMsg());
		return true;
	}

	@Override
	public void checkCourseSchedulePlansExitLeaveRecord(List<CourseSchedule> courseSchedules){
		Date now=new Date();
		List<Integer> teacherIds = courseSchedules.stream().map(CourseSchedule::getActualTeacherId).collect(Collectors.toList());
		List<TeacherLeaveRecord> teacherLeaveRecords = teacherLeaveRecordDao.findByTeacherIds(teacherIds, now);
		Map<Integer, List<TeacherLeaveRecord>> teacherLeaveRecordByTeacher = teacherLeaveRecords.stream().collect(Collectors.groupingBy(TeacherLeaveRecord::getUserId));
		courseSchedules.forEach(courseSchedule -> {
			List<TeacherLeaveRecord> teacherLeaveRecordsWithTeacher = teacherLeaveRecordByTeacher.get(courseSchedule.getActualTeacherId());
			if(CollectionUtils.isEmpty(teacherLeaveRecordsWithTeacher)){
				return;
			}
			teacherLeaveRecordsWithTeacher.forEach(teacherLeaveRecord -> {
				if(!teacherLeaveRecord.getEndTime().before(courseSchedule.getStartClassTime())
					&&!teacherLeaveRecord.getStartTime().after(courseSchedule.getEndClassTime())){
					throw new BizException("课程时间与老师请假时间存在冲突");
				}
			});
		});
	}
}
