package com.magistr.app.repository;

import com.magistr.app.model.AcademicCalendar;
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.util.List;
import java.util.Optional;

public interface AcademicCalendarRepository extends JpaRepository<AcademicCalendar, Long> {

    long countByStudyFormId(Long studyFormId);

    @Query("""
            select calendar
            from AcademicCalendar calendar
            join fetch calendar.academicYear
            join fetch calendar.speciality
            join fetch calendar.specialtyProfile
            join fetch calendar.studyForm
            where (:academicYearId is null or calendar.academicYear.id = :academicYearId)
              and (:specialtyId is null or calendar.speciality.id = :specialtyId)
              and (:profileId is null or calendar.specialtyProfile.id = :profileId)
            order by calendar.academicYear.startDate desc, calendar.title asc
            """)
    List<AcademicCalendar> findAllWithDetails(
            @Param("academicYearId") Long academicYearId,
            @Param("specialtyId") Long specialtyId,
            @Param("profileId") Long profileId
    );

    @Query("""
            select calendar
            from AcademicCalendar calendar
            join fetch calendar.academicYear
            join fetch calendar.speciality
            join fetch calendar.specialtyProfile
            join fetch calendar.studyForm
            where calendar.id = :id
            """)
    Optional<AcademicCalendar> findByIdWithDetails(@Param("id") Long id);

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("""
            select calendar
            from AcademicCalendar calendar
            join fetch calendar.academicYear
            join fetch calendar.speciality
            join fetch calendar.specialtyProfile
            join fetch calendar.studyForm
            where calendar.id = :id
            """)
    Optional<AcademicCalendar> findByIdWithDetailsForUpdate(@Param("id") Long id);
}
