package com.younike.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.younike.common.constant.Constants;
import com.younike.common.core.domain.AjaxResult;
import com.younike.common.utils.StringUtils;
import com.younike.common.utils.bean.BeanUtils;
import com.younike.hlpay.dto.OrderParam;
import com.younike.system.domain.*;
import com.younike.system.domain.vo.DateSectionVO;
import com.younike.system.domain.vo.ServerTimeSectionVo;
import com.younike.system.domain.vo.ServerTimeVo;
import com.younike.system.domain.vo.TimeSectionVO;
import com.younike.system.mapper.*;
import com.younike.system.service.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务人员服务时间Service业务层处理
 *
 * @author elev
 * @date 2022-01-10
 */
@Service
@Log4j2
public class ServerTimeServiceImpl implements IServerTimeService {
    public static final String WEEK_SPLIT = ",";
    @Autowired
    private ServerTimeMapper serverTimeMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ServerTimeSectionMapper serverTimeSectionMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private ServerTimeBookMapper serverTimeBookMapper;
    @Autowired
    private IMerchantServerTimeService merchantServerTimeService;
    @Autowired
    private IServerUserService serverUserService;
    @Autowired
    private IMerchantService merchantService;

    @Autowired
    private IPublishQuoteService publishQuoteService;

    /**
     * 查询服务人员服务时间
     *
     * @param serverId 服务人员服务时间主键
     * @return 服务人员服务时间
     */
    @Override
    public ServerTime selectServerTimeByServerId(Long serverId) {
        return serverTimeMapper.selectServerTimeByServerId(serverId);
    }

    /**
     * 查询服务人员服务时间列表
     *
     * @param serverTime 服务人员服务时间
     * @return 服务人员服务时间
     */
    @Override
    public List<ServerTime> selectServerTimeList(ServerTime serverTime) {
        return serverTimeMapper.selectServerTimeList(serverTime);
    }

    /**
     * 新增服务人员服务时间
     *
     * @param serverTime 服务人员服务时间
     * @return 结果
     */
    @Override
    public int insertServerTime(ServerTime serverTime) {
        serverTime.setCreateTime(LocalDateTime.now());
        int result = serverTimeMapper.insertServerTime(serverTime);
        merchantServerTimeService.generateBookTimes(Long.valueOf(serverTime.getServerId()), serverTime.getCurrentUser());
        return result;
    }

    /**
     * 修改服务人员服务时间
     *
     * @param serverTime 服务人员服务时间
     * @return 结果
     */
    @Override
    public int updateServerTime(ServerTime serverTime) {
        serverTime.setUpdateTime(LocalDateTime.now());
        int result = serverTimeMapper.updateServerTime(serverTime);
        merchantServerTimeService.generateBookTimes(Long.valueOf(serverTime.getServerId()), serverTime.getCurrentUser());
        return result;
    }

    /**
     * 批量删除服务人员服务时间
     *
     * @param serverIds 需要删除的服务人员服务时间主键
     * @return 结果
     */
    @Override
    public int deleteServerTimeByServerIds(Long[] serverIds) {
        return serverTimeMapper.deleteServerTimeByServerIds(serverIds);
    }

    /**
     * 删除服务人员服务时间信息
     *
     * @param serverId 服务人员服务时间主键
     * @return 结果
     */
    @Override
    public int deleteServerTimeByServerId(Long serverId) {
        return serverTimeMapper.deleteServerTimeByServerId(serverId);
    }

    /**
     * 根据服务人员id查询服务人员工作时间数据
     *
     * @param serverId
     * @return
     */
    @Override
    public ServerTimeVo getServerTime(Long serverId) {

        return serverTimeMapper.getServerTime(serverId);
    }

    /**
     * 根据服务人员id查询服务人员已经被预约的时间
     *
     * @param serverId
     * @return
     */
    @Override
    public List<Order> getServerOrderTime(Long serverId) {
        return serverTimeMapper.getServerOrderTime(serverId);
    }

