package cn.novalon.gym.manage.groupcourse.repository;

import cn.novalon.gym.manage.groupcourse.domain.GroupCourseBooking;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 团课预约记录Repository接口
 * 
 * @author 张翔
 * @date 2026-06-01
 */
public interface IGroupCourseBookingRepository {

    /**
     * 根据ID查询预约记录
     */
    Mono<GroupCourseBooking> findById(Long id);

    /**
     * 根据会员ID查询预约记录列表
     */
    Flux<GroupCourseBooking> findByMemberId(Long memberId);

    /**
     * 根据团课ID查询预约记录列表
     */
    Flux<GroupCourseBooking> findByCourseId(Long courseId);

    /**
     * 查询会员是否已预约某课程
     */
    Mono<GroupCourseBooking> findByCourseIdAndMemberId(Long courseId, Long memberId);

    /**
     * 查询会员在指定课程的有效预约
     */
    Mono<GroupCourseBooking> findValidBooking(Long courseId, Long memberId);

    /**
     * 统计课程有效预约人数
     */
    Mono<Long> countValidBookings(Long courseId);

    /**
     * 保存预约记录
     */
    Mono<GroupCourseBooking> save(GroupCourseBooking booking);

    /**
     * 更新预约记录
     */
    Mono<GroupCourseBooking> update(GroupCourseBooking booking);

    /**
     * 更新预约状态
     */
    Mono<Integer> updateStatus(Long bookingId, String status);

    /**
     * 删除预约记录
     */
    Mono<Void> deleteById(Long bookingId);

    /**
     * 根据会员卡记录ID查询预约记录
     */
    Flux<GroupCourseBooking> findByMemberCardRecordId(Long memberCardRecordId);

    /**
     * 查询会员是否有时间冲突的预约
     * 
     * @param memberId 会员ID
     * @param newStartTime 新课程开始时间
     * @param newEndTime 新课程结束时间
     * @return 冲突的预约记录列表
     */
    Flux<GroupCourseBooking> findConflictingBookings(Long memberId, java.time.LocalDateTime newStartTime, java.time.LocalDateTime newEndTime);

    /**
     * 查询已开始课程但未到场会员的预约记录
     * @return 缺席会员的预约记录列表
     */
    Flux<GroupCourseBooking> findAbsentMembers();

    /**
     * 更新预约状态为缺席(3)
     * @param bookingId 预约ID
     * @return 更新记录数
     */
    Mono<Integer> updateToAbsent(Long bookingId);
}