package com.magistr.app.repository;

import com.magistr.app.model.AcademicCalendarDay;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

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

public interface AcademicCalendarDayRepository extends JpaRepository<AcademicCalendarDay, Long> {

    @Query("""
            select day
            from AcademicCalendarDay day
            join fetch day.activityType
            where day.academicCalendar.id = :calendarId
            order by day.courseNumber asc, day.date asc
            """)
    List<AcademicCalendarDay> findByCalendarIdWithActivity(@Param("calendarId") Long calendarId);

    @Query("""
            select day
            from AcademicCalendarDay day
            join fetch day.activityType
            where day.academicCalendar.id = :calendarId
              and day.courseNumber = :courseNumber
              and day.date = :date
            """)
    Optional<AcademicCalendarDay> findByCalendarIdAndCourseNumberAndDate(
            @Param("calendarId") Long calendarId,
            @Param("courseNumber") Integer courseNumber,
            @Param("date") LocalDate date
    );

    @Query("""
            select day
            from AcademicCalendarDay day
            join fetch day.academicCalendar
            join fetch day.activityType
            where day.academicCalendar.id in :calendarIds
              and day.date between :startDate and :endDate
            order by day.academicCalendar.id, day.courseNumber, day.date
            """)
    List<AcademicCalendarDay> findForScheduleBatch(
            @Param("calendarIds") Collection<Long> calendarIds,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );

    boolean existsByActivityTypeId(Long activityTypeId);

    boolean existsByAcademicCalendarIdAndCourseNumberGreaterThan(Long calendarId, Integer courseNumber);

    @Query("""
            select case when count(day) > 0 then true else false end
            from AcademicCalendarDay day
            where day.academicCalendar.id = :calendarId
              and (day.date < :startDate or day.date > :endDate)
            """)
    boolean existsOutsideDateRange(@Param("calendarId") Long calendarId,
                                   @Param("startDate") LocalDate startDate,
                                   @Param("endDate") LocalDate endDate);

    @Modifying
    @Query("delete from AcademicCalendarDay day where day.academicCalendar.id = :calendarId")
    void deleteByCalendarId(@Param("calendarId") Long calendarId);
}