    /**
     * 查询预约的时间服务人员是否下班
     *
     * @param param
     * @return
     */
    @Override
    public AjaxResult getServerWork(OrderParam param) {

        BigDecimal multiply = new BigDecimal(param.getGoodsCounts()).multiply(param.getSingleTime());
        //服务人员两个订单服务间隔时间
        ServerTime serverTime = serverTimeMapper.selectServerTimeByServerId(param.getServerId());
        if (ObjectUtils.isEmpty(serverTime)) {
            return AjaxResult.error("服务人员查无服务时间");
        }
        BigDecimal serverGrap = serverTime.getServerGrap();
        //计算出预约结束时间(预约结束时间加上服务人员休息时间间隔)
        param.setAppointmentEndTime(param.getAppointmentStartTime().plusHours(multiply.add(serverGrap).longValue()));

        //创建订单对象
        Order order = new Order();
        BeanUtils.copyProperties(param, order);
        // 校验订单时间是否以及被预约
        log.info("校验订单时间是否以及被预约 " + JSON.toJSONString(param));
        List<Order> orders = orderMapper.getOrderList(param);
        log.info("校验订单时间是否以及被预约,Result " + JSON.toJSONString(orders));
        if (orders.size() > 0) {
            return AjaxResult.success("预约失败，超出可预约时间范围", false);
        }
        //星期几
        //验证预约结束世界是否超出服务人员工作时间
        //结束时间不包含两订单之间间隔时间
        param.setAppointmentEndTime(param.getAppointmentStartTime().plusHours(multiply.longValue()));
        int week = param.getAppointmentEndTime().getDayOfWeek().getValue();
        if (week == 7) {
            week = 0;
        }
        //时间：时分秒
        LocalTime localTime = param.getAppointmentEndTime().toLocalTime();
        ServerTimeSection serverTimeSection = new ServerTimeSection();
        serverTimeSection.setServerId(String.valueOf(param.getServerId()));
        serverTimeSection.setWeeks(String.valueOf(week));
        //查询工作人员工作时间
        ServerTimeSection section = serverTimeSectionMapper.selectSectionWeek(serverTimeSection);

        if (ObjectUtils.isEmpty(section)) {
            return AjaxResult.success("预约失败,超出可预约时间范围", false);
        }
        if (localTime.isAfter(section.getHoursEnd())) {
            return AjaxResult.success("预约失败,超出可预约时间范围", false);
        }

        return AjaxResult.success("可预约", true);
    }

    @Override
    public ServerTimeVo getServerTimeInfo(ServerTime serverTime) {
        ServerTimeVo serverTimeInfo = serverTimeMapper.getServerTimeInfo(serverTime);
        if (ObjectUtils.isEmpty(serverTimeInfo)) {
            return null;
        }
//        serverTimeInfo.getSectionList().forEach(vo -> {
//            vo.setCheckAll(false);
//            vo.setIsIndeterminate(false);
//            vo.setWeekNames(this.conversion(vo.getWeeks()));
//        });
        // 查询服务人员时间子表
        ServerTimeSection queryParam = new ServerTimeSection();
        queryParam.setServerId(String.valueOf(serverTimeInfo.getServerId()));
        List<ServerTimeSection> serverTimeSectionList = serverTimeSectionMapper.selectServerTimeSectionList(queryParam);
        if (CollectionUtils.isNotEmpty(serverTimeSectionList)) {
            List<ServerTimeSectionVo> serverTimeSectionVoList = serverTimeSectionList.stream().map(serverTimeSection -> {
                ServerTimeSectionVo serverTimeSectionVo = new ServerTimeSectionVo();
                BeanUtils.copyProperties(serverTimeSection, serverTimeSectionVo);
                serverTimeSectionVo.setCheckAll(false);
                serverTimeSectionVo.setIsIndeterminate(false);
                serverTimeSectionVo.setWeekNames(this.conversion(serverTimeSectionVo.getWeeks()));
                return serverTimeSectionVo;
            }).collect(Collectors.toList());
            serverTimeInfo.setSectionList(serverTimeSectionVoList);
        }
        return serverTimeInfo;
    }

    @Override
    public ServerTimeVo getServerTimeInfoMerchant(ServerTime serverTime) {
        ServerTimeVo serverTimeInfo = serverTimeMapper.getServerTimeInfoMerchant(serverTime);
        if (ObjectUtils.isEmpty(serverTimeInfo)) {
            return null;
        }
        serverTimeInfo.getSectionList().forEach(vo -> {
            vo.setCheckAll(false);
            vo.setIsIndeterminate(false);
            vo.setWeekNames(this.conversion(vo.getWeeks()));
        });
        return serverTimeInfo;
    }

    /**
     * 查询服务人员是否停止接单
     *
     * @param serverId
     * @return
     */
    @Override
    public String getServerIsStopTakeOrder(Long serverId) {
        ServerTimeVo serverTimeVo = getServerTime(serverId);
        if (serverTimeVo == null || Objects.isNull(serverTimeVo.getStopOrder())) {
            return "1";
        }
        return String.valueOf(serverTimeVo.getStopOrder());
    }

