package com.bytesw.bytebot.repository;

import com.bytesw.bytebot.model.CalendarException;
import com.bytesw.bytebot.model.enums.CalendarExceptionType;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

import java.math.BigInteger;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Optional;

public interface CalendarExceptionRepository extends CrudRepository<CalendarException, BigInteger>, JpaSpecificationExecutor<CalendarException> {

    @Query("select s from RangeCalendarException s where s.calendar.id = :calendarId and s.from < :date and s.to > :date and s.calendarExceptionType = :type")
    Optional<CalendarException> findByRangeExceptionByCalendarIdAndDateAndType(@Param("calendarId") String calendarId, @Param("date") OffsetDateTime date, @Param("type") CalendarExceptionType type);

    @Query("select s from AnnualCalendarException s where s.calendar.id = :calendarId and s.month = :month and s.dayOfMonth = :dayOfMonth")
    Optional<CalendarException> findByAnnualExceptionByCalendarIdAndYearAndDay(@Param("calendarId") String calendarId, @Param("month") int month, @Param("dayOfMonth") int dayOfMonth);

    @Query("select s from UniqueCalendarException s where s.calendar.id = :calendarId and s.date = :date")
    Optional<CalendarException> findByUniqueExceptionByCalendarIdAndDate(@Param("calendarId") String calendarId, @Param("date") LocalDate date);

    @Query("select s from UniqueWeeklyCalendarException s where s.calendar.id = :calendarId and s.month = :month and s.dayOfWeek = :dayOfWeek and s.weekOfMonth = :weekOfMonth")
    Optional<CalendarException> findByUniqueWeeklyExceptionByCalendarIdAndDayOfWeekAndWeekOfMonth(@Param("calendarId") String calendarId, @Param("month") int month, @Param("dayOfWeek") int dayOfWeek, @Param("weekOfMonth") int weekOfMonth);

    @Query("select s from RangeCalendarException s where s.calendar.id = :calendarId and s.from >= :date and s.calendarExceptionType = :type")
    Optional<CalendarException> findByRangeExceptionByCalendarIdFromDateAndType(@Param("calendarId") String calendarId, @Param("date") OffsetDateTime date, @Param("type") CalendarExceptionType type);

    @Query("select s from CalendarException s where s.calendar.id = :calendarId")
    Optional<List<CalendarException>> findByCalendarId(@Param("calendarId") String calendarId);

}
