package com.magistr.app.repository;

import com.magistr.app.model.ScheduleOverride;
import jakarta.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

public interface ScheduleOverrideRepository extends JpaRepository<ScheduleOverride, Long> {

    @Query("""
            select o
            from ScheduleOverride o
            left join fetch o.baseRuleSlot baseSlot
            left join fetch o.newTimeSlot
            left join fetch o.newClassroom
            left join fetch o.newTeacher
            where o.lessonDate between :startDate and :endDate
            """)
    List<ScheduleOverride> findByLessonDateBetweenWithDetails(
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );

    Optional<ScheduleOverride> findByBaseRuleSlotIdAndLessonDate(Long baseRuleSlotId, LocalDate lessonDate);

    @Query("select o.lessonDate from ScheduleOverride o where o.id = :id")
    Optional<LocalDate> findLessonDateById(@Param("id") Long id);

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("select o from ScheduleOverride o where o.id = :id")
    Optional<ScheduleOverride> findByIdForUpdate(@Param("id") Long id);

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("""
            select o
            from ScheduleOverride o
            where o.baseRuleSlot.id = :baseRuleSlotId
              and o.lessonDate = :lessonDate
            """)
    Optional<ScheduleOverride> findByBaseRuleSlotIdAndLessonDateForUpdate(
            @Param("baseRuleSlotId") Long baseRuleSlotId,
            @Param("lessonDate") LocalDate lessonDate
    );
}