    /**
     * 把 0,1,2,3,4,5,6 转成对应的 周日周一周二周三周四周五周六
     *
     * @param weeks
     * @return
     */
    private String conversion(String weeks) {
        StringBuffer weekNames = new StringBuffer();

        if (StringUtils.isNotNull(weeks)) {
            if ("0,1,2,3,4,5,6".equals(weeks)) {
                return "每天";
            }

            String[] weekArray = weeks.split(",");
            for (String week : weekArray) {
                switch (week) {
                    case "0":
                        weekNames.append("周日 ");
                        break;
                    case "1":
                        weekNames.append("周一 ");
                        break;
                    case "2":
                        weekNames.append("周二 ");
                        break;
                    case "3":
                        weekNames.append("周三 ");
                        break;
                    case "4":
                        weekNames.append("周四 ");
                        break;
                    case "5":
                        weekNames.append("周五 ");
                        break;
                    case "6":
                        weekNames.append("周六 ");
                        break;
                }
            }
        }
        return new String(weekNames);
    }

    /**
     * @param serverId    服务人员ID
     * @param goodsId     商品ID
     * @param goodsCounts 商品数量
     * @return 服务人员服务时间选择列表
     */
    @Override
    public List<DateSectionVO> getServerTimeSections(Long serverId, Long goodsId, Long goodsCounts) {
        log.info("【0】构建时间选择器 -- 参数: " + serverId + ", " + goodsId + "," + goodsCounts);
        List<DateSectionVO> result = new ArrayList<>();
//        Map<Integer, DateSectionVO> map = new HashMap<>();
//
//        // 查询服务商品信息
//        Goods goods = goodsMapper.selectGoodsByGoodsId(goodsId);
//        if (goods == null || goods.getIsSale() != 1 || goods.getSingleTime() == null) {
//            // 商品不存在，或已下架，或单次服务时长定义异常
//            log.error("【0】构建时间选择器 -- 商品不存在，或已下架，或单次服务时长定义异常");
//            return result;
//        }
//        // 单次服务标准时长（小时）
//        BigDecimal singleTime = goods.getSingleTime();
//        log.info("【0】构建时间选择器 -- 单次服务标准时长: " + singleTime);
//        // 预约服务总时长
//        BigDecimal totalTime = singleTime.multiply(BigDecimal.valueOf(goodsCounts));
//        log.info("【0】构建时间选择器 -- 本次预约服务总时长: " + totalTime);
//
//        // 明天是星期几（sun start, 1 -> 7）
//        int nextWeekNum = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
//        if (nextWeekNum == 7) {
//            // 今天是周六，明天是周天（0）
//            nextWeekNum = 0;
//        }
//
//        // 查询服务人员的时间安排
//        ServerTime serverTime = new ServerTime();
//        serverTime.setServerId(serverId);
//        // 服务人员可服务时间对象
//        ServerTimeVo serverTimeInfo = serverTimeMapper.getServerTimeInfo(serverTime);
//        if (serverTimeInfo == null || serverTimeInfo.getSectionList() == null || serverTimeInfo.getSectionList().size() == 0) {
//            // 未安排服务时间
//            log.error("【0】构建时间选择器 -- 未安排服务时间");
//            return null;
//        }
//        // 每次服务时间间隔(小时)
//        BigDecimal serverGrap = serverTimeInfo.getServerGrap();
//        log.info("【0】构建时间选择器 -- 每次服务时间间隔(小时): " + serverGrap);
//        log.info("【0】构建时间选择器 -- 服务人员可服务时间对象:\n" + JSON.toJSONString(serverTimeInfo));
//
//        // ------------ 【1】构建时间选择器（未区分是否可选） >>>>>>>>>>>>
//        serverTimeInfo.getSectionList().forEach(vo -> buildServerTimeMap(map, vo));
//        log.info("【1】构建时间选择器 -- 未区分是否可选:\n" + JSON.toJSONString(map));
//        // ------------ 【1】构建时间选择器（未区分是否可选） <<<<<<<<<<<<
//
//        // 查询服务人员未来预约订单(订单状态000， 001)
//        List<Order> orders = orderMapper.listOrderedOrderByServerId(serverId);
//        log.info("【1】构建时间选择器 -- 查询服务人员未来预约订单(订单状态000， 001):\n" + JSON.toJSONString(orders));
//        // 按「星期几」进行分组
//        Map<Integer, List<Order>> ordered = orders.stream().collect(Collectors.groupingBy(order -> {
//            int value = order.getAppointmentStartTime().getDayOfWeek().getValue();
//            if (value == 7) {
//                // 周日
//                return 0;
//            }else{
//                return value;
//            }
//        }));
//        log.info("【1】构建时间选择器 -- 服务人员=预约订单(已分组):\n" + JSON.toJSONString(ordered));
//
//        // 遍历生成未来七天的数据
//        LocalDate nextDate = LocalDate.now().plusDays(1L);
//        for (int i = 0; i < 7; i++) {
//            log.info("【1】构建时间选择器 -- 遍历因子i : " + i);
//            DateSectionVO dateSectionVO = map.get(nextWeekNum);
//            if (dateSectionVO == null || dateSectionVO.getTimeSectionList() == null || dateSectionVO.getTimeSectionList().size() == 0) {
//                // 没有服务排班
//                log.info("【1】构建时间选择器 -- 没有服务排班，nextWeekNum: " + nextWeekNum);
//                dateSectionVO = new DateSectionVO();
//                dateSectionVO.setWeek(nextWeekNum);
//            } else {
//                LocalTime hoursFrom = null;
//                if (i == 0) {
//                    // i = 0, 为明天的数据，明天只能约24小时后的数据
//                    log.info("【1】构建时间选择器 -- 明天的数据，明天只能约24小时后的数据");
//                    // 明天的时间段需要24小时后
//                    if (LocalTime.now().getMinute() < 30) {
//                        hoursFrom = LocalTime.now().withMinute(30).withSecond(0).withNano(0);
//                    } else{
//                        hoursFrom = LocalTime.now().plusHours(1).withMinute(0).withSecond(0).withNano(0);
//                    }
//                    List<TimeSectionVO> timeSectionList = dateSectionVO.getTimeSectionList();
//                    for (TimeSectionVO timeSectionVO : timeSectionList) {
//                        // 已过24小时的不让点击
//                        if (timeSectionVO.getStartTime().compareTo(hoursFrom) < 0) {
//                            timeSectionVO.setBooked(true);
//                        }
//                    }
//                }
//
//                List<TimeSectionVO> timeSectionList = dateSectionVO.getTimeSectionList();
//                // 检查当前时间段中是否有已约订单
//                for (TimeSectionVO timeSectionVO : timeSectionList) {
//                    timeSectionVO.setBooked(checkBook(timeSectionVO, ordered.get(nextWeekNum), serverGrap.multiply(BigDecimal.valueOf(60)).longValue()));
//                }
//
//                // 检查预约时间是否超过可约时间区间
//                checkRange(timeSectionList, totalTime, serverGrap.multiply(BigDecimal.valueOf(60)).longValue());
//            }
//            dateSectionVO.setDate(nextDate.toString());
//            log.info("【1】构建时间选择器 -- 时间: " + nextDate.toString());
//            nextDate = nextDate.plusDays(1L);
//            result.add(dateSectionVO);
//            nextWeekNum= nextWeekNum + 1;
//            if (nextWeekNum > 6) {
//                nextWeekNum = 0;
//            }
//        }
        return result;
    }

