package com.xinelu.applet.utils;


import com.xinelu.applet.vo.specialdisease.WeekDaysVO;
import com.xinelu.common.enums.AppointmentTimeIntervalEnum;
import com.xinelu.common.exception.ServiceException;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

/**
 * @Description 提前预约时间近七天时间点动态生成工具类
 * @Author 纪寒
 * @Date 2023-02-15 09:31:50
 * @Version 1.0
 */
@Component
public class AppointmentTimeUtil {

    /**
     * 近一周的时间点循环标识
     */
    private static final int DAYS = 6;
    /**
     * 周一
     */
    private static final String MONDAY = "MONDAY";
    /**
     * 周二
     */
    private static final String TUESDAY = "TUESDAY";
    /**
     * 周三
     */
    private static final String WEDNESDAY = "WEDNESDAY";
    /**
     * 周四
     */
    private static final String THURSDAY = "THURSDAY";
    /**
     * 周五
     */
    private static final String FRIDAY = "FRIDAY";
    /**
     * 周六
     */
    private static final String SATURDAY = "SATURDAY";
    /**
     * 周天
     */
    private static final String SUNDAY = "SUNDAY";

    /**
     * 根据预约时间间隔个营业开始时间和解释时间动态生成近七天的日期间隔时间点
     *
     * @param timeInterval           预约时间间隔
     * @param morningOpenStartTime   上午营业开始时间
     * @param morningOpenEndTime     上午营业结束时间
     * @param afternoonOpenStartTime 下午营业开始时间
     * @param afternoonOpenEndTime   下午营业结束时间
     * @return List<WeekDaysVO> 近七天的营业时间点
     */
    public List<WeekDaysVO> getAppointmentTimeList(String timeInterval, LocalTime morningOpenStartTime,
                                                   LocalTime morningOpenEndTime, LocalTime afternoonOpenStartTime,
                                                   LocalTime afternoonOpenEndTime) {
        if (StringUtils.isEmpty(timeInterval)) {
            throw new ServiceException("预约时间间隔不能为空！");
        }
        if (Objects.isNull(morningOpenStartTime) || Objects.isNull(morningOpenEndTime)) {
            throw new ServiceException("上午营业开始时间和结束时间不能为空！");
        }
        if (Objects.isNull(afternoonOpenStartTime) || Objects.isNull(afternoonOpenEndTime)) {
            throw new ServiceException("下午营业开始时间和结束时间不能为空！");
        }
        LocalDate nowTime = LocalDate.now();
        //近七天的预约时间点数据集合
        List<WeekDaysVO> weekDaysList = Lists.newArrayList();
        this.setWeekDayAndWeekDate(nowTime, weekDaysList);
        //格式化营业时间
        morningOpenStartTime = formatTime(morningOpenStartTime);
        morningOpenEndTime = formatTime(morningOpenEndTime);
        afternoonOpenStartTime = formatTime(afternoonOpenStartTime);
        afternoonOpenEndTime = formatTime(afternoonOpenEndTime);
        //获取时间间隔分钟
        long interval = getInterval(StringUtils.trim(timeInterval));
        //上午时间点集合
        List<String> morningTimeList = Lists.newArrayList();
        //下午时间点集合
        List<String> afternoonTimeList = Lists.newArrayList();
        if (interval > 0) {
            //生成上午时间点
            LocalTime morningInitTime = morningOpenStartTime;
            morningTimeList.add(morningOpenStartTime.toString());
            while (morningInitTime.isBefore(morningOpenEndTime)) {
                LocalTime localTime = morningInitTime.plusMinutes(interval);
                if (localTime.isBefore(morningOpenEndTime)) {
                    morningTimeList.add(formatTime(localTime).toString());
                }
                morningInitTime = morningInitTime.plusMinutes(interval);
            }
            //生成下午时间点
            LocalTime afternoonInitTime = afternoonOpenStartTime;
            afternoonTimeList.add(afternoonOpenStartTime.toString());
            while (afternoonInitTime.isBefore(afternoonOpenEndTime)) {
                LocalTime localTime = afternoonInitTime.plusMinutes(interval);
                if (localTime.isBefore(afternoonOpenEndTime)) {
                    afternoonTimeList.add(formatTime(localTime).toString());
                }
                afternoonInitTime = afternoonInitTime.plusMinutes(interval);
            }
        }
        //组装数据
        for (WeekDaysVO weekDaysVO : weekDaysList) {
            weekDaysVO.setMorningList(morningTimeList);
            weekDaysVO.setAfternoonList(afternoonTimeList);
        }
        return weekDaysList;
    }

    /**
     * 生成近七天的时间和周几
     *
     * @param nowTime      当前时间
     * @param weekDaysList 日期集合
     */
    public void setWeekDayAndWeekDate(LocalDate nowTime, List<WeekDaysVO> weekDaysList) {
        for (int i = 0; i <= DAYS; i++) {
            //每天的日期值，例如：2023-02-15
            LocalDate weekDate = nowTime.plusDays(i);
            //日期对应的周几，例如：MONDAY
            String week = weekDate.getDayOfWeek().toString();
            //日期对应的周几，例如：周一
            String weekDay = getWeekDay(nowTime, weekDate, week);
            WeekDaysVO weekDaysVO = new WeekDaysVO();
            weekDaysVO.setDate(weekDate.toString());
            weekDaysVO.setWeek(weekDay);
            weekDaysVO.setHealthConsultationDate(weekDate);
            weekDaysList.add(weekDaysVO);
        }
    }

    /**
     * 获取近七天日期对应得周几的值
     *
     * @param nowTime  当前日期
     * @param weekDate 近七天中每天的日期值
     * @param week     近七天中每天日期对应的周几
     * @return String 周几
     */
    public String getWeekDay(LocalDate nowTime, LocalDate weekDate, String week) {
        String weekDay;
        switch (week) {
            case MONDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周一";
                break;
            case TUESDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周二";
                break;
            case WEDNESDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周三";
                break;
            case THURSDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周四";
                break;
            case FRIDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周五";
                break;
            case SATURDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周六";
                break;
            case SUNDAY:
                weekDay = weekDate.isEqual(nowTime) ? "今天" : "周天";
                break;
            default:
                weekDay = "";
                break;
        }
        return weekDay;
    }

    /**
     * 根据时间间隔获取对应得时间间隔分钟
     *
     * @param timeInterval 时间间隔
     * @return 时间间隔分钟
     */
    private long getInterval(String timeInterval) {
        long interval = 0;
        if (AppointmentTimeIntervalEnum.HALF_HOUR.getValue().equals(timeInterval)) {
            interval = 30;
        }
        if (AppointmentTimeIntervalEnum.ONE_HOUR.getValue().equals(timeInterval)) {
            interval = 60;
        }
        if (AppointmentTimeIntervalEnum.NINETY_MINUTES.getValue().equals(timeInterval)) {
            interval = 90;
        }
        if (AppointmentTimeIntervalEnum.TWO_HOUR.getValue().equals(timeInterval)) {
            interval = 120;
        }
        return interval;
    }

    /**
     * 格式化时间格式
     *
     * @param localTime 时间值
     */
    private LocalTime formatTime(LocalTime localTime) {
        return LocalTime.parse(DateTimeFormatter.ofPattern("HH:mm").format(localTime));
    }
}
