package com.leromro.core.facade;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.leromro.common.core.domain.R;
import com.leromro.core.domain.VolunteerReservationTime;
import com.leromro.core.domain.VolunteerWorkDate;
import com.leromro.core.domain.dto.AddReservationTimesDTO;
import com.leromro.core.domain.vo.VolunteerReservationTimeVO;
import com.leromro.core.service.IVolunteerReservationTimeService;
import com.leromro.core.service.IVolunteerWorkDateService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class VolunteerWorkDateFacade {

    private final IVolunteerWorkDateService workDateService;

    private final IVolunteerReservationTimeService reservationTimeService;


    /**
     * 根据日期获取志愿者工作时间
     * @param date
     * @return
     */
    public R<List<VolunteerReservationTimeVO>> getTimesByDate(Long volunteerId, LocalDate date) {
        //判断志愿者当前日期是否排班
        VolunteerWorkDate dateInfo = workDateService.getOne(new LambdaQueryWrapper<VolunteerWorkDate>()
                .eq(VolunteerWorkDate::getVolunteerId, volunteerId)
                .eq(VolunteerWorkDate::getWorkDate, date));
        if (ObjectUtil.isNull(dateInfo)){
            return R.fail("该志愿者当前日期未排班");
        }
        LocalTime startTime = roundToNearest30Minutes(dateInfo.getWorkStartTime());
        LocalTime endTime = dateInfo.getWorkEndTime();
        List<VolunteerReservationTimeVO> list = new ArrayList<>();
        //获取当前志愿者所有预约时间
        List<VolunteerReservationTime> reservationTimes = reservationTimeService.list(new LambdaQueryWrapper<VolunteerReservationTime>()
                .eq(VolunteerReservationTime::getVolunteerId, volunteerId)
                .eq(VolunteerReservationTime::getReservationDate, date));
        List<LocalTime> times = reservationTimes.stream().map(VolunteerReservationTime::getReservationTime).collect(Collectors.toList());
        Map<LocalTime, Long> timeMapUser = reservationTimes.stream().collect(Collectors.toMap(VolunteerReservationTime::getReservationTime, VolunteerReservationTime::getClientId));
        //按照开始时间到结束时间生成数组，间隔为30分钟，第一个时间为整点，第二个时间为整点加30分钟，第三个时间为整点加60分钟，以此类推
        while (startTime.isBefore(endTime)){
            VolunteerReservationTimeVO vo = VolunteerReservationTimeVO.builder()
                    .reservationTime(startTime)
                    .build();
            if (times.contains(startTime)){
                vo.setHasReservation(1);
                vo.setClientId(timeMapUser.get(startTime));
            }else {
                vo.setHasReservation(0);
            }
            list.add(vo);
            startTime = startTime.plusMinutes(30);
        }
        return R.ok(list);
    }

    /**
     * 新增预约志愿者时间
     */
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> addReservationTimes(AddReservationTimesDTO dto) {
        //todo 目前不做校验，后续做校验
        //修改当前志愿者的排班日期为已预约
        List<AddReservationTimesDTO.ReservationInfo> infos = dto.getInfos();
        workDateService.update(new LambdaUpdateWrapper<VolunteerWorkDate>()
                .eq(VolunteerWorkDate::getVolunteerId, dto.getVolunteerId())
                .in(VolunteerWorkDate::getWorkDate, infos.stream().map(AddReservationTimesDTO.ReservationInfo::getReservationDate).collect(Collectors.toList()))
                .set(VolunteerWorkDate::getHasReservation, 1));
        //组装预约时间
        List<VolunteerReservationTime> list = new ArrayList<>();
        for (AddReservationTimesDTO.ReservationInfo info : infos) {
            List<LocalTime> times = info.getReservationTimes();
            for (LocalTime time : times) {
                VolunteerReservationTime volunteerReservationTime = VolunteerReservationTime.builder()
                        .volunteerId(dto.getVolunteerId())
                        .clientId(dto.getClientId())
                        .reservationDate(info.getReservationDate())
                        .reservationTime(time)
                        .build();
                list.add(volunteerReservationTime);
            }
        }
        //批量保存预约时间
        reservationTimeService.saveBatch(list);
        return R.ok();
    }

    public static LocalTime roundToNearest30Minutes(LocalTime time) {
        // 获取当前时间的分钟数
        int minutes = time.getMinute();

        // 计算最接近的 30 分钟间隔
        int roundedMinutes = (minutes + 15) / 30 * 30;

        // 如果分钟数为 60，则需要进位到下一个整点
        if (roundedMinutes == 60) {
            return time.plusHours(1).withMinute(0).withSecond(0).withNano(0);
        }

        // 返回取整后的时间
        return time.withMinute(roundedMinutes).withSecond(0).withNano(0);
    }
}