    @Override
    public List<DateSectionVO> getServerTimePublish(Long serverId, Long quoteId) {
        log.info("【0】构建时间选择器 -- 参数: " + serverId + ", " + quoteId);
        // 查询服务商品信息
        PublishQuote publishQuote = publishQuoteService.selectPublishQuoteByQuoteId(quoteId);
        BigDecimal totalTime = publishQuote.getTotalTime();
        int totalCounts = totalTime.multiply(BigDecimal.valueOf(2)).intValue();
        log.info("【1】参数---totalTime--> " + totalTime + "--totalCounts--> " + totalCounts);
        return getServerTimeSection(serverId, totalCounts);
    }

    private void checkRange(List<TimeSectionVO> timeSectionList, BigDecimal totalTime, long longValue) {
        for (int i = 0; i < timeSectionList.size(); i++) {
            TimeSectionVO startTimeSection = timeSectionList.get(i);
            if (startTimeSection.isBooked()) {
                continue;
            }
            // 开始时间
            LocalTime startTime = startTimeSection.getStartTime();
            // 预约多少个半小时
            int halfCounts = totalTime.divide(BigDecimal.valueOf(0.5)).intValue();
            for (int j = 0; j < halfCounts; j++) {
                startTime = startTime.plusMinutes(j * 30);
                TimeSectionVO tv = null;
                for (TimeSectionVO timeSectionVO : timeSectionList) {
                    if (timeSectionVO.getStartTime().equals(startTime)) {
                        tv = timeSectionVO;
                    }
                }
                if (tv == null) {
                    // 预约时间段包含不服务时间段
                    startTimeSection.setBooked(true);
                    continue;
                }
                if (tv.isBooked()) {
                    // 预约时间段包含已预约时间段
                    startTimeSection.setBooked(true);
                    continue;
                }

//                if (j == halfCounts -1) {
//                    if ()
//                    // 最后一个时间段，要考虑服务时间间隔
//                    long grap = Long.valueOf(longValue / 30).intValue();
//
//                }
            }
        }
    }

