package com.petshop.backend.repository;

import com.petshop.backend.entity.Appointment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

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

@Repository
public interface AppointmentRepository extends JpaRepository<Appointment, Long> {

    @Query("SELECT a FROM Appointment a WHERE a.appointmentDate = :date AND a.appointmentTime = :time")
    List<Appointment> findByDateAndTime(@Param("date") LocalDate date, @Param("time") LocalTime time);

    @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.store.storeId = :storeId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')")
    List<Appointment> findByStoreAndDate(@Param("storeId") Long storeId, @Param("date") LocalDate date);

    @Query("SELECT a FROM Appointment a LEFT JOIN a.pet p WHERE " +
           "(:q IS NULL OR (" +
           "LOWER(a.customer.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
           "LOWER(a.customer.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
           "LOWER(a.service.serviceName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
           "LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%'))" +
           ")) AND " +
           "(:customerId IS NULL OR a.customer.id = :customerId) AND " +
           "(:employeeId IS NULL OR a.employee.id = :employeeId) AND " +
           "(:storeId IS NULL OR a.store.storeId = :storeId) AND " +
           "(:status IS NULL OR LOWER(a.appointmentStatus) = LOWER(:status)) AND " +
           "(:date IS NULL OR a.appointmentDate = :date)")
    Page<Appointment> searchAppointments(
            @Param("q") String query,
            @Param("customerId") Long customerId,
            @Param("employeeId") Long employeeId,
            @Param("storeId") Long storeId,
            @Param("status") String status,
            @Param("date") LocalDate date,
            Pageable pageable);

    @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.employee.id = :employeeId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')")
    List<Appointment> findByEmployeeIdAndAppointmentDate(@Param("employeeId") Long employeeId, @Param("date") LocalDate date);

    @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.employee.id IN :employeeIds AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')")
    List<Appointment> findByEmployeeIdInAndAppointmentDate(@Param("employeeIds") List<Long> employeeIds, @Param("date") LocalDate date);

    @Query("SELECT a FROM Appointment a WHERE (a.appointmentDate < :currentDate OR (a.appointmentDate = :currentDate AND a.appointmentTime < :currentTime)) AND LOWER(a.appointmentStatus) = 'booked'")
    List<Appointment> findPastBookedAppointments(@Param("currentDate") LocalDate currentDate, @Param("currentTime") LocalTime currentTime);

    List<Appointment> findByPet_Id(Long petId);

    @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.pet.petId = :petId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')")
    List<Appointment> findByPetIdAndAppointmentDate(@Param("petId") Long petId, @Param("date") LocalDate date);

    List<Appointment> findByAppointmentDateAndAppointmentStatusIgnoreCase(LocalDate date, String status);
}
