package com.xinelu.manage.service.scheduleplan.impl;

import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.schedule.Schedule;
import com.xinelu.manage.domain.scheduleplan.SchedulePlan;
import com.xinelu.manage.domain.scheduleplandetail.SchedulePlanDetail;
import com.xinelu.manage.mapper.schedule.ScheduleMapper;
import com.xinelu.manage.mapper.scheduleplan.SchedulePlanMapper;
import com.xinelu.manage.mapper.scheduleplandetail.SchedulePlanDetailMapper;
import com.xinelu.manage.service.scheduleplan.ISchedulePlanService;
import com.xinelu.manage.vo.scheduleplan.SchedulePlanVO;
import com.xinelu.manage.vo.scheduleplandetail.SchedulePlanDetailVO;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* @author haown
* @description 针对表【schedule_plan(医生排班计划表)】的数据库操作Service实现
* @createDate 2023-09-21 17:16:40
*/
@Service
public class SchedulePlanServiceImpl implements ISchedulePlanService {

	@Resource
	private SchedulePlanMapper schedulePlanMapper;

	@Resource
	private ScheduleMapper scheduleMapper;

	@Resource
	private SchedulePlanDetailMapper planDetailMapper;

	@Override public List<SchedulePlan> getList(SchedulePlan schedulePlan) {
		return schedulePlanMapper.getList(schedulePlan);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int save(SchedulePlan schedulePlan) throws Exception {
		if (schedulePlan.getScheduleStartDate().isBefore(LocalDate.now())) {
			throw new Exception("排班开始时间应在当前日期之后！");
		}
		// 保存排班计划
		schedulePlan.setDelFlag("0");
		if (StringUtils.isBlank(schedulePlan.getStatus())) {
			schedulePlan.setStatus("0");
		}
		int flag = schedulePlanMapper.insert(schedulePlan);

		Schedule schedule = scheduleMapper.selectByPrimaryKey(schedulePlan.getScheduleId());
		if (flag > 0) {
			// 计算排班天数
			long days = ChronoUnit.DAYS.between(schedulePlan.getScheduleStartDate(), schedulePlan.getScheduleEndDate());
			if (days < 0) {
				throw new Exception("排班结束时间应在排班开始时间之后！");
			}
			for (int i = 0; i <= days; i++) {
				int patientsPerDay = 0;
				// 排班计划明细
				List<SchedulePlanDetail> detailList = new ArrayList<>();
				SchedulePlanDetail schedulePlanDetail = new SchedulePlanDetail();
				schedulePlanDetail.setSchedulePlanId(schedulePlan.getId());
				schedulePlanDetail.setScheduleDate(schedulePlan.getScheduleStartDate().plusDays(i));
				schedulePlanDetail.setDoctorId(schedulePlan.getDoctorId());
				schedulePlanDetail.setDoctorName(schedulePlan.getDoctorName());
				schedulePlanDetail.setStatus("0");
				// 生成上午计划
				if (schedule.getForenoonStartTime() != null && schedule.getForenoonEndTime() != null) {
					schedulePlanDetail.setType("1");
					// 根据时间间隔计算时间段
					long forenoonMinutes = ChronoUnit.MINUTES.between(schedule.getForenoonStartTime(), schedule.getForenoonEndTime());
					if (forenoonMinutes % schedulePlan.getMinutesPerPatient() == 0) {
						int number = (int) (forenoonMinutes / schedulePlan.getMinutesPerPatient());
						patientsPerDay += forenoonMinutes / schedulePlan.getMinutesPerPatient();
						detailList.addAll(genPlanDetail(schedulePlanDetail, number, schedule.getForenoonStartTime(), schedulePlan.getMinutesPerPatient()));
					} else {
						throw new Exception("上午上班时间不是每人可预约分钟数的倍数。");
					}
				}
				// 生成下午计划
				if (schedule.getAfternoonStartTime() != null && schedule.getAfternoonEndTime() != null) {
					// 根据时间间隔计算时间段
					schedulePlanDetail.setType("2");
					long afternoonMinutes = ChronoUnit.MINUTES.between(schedule.getAfternoonStartTime(), schedule.getAfternoonEndTime());
					if (afternoonMinutes % schedulePlan.getMinutesPerPatient() == 0) {
						int number = (int) (afternoonMinutes / schedulePlan.getMinutesPerPatient());
						patientsPerDay += afternoonMinutes / schedulePlan.getMinutesPerPatient();
						detailList.addAll(genPlanDetail(schedulePlanDetail, number, schedule.getAfternoonStartTime(), schedulePlan.getMinutesPerPatient()));
					} else {
						throw new Exception("上午上班时间不是每人可预约分钟数的倍数。");
					}
				}

				// 保存计划明细
				planDetailMapper.batchInsert(detailList);
				schedulePlan.setPatientsPerDay(patientsPerDay);
				schedulePlanMapper.updateByPrimaryKey(schedulePlan);
			}
		}
		return flag;
	}

	@Override public List<SchedulePlanVO> getListByDoctor(SchedulePlan schedulePlan) {
		List<SchedulePlanVO> retList = new ArrayList<>();
		LocalDate localDate = LocalDate.now();
		for (int i = 0; i < 6; i++) {
			// 查询排班明细表
			SchedulePlanDetail query = new SchedulePlanDetail();
			query.setDoctorId(schedulePlan.getDoctorId());
			query.setScheduleDate(localDate.plusDays(i));
			query.setAfter(1);
			List<SchedulePlanDetail> detailList = planDetailMapper.getList(query);
			List<SchedulePlanDetailVO> morningList = new ArrayList<>();
			List<SchedulePlanDetailVO> afternoonList = new ArrayList<>();
			if (CollectionUtils.isNotEmpty(detailList)) {
				detailList.forEach(detail -> {
					DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
					if (StringUtils.equals("1", detail.getType())) {
						morningList.add(SchedulePlanDetailVO.builder().scheduleTimeSlot(detail.getScheduleStartTime().format(formatter) + "~" + detail.getScheduleEndTime().format(formatter))
							.status(StringUtils.equals("0", detail.getStatus()) && StringUtils.equals("0",detail.getApplyState())).build());
					}
					if (StringUtils.equals("2", detail.getType())) {
						afternoonList.add(SchedulePlanDetailVO.builder().scheduleTimeSlot(detail.getScheduleStartTime().format(formatter) + "~" + detail.getScheduleEndTime().format(formatter))
							.status(StringUtils.equals("0", detail.getStatus()) && StringUtils.equals("0",detail.getApplyState())).build());
					}
				});
			}
			SchedulePlanVO schedulePlanVO = SchedulePlanVO.builder()
				.scheduleDate(localDate.plusDays(i))
				.morningList(morningList)
				.afternoonList(afternoonList).build();

			retList.add(schedulePlanVO);
		}
		return retList;
	}

	@Override public int updateDetailByOrder(String orderNo) {

		return 0;
	}

	/**
	 * 生成计划明细
	 * @param number：人数
	 * @param startTime：开始时间
	 * @return
	 */
	private List<SchedulePlanDetail> genPlanDetail(SchedulePlanDetail schedulePlanDetail, int number, LocalTime startTime, int minutesPerPatient) {
		List<SchedulePlanDetail> planDetails = new ArrayList<>();
		for (int i = 0; i < number; i++) {
			SchedulePlanDetail planDetail = new SchedulePlanDetail();
			BeanUtils.copyBeanProp(planDetail, schedulePlanDetail);
			planDetail.setScheduleStartTime(startTime.plusMinutes((long) minutesPerPatient * i));
			planDetail.setScheduleEndTime(startTime.plusMinutes((long) minutesPerPatient * (i + 1)));
			planDetail.setApplyState("0");
			planDetails.add(planDetail);
		}
		return planDetails;
	}
}