    /**
     * @param timeSectionVO
     * @param orders
     * @param grapTimes     服务时间间隔（分）
     * @return
     */
    private boolean checkBook(TimeSectionVO timeSectionVO, List<Order> orders, Long grapTimes) {
        if (orders == null || orders.size() == 0) {
            // 无已预约的
            return timeSectionVO.isBooked();
        }
        for (Order order : orders) {
            // 开始时间
            LocalTime orderedStartTime = order.getAppointmentStartTime().toLocalTime();
            // 结束时间（添加服务间隔）
            LocalTime orderedEndTime = order.getAppointmentEndTime().plusMinutes(grapTimes).toLocalTime();

            // 1、已预约开始时间 = 当前时间段开始时间 || 已预约结束时间 = 当前时间段结束时间
            if (timeSectionVO.getStartTime().equals(orderedStartTime) || timeSectionVO.getEndTime().equals(orderedEndTime)) {
                return true;
            }
            // 2、已预约开始时间 < 当前时间段开始时间 && 已预约结束时间 > 当前时间段结束时间
            if (orderedStartTime.compareTo(timeSectionVO.getStartTime()) < 0 && orderedEndTime.compareTo(timeSectionVO.getEndTime()) > 0) {
                return true;
            }
        }
        return timeSectionVO.isBooked();
    }

