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

import com.ym.mec.biz.dal.dao.ExtracurricularExercisesDao;
import com.ym.mec.biz.dal.dao.ExtracurricularExercisesReplyDao;
import com.ym.mec.biz.dal.dao.StudentExtracurricularExercisesSituationDao;
import com.ym.mec.biz.dal.dao.TeacherDao;
import com.ym.mec.biz.dal.dto.BasicUserDto;
import com.ym.mec.biz.dal.dto.SimpleUserDto;
import com.ym.mec.biz.dal.entity.ExtracurricularExercises;
import com.ym.mec.biz.dal.entity.ExtracurricularExercisesReply;
import com.ym.mec.biz.dal.entity.Teacher;
import com.ym.mec.biz.dal.enums.ImSendTypeEnum;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.page.ExtraExercilseQueryInfo;
import com.ym.mec.biz.service.ExtracurricularExercisesService;
import com.ym.mec.biz.service.StudentServeService;
import com.ym.mec.biz.service.SysMessageService;
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.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.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExtracurricularExercisesServiceImpl extends BaseServiceImpl<Long, ExtracurricularExercises> implements ExtracurricularExercisesService {
	
	@Autowired
	private ExtracurricularExercisesDao extracurricularExercisesDao;
	@Autowired
	private ExtracurricularExercisesReplyDao extracurricularExercisesReplyDao;
	@Autowired
	private StudentExtracurricularExercisesSituationDao studentExtracurricularExercisesSituationDao;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private StudentServeService studentServeService;

	@Override
	public BaseDAO<Long, ExtracurricularExercises> getDAO() {
		return extracurricularExercisesDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
	public void createExtraExercises(ExtracurricularExercises exercises) {
		if(StringUtils.isBlank(exercises.getTitle())){
			throw new BizException("请填写标题");
		}
		if(StringUtils.isBlank(exercises.getContent())){
			throw new BizException("请填写内容");
		}
		if(StringUtils.isBlank(exercises.getStudentIdList())){
			throw new BizException("请指定学生");
		}

		teacherDao.getLocked(exercises.getTeacherId());
		Teacher teacher = teacherDao.get(exercises.getTeacherId());

		ExtracurricularExercises repeatLastExercises = extracurricularExercisesDao.findRepeatLastExercises(exercises.getTeacherId(), exercises.getStudentIdList(), exercises.getContent());
		if(Objects.nonNull(repeatLastExercises)&&DateUtil.secondsBetween(repeatLastExercises.getCreateTime(),new Date())<60){
			return;
		}

		if(Objects.isNull(exercises.getExpireDate())){
			LocalDateTime localDateTime=LocalDateTime.now();
			localDateTime=localDateTime.plusDays(2).withHour(21).withMinute(0).withSecond(0);
			exercises.setExpireDate(Date.from(localDateTime.atZone(DateUtil.zoneId).toInstant()));
		}
		List<Integer> studentIds = Arrays.asList(exercises.getStudentIdList().split(",")).stream().mapToInt(Integer::valueOf).boxed().collect(Collectors.toList());
		exercises.setBatchNo(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
		exercises.setExpectNum(studentIds.size());
		extracurricularExercisesDao.insert(exercises);
		String dateStr = DateUtil.dateToString(exercises.getExpireDate(), "MM月dd日HH点");
		for (Integer studentId : studentIds) {
			ExtracurricularExercisesReply studentExtraExercise=new ExtracurricularExercisesReply();
			studentExtraExercise.setExtracurricularExercisesId(exercises.getId());
			studentExtraExercise.setUserId(studentId);
			studentExtraExercise.setStatus(0);
			studentExtraExercise.setIsReplied(0);
			studentExtraExercise.setIsView(0);
			studentExtraExercise.setIsRepliedTimely(0);
			extracurricularExercisesReplyDao.insert(studentExtraExercise);

			String notifyUrl = "?courseScheduleID=" + studentExtraExercise.getId() + "&studentCourseHomeworkId=" + studentExtraExercise.getId() + "&extra=1";
			String extra = "dayaedu" + notifyUrl + "&userId=" + studentId;
			if (exercises.getMsgType() != ImSendTypeEnum.TXT){
				sysMessageService.batchSendImMessage(MessageTypeEnum.EXTRA_REMIND_IM_DETAIL,exercises.getTeacherId().toString(),extra,
						new String[]{studentId.toString()},
						null, exercises.getTitle(), dateStr);
			}else {
				sysMessageService.batchSendImMessage(MessageTypeEnum.EXTRA_REMIND_IM,exercises.getTeacherId().toString(),extra,
						new String[]{studentId.toString()},
						null, exercises.getTitle(), dateStr,exercises.getContent());
			}
			Map<Integer, String> userMap = new HashMap<>();
			userMap.put(studentId, studentId.toString());
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.EXTRA_REMIND_PUSH,
					userMap, null, 0, 3+notifyUrl, "STUDENT",
					teacher.getRealName(),exercises.getTitle(), dateStr);
		}
		studentServeService.updateExercisesSituation(new Date(), studentIds, exercises.getTeacherId());
	}

	@Override
	public List<Map<String, Object>> findExtraExercilses(ExtraExercilseQueryInfo queryInfo) {
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		List<Map<String, Object>> result = new ArrayList<>();

		List<ExtracurricularExercises> dataList = extracurricularExercisesDao.findExtraExercises(params);
		if(!CollectionUtils.isEmpty(dataList)){
			List<Long> extraExerciseIds = dataList.stream().map(ExtracurricularExercises::getId).collect(Collectors.toList());
			List<ExtracurricularExercisesReply> extraExerciseStudentsByExtraExercises = extracurricularExercisesReplyDao.findExtraExerciseStudentsByExtraExercises(extraExerciseIds);
			Map<Long, List<ExtracurricularExercisesReply>> idStudentsMap = extraExerciseStudentsByExtraExercises.stream().collect(Collectors.groupingBy(ExtracurricularExercisesReply::getExtracurricularExercisesId));
			for (ExtracurricularExercises extracurricularExercises : dataList) {
				List<ExtracurricularExercisesReply> extracurricularExercisesReplies = idStudentsMap.get(extracurricularExercises.getId());
				if(CollectionUtils.isEmpty(extracurricularExercisesReplies)){
					continue;
				}
				long noRepliedNum = extracurricularExercisesReplies.stream().filter(e -> e.getStatus()==1&&e.getIsReplied() == 0).count();
				if(noRepliedNum<=0){
					extracurricularExercises.setIsReplied(1);
				}
				long notSubmitNum = extracurricularExercisesReplies.stream().filter(e -> e.getStatus() == 0).count();
				if(notSubmitNum<=0){
					extracurricularExercises.setIsSubmit(1);
				}
				if(noRepliedNum>0){
					extracurricularExercises.setStatus(1);
				}else if(noRepliedNum<=0&&notSubmitNum>0){
					extracurricularExercises.setStatus(2);
				}else if(noRepliedNum<=0&&notSubmitNum<=0){
					extracurricularExercises.setStatus(3);
				}
			}

			Map<String, List<ExtracurricularExercises>> collect = dataList.stream().collect(Collectors.groupingBy(e -> DateUtil.dateToString(e.getCreateTime(), "yyyy-MM-dd")));
			List<Date> dates=new ArrayList<>();
			collect.keySet().forEach(ds-> dates.add(DateUtil.stringToDate(ds,"yyyy-MM-dd")));
			dates.sort(Comparator.comparing(Date::getTime));
			dates.sort(Comparator.reverseOrder());
			for (Date date : dates) {
				String key=DateUtil.dateToString(date, "yyyy-MM-dd");
				Map<String, Object> r = new HashMap<>();
				r.put("day", key);
				collect.get(key).sort(Comparator.comparing(ExtracurricularExercises::getCreateTime).reversed());
				r.put("list", collect.get(key));
				result.add(r);
			}
		}
		return result;
	}

	@Override
	public List<BasicUserDto> getDontServeStudents(Integer teacherId, String search) {
		LocalDate nowDate = LocalDateTime.now(DateUtil.zoneId).toLocalDate();
		LocalDate monDayDate = nowDate.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue());
		return extracurricularExercisesDao.findNoExercisesStudentsInThisWeekWithTeacher(teacherId, monDayDate.toString(), search);
	}

	@Override
	public void studentServeRemind() {
		LocalDate nowDate = LocalDateTime.now(DateUtil.zoneId).toLocalDate();
		LocalDate monDayDate = nowDate.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue());
		List<Map<Integer, Long>> noFinishedServiceTeacher = studentExtracurricularExercisesSituationDao.getNoFinishedServiceTeacher(monDayDate.toString());
		Map<Integer, Long> noFinishedServiceTeacherMap= MapUtil.convertIntegerMap(noFinishedServiceTeacher);
		for (Map.Entry<Integer, Long> integerLongEntry : noFinishedServiceTeacherMap.entrySet()) {
			Map<Integer, String> userMap = new HashMap<>();
			userMap.put(integerLongEntry.getKey(), integerLongEntry.getKey().toString());
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.PUBLIC_EXTRA_REMIND,
					userMap, null, 0, "11" , "TEACHER", integerLongEntry.getValue());
		}
	}
}