    /**
     * @param serverId 服务人员ID
     * @return 服务人员服务时间选择列表
     */
    @Override
    public List<DateSectionVO> getServerTimeSections(Long serverId) {
        List<DateSectionVO> result = new ArrayList<>();
//        Map<Integer, DateSectionVO> map = new HashMap<>();
//
//        // 星期几（sun start, 1 -> 7）
//        int nextWeekNum = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
//        if (nextWeekNum == 7) {
//            // 今天是周六，明天是周天（0）
//            nextWeekNum = 0;
//        }
//
//        // 查询服务人员的时间安排
//        ServerTime serverTime = new ServerTime();
//        serverTime.setServerId(serverId);
//        ServerTimeVo serverTimeInfo = serverTimeMapper.getServerTimeInfo(serverTime);
//        serverTime = serverTimeMapper.selectServerTimeByServerId(serverId);
//        if (serverTimeInfo == null || serverTimeInfo.getSectionList() == null || serverTimeInfo.getSectionList().size() == 0) {
//            // 未安排服务时间
//            return null;
//        }
//
//        // 星期拆分(weeks)
//        int finalNextWeekNum = nextWeekNum;
//        serverTimeInfo.getSectionList().forEach(vo -> {
//            String weeks = vo.getWeeks();
//            LocalTime hoursFrom = vo.getHoursFrom();
//            LocalTime hoursEnd = vo.getHoursEnd();
//            if (weeks.contains(WEEK_SPLIT)) {
//                // 存在多个工作日相同时间安排
//                for (String weekStr : weeks.split(WEEK_SPLIT)) {
//                    DateSectionVO dateSectionVO = new DateSectionVO();
//                    dateSectionVO.setWeek(Integer.parseInt(weekStr));
//                    if (finalNextWeekNum == dateSectionVO.getWeek()) {
//                        // 明天的时间段需要24小时后
//                        if (LocalTime.now().getMinute() < 30) {
//                            hoursFrom = LocalTime.now().withMinute(30).withSecond(0).withNano(0);
//                        } else{
//                            hoursFrom = LocalTime.now().plusHours(1).withMinute(0).withSecond(0).withNano(0);
//                        }
//                    } else{
//                        hoursFrom  = vo.getHoursFrom();
//                    }
//                    List<TimeSectionVO> timeSectionList = buildTimeSectionVOList(hoursFrom, hoursEnd);
//                    dateSectionVO.setTimeSectionList(timeSectionList);
//                    map.put(dateSectionVO.getWeek(), dateSectionVO);
//                }
//            } else {
//                // weeks为单个工作日，直接添加
//                DateSectionVO dateSectionVO = new DateSectionVO();
//                dateSectionVO.setWeek(Integer.parseInt(weeks));
//                if (finalNextWeekNum == dateSectionVO.getWeek()) {
//                    // 明天的时间段需要24小时后
//                    if (LocalTime.now().getMinute() < 30) {
//                        hoursFrom = LocalTime.now().withMinute(30).withSecond(0).withNano(0);
//                    } else{
//                        hoursFrom = LocalTime.now().plusHours(1).withMinute(0).withSecond(0).withNano(0);
//                    }
//                } else{
//                    hoursFrom  = vo.getHoursFrom();
//                }
//                List<TimeSectionVO> timeSectionList = buildTimeSectionVOList(hoursFrom, hoursEnd);
//                dateSectionVO.setTimeSectionList(timeSectionList);
//                map.put(dateSectionVO.getWeek(), dateSectionVO);
//            }
//        });
//
//        // 查询服务人员未来预约订单
//        List<Order> orders = orderMapper.listOrderedOrderByServerId(serverId);
//        Map<Integer, List<Order>> ordered = orders.stream().collect(Collectors.groupingBy(order -> {
//            int value = order.getAppointmentStartTime().getDayOfWeek().getValue();
//            if (value == 7) {
//                // 周日
//                return 0;
//            }else{
//                return value;
//            }
//        }));
//
//        // 遍历生成未来七天的数据
//        LocalDate nextDate = LocalDate.now().plusDays(1L);
//        for (int i = 0; i < 7; i++) {
//            DateSectionVO dateSectionVO = map.get(nextWeekNum);
//            if (dateSectionVO == null) {
//                // 没有服务排班
//                dateSectionVO = new DateSectionVO();
//                dateSectionVO.setWeek(nextWeekNum);
//            } else {
//                // 查询是否已经有服务计划
//                List<Order> orderedList = ordered.get(nextWeekNum);
//                if (orderedList != null && orderedList.size() > 0) {
//                    DateSectionVO finalDateSectionVO = dateSectionVO;
//                    ServerTime finalServerTime = serverTime;
//                    orderedList.forEach(order -> {
//                        LocalTime startTime = order.getAppointmentStartTime().toLocalTime();
//                        // 结束时间添加服务间隔
//                        LocalTime endTime = order.getAppointmentEndTime().plusMinutes(finalServerTime.getServerGrap().multiply(BigDecimal.valueOf(60)).longValue()).toLocalTime();
//
//                        List<TimeSectionVO> timeSectionList = finalDateSectionVO.getTimeSectionList();
//                        boolean booked = false;
//                        for (TimeSectionVO timeSectionVO : timeSectionList) {
//                            if (timeSectionVO.getStartTime().equals(startTime)) {
//                                booked = true;
//                            }
//                            if (!timeSectionVO.isBooked()) {
//                                timeSectionVO.setBooked(booked);
//                            }
//                            if (timeSectionVO.getEndTime().equals(endTime)) {
//                                booked = false;
//                            }
//                        }
//                    });
//                }
//            }
//            dateSectionVO.setDate(nextDate.toString());
//            log.info(nextDate.toString());
//            nextDate = nextDate.plusDays(1L);
//            result.add(dateSectionVO);
//            nextWeekNum= nextWeekNum + 1;
//            if (nextWeekNum > 6) {
//                nextWeekNum = 0;
//            }
//        }
        return result;
    }

//    private void buildServerTimeMap(Map<Integer, DateSectionVO> map, ServerTimeSectionVo vo){
//        DateSectionVO dateSectionVO = new DateSectionVO();
//        List<TimeSectionVO> timeSectionList = buildTimeSectionVOList(vo.getHoursFrom(), vo.getHoursEnd());
//        String weeks = vo.getWeeks();
//        if (weeks.contains(WEEK_SPLIT)) {
//            // 存在多个工作日相同时间安排
//            for (String weekStr : weeks.split(WEEK_SPLIT)) {
//                dateSectionVO = new DateSectionVO();
//                int week = Integer.parseInt(weekStr);
//                dateSectionVO.setWeek(week);
//                buildDateSectionVO(map, dateSectionVO, timeSectionList);
//            }
//        } else {
//            dateSectionVO.setWeek(Integer.parseInt(weeks));
//            buildDateSectionVO(map, dateSectionVO, timeSectionList);
//        }
//    }
//
//    private void buildDateSectionVO(Map<Integer, DateSectionVO> map,DateSectionVO dateSectionVO, List<TimeSectionVO> timeSectionList){
//        if (map.containsKey(dateSectionVO.getWeek())) {
//            // 已存在（一天存在多个时间段），合并
//            timeSectionList.addAll(map.get(dateSectionVO.getWeek()).getTimeSectionList());
//            // 排序
//            timeSectionList.sort(Comparator.comparing(TimeSectionVO::getStartTime));
//            dateSectionVO.setTimeSectionList(timeSectionList);
//        }
//        dateSectionVO.setTimeSectionList(timeSectionList);
//        map.put(dateSectionVO.getWeek(), dateSectionVO);
//    }

//    /**
//     * @param hoursFrom 开始时间
//     * @param hoursEnd  结束时间
//     * @return 服务时间集合
//     */
//    private List<TimeSectionVO> buildTimeSectionVOList(LocalTime hoursFrom, LocalTime hoursEnd) {
//        List<TimeSectionVO> list = new ArrayList<>();
//        Duration duration = java.time.Duration.between(hoursFrom, hoursEnd);
//        long minutes = duration.toMinutes();
//        LocalTime startTime = hoursFrom;
//        for (long i = 0; i < (minutes / 30); i++) {
//            TimeSectionVO vo = new TimeSectionVO();
//            vo.setStartTime(startTime);
//            startTime = startTime.plusMinutes(30);
//            vo.setEndTime(startTime);
//            list.add(vo);
//        }
//        return list;
//    }

    /**
     * @param serverId    服务人员ID
     * @param goodsId     商品ID
     * @param goodsCounts 商品数量
     * @return 服务人员服务时间选择列表
     */
    @Override
    public List<DateSectionVO> getServerTimeSection(Long serverId, Long goodsId, Long goodsCounts) {
        log.info("【0】构建时间选择器 -- 参数: " + serverId + ", " + goodsId + ", " + goodsCounts);
        List<DateSectionVO> result = new ArrayList<>();

        // 查询服务商品信息
        Goods goods = goodsMapper.selectGoodsByGoodsId(goodsId);
//        if (goods == null || goods.getIsSale() != 1 || goods.getSingleTime() == null) {
        if (goods == null || goods.getIsSale() == 0 || goods.getSingleTime() == null) {
            // 商品不存在，或已下架，或单次服务时长定义异常
            log.error("【0】构建时间选择器 -- 商品不存在，或已下架，或单次服务时长定义异常");
            return result;
        }
        // 单次服务标准时长（小时）
        BigDecimal singleTime = goods.getSingleTime();
        log.info("【0】构建时间选择器 -- 单次服务标准时长: " + singleTime);
        // 预约服务总时长
        BigDecimal totalTime = singleTime.multiply(BigDecimal.valueOf(goodsCounts));
        // 预约连续时间段数量
        int totalCounts = totalTime.multiply(BigDecimal.valueOf(2)).intValue();
        log.info("【0】构建时间选择器 -- 本次预约服务总时长: " + totalTime);
        log.info("【0】构建时间选择器 -- 预约连续时间段数量: " + totalCounts);

        return getServerTimeSection(serverId, totalCounts);
    }

    /**
     * @param serverId 服务人员ID
     * @param totalCounts 服务预约总时间段数（半小时为一段）
     * @return 可预约服务时间集合
     */
    public List<DateSectionVO> getServerTimeSection(Long serverId, int totalCounts) {
        List<DateSectionVO> result = new ArrayList<>();
        // 查询服务人员的时间安排
        ServerTime serverTime = new ServerTime();
        serverTime.setServerId(serverId);
        // 服务人员可服务时间对象
        ServerTimeVo serverTimeInfo = serverTimeMapper.getServerTimeInfo(serverTime);
        if (serverTimeInfo == null || serverTimeInfo.getSectionList() == null || serverTimeInfo.getSectionList().size() == 0) {
            // 未安排服务时间
            log.error("【0】构建时间选择器 -- 未安排服务时间");
            return result;
        }
        // 每次服务时间间隔(小时)
        BigDecimal serverGap = serverTimeInfo.getServerGrap();
        serverGap = serverGap == null ? BigDecimal.valueOf(0) : serverGap;
        log.info("【0】构建时间选择器 -- 每次服务时间间隔(小时): " + serverGap);
        int totalCountsIncludeGap = totalCounts + serverGap.intValue() * 2;
        log.info("【0】构建时间选择器 -- 预约连续时间段数量（包含gapTime）: " + totalCountsIncludeGap);
        log.info("【0】构建时间选择器 -- 服务人员可服务时间对象:\n" + JSON.toJSONString(serverTimeInfo));
        // 明天是星期几（sun start, 1 -> 7）
        int nextWeekNum = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
        if (nextWeekNum == 7) {
            // 今天是周六，明天是周天（0）
            nextWeekNum = 0;
        }
        // 服务人员预约情况
        List<ServerTimeBook> serverTimeBooks = serverTimeBookMapper.selectServerTimeBookByServerId(serverId);
        if (serverTimeBooks.size() == 0) {
            log.error("【0】构建时间选择器 -- 服务人员预约表未空");
            return result;
        }
        // 服务人员预约信息Map
        Map<Integer, List<ServerTimeBook>> serverTimeBookMap = serverTimeBooks.stream().collect(Collectors.groupingBy(ServerTimeBook::getWeek));
        log.info("【0】构建时间选择器 -- 服务人员已预约信息Map：" + JSON.toJSONString(serverTimeBookMap));

        // 获取商家配置的是否可组合服务时间
        ServerUser serverUser = serverUserService.selectServerUserByServerId(serverId);
        Merchant merchant = merchantService.selectMerchantByMerchantId(serverUser.getMerchantId());
        Boolean allowCompose = merchant.getAllowCompose() == 1;

        // 可预约时间遍历处理
        for (Map.Entry<Integer, List<ServerTimeBook>> entry : serverTimeBookMap.entrySet()) {
            List<ServerTimeBook> allList = entry.getValue();
            Integer week = entry.getKey();
            int allListSize = allList.size();
            // 当天所有可用时间都不满足条件
            if (allListSize < totalCounts) {
                log.info("【0】构建时间选择器 -- 星期" + week + "能提供总服务时间段数（" + allListSize + "）不满足预约连续时间段数量（" + totalCounts + "）");
                // 所有时间段均不可选择
//                allList.forEach(serverTimeBook -> serverTimeBook.setBooked(1));
                allList.forEach(serverTimeBook -> serverTimeBook.setBooked(serverTimeBook.getBooked() == 0 ? 2 : serverTimeBook.getBooked()));
                continue;
            }

            // 遍历当天所有时间段
            for (int i = 0; i < allListSize; i++) {
                ServerTimeBook book = allList.get(i);
                if (book.getBooked() == 1 || book.getBooked() == 2) {
                    // 本身已预约 或 不可约，continue
                    continue;
                }

                if (allListSize - i < totalCounts) {
                    // 可预约时间段不足，则不可预约，且后面的均不可预约，break
                    for (int j = i; j < allListSize; j++) {
//                        allList.get(j).setBooked(1);
                        allList.get(j).setBooked(allList.get(j).getBooked() == 0 ? 2 : allList.get(j).getBooked());
                    }
                    break;
                }

                // 连续可预约时间段
                int count = 0;
                int j;
                // 是否是因为预约终止
                boolean isBooked = false;
                for (j = i; j < allListSize; j++) {
                    isBooked = allList.get(j).getBooked() == 1;
                    if (isBooked){
                        break;
                    }
                    boolean continuous = j == i || allList.get(j-1).getEndTime().equals(allList.get(j).getStartTime());
                    // 不允许组合服务时间时开始和结束时间必须连续
                    if (!allowCompose && !continuous) {
                        break;
                    }
                    count = count + 1;
                }

                if (j == allListSize && count < totalCounts) {
                    // 一直遍历到最后了，都凑不够需要的时间段
                    for (j = i; j < allListSize; j++) {
//                        allList.get(j).setBooked(1);
                        allList.get(j).setBooked(allList.get(j).getBooked() == 0 ? 2 : allList.get(j).getBooked());
                    }
                }

                if (j < allListSize && count < (isBooked ? totalCountsIncludeGap : totalCounts)) {
                    // 遍历到最近的booked时间段，但凑不够需要的时间段
                    int end = j;
                    for (j = i; j < end; j++) {
//                        allList.get(j).setBooked(1);
                        allList.get(j).setBooked(allList.get(j).getBooked() == 0 ? 2 : allList.get(j).getBooked());
                    }
                }
            }
        }
        log.info("【1】构建时间选择器 -- 时间段booked标记结束");
        log.info("【1】构建时间选择器 -- 时间段booked标记结果" + JSON.toJSONString(serverTimeBookMap));

        // 遍历生成未来七天的数据
        LocalDate nextDate = LocalDate.now().plusDays(1L);
        for (int i = 0; i < 7; i++) {
            List<ServerTimeBook> timeBooks = serverTimeBookMap.get(nextWeekNum);
            DateSectionVO dateSectionVO = new DateSectionVO();
            dateSectionVO.setWeek(nextWeekNum);
            dateSectionVO.setDate(nextDate.toString());
            log.info("【1】构建时间选择器 -- 时间: " + nextDate);
            nextDate = nextDate.plusDays(1L);
            dateSectionVO.setTimeSectionList(timeBooks);
            result.add(dateSectionVO);
            nextWeekNum = nextWeekNum + 1;
            if (nextWeekNum > 6) {
                nextWeekNum = 0;
            }
        }
        return result;
    }

}
