package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository;

import java.time.OffsetDateTime;
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import com.iqser.red.service.persistence.management.v1.processor.entity.notification.NotificationEntity;

public interface NotificationRepository extends JpaRepository<NotificationEntity, Long> {

    @Query("select count(n) from NotificationEntity n  where " + " (exists (select e from NotificationPreferencesEntity e where e.userId = :userId) and n.notificationType in ( select apn from NotificationPreferencesEntity p join p.inAppNotifications apn  where p.userId = :userId and p.inAppNotificationsEnabled = true )) " + " and n.softDeleted is null and n.userId = :userId and n.creationDate > :since")
    int hasInAppNotificationForUser(String userId, OffsetDateTime since);


    @Query("""
            select n from NotificationEntity n  where
            (exists (select e from NotificationPreferencesEntity e where e.userId = :userId) and n.notificationType in
                (select apn from NotificationPreferencesEntity p join p.inAppNotifications apn  where p.userId = :userId and p.inAppNotificationsEnabled = true))
            and n.softDeleted is null and n.userId = :userId order by n.creationDate desc""")
    List<NotificationEntity> findAppNotificationsForUser(String userId);


    @Query("""
            select n from NotificationEntity n where
            (exists (select e from NotificationPreferencesEntity e where e.userId = :userId) and n.notificationType in
                (select apn from NotificationPreferencesEntity p join p.inAppNotifications apn  where p.userId = :userId and p.inAppNotificationsEnabled = true))
            and n.seenDate is null and n.softDeleted is null and n.userId = :userId order by n.creationDate desc""")
    List<NotificationEntity> findUnseenNotificationsForUser(String userId);


    @Modifying
    @Query("update NotificationEntity n set n.seenDate = :seenDate where n.id = :notificationId and n.userId = :userId")
    int setSeenDate(String userId, long notificationId, OffsetDateTime seenDate);


    @Modifying
    @Query("update NotificationEntity n set n.readDate = :readDate where n.id = :notificationId and n.userId = :userId")
    int setReadDate(String userId, long notificationId, OffsetDateTime readDate);


    @Modifying
    @Query("update NotificationEntity n set n.softDeleted = :softDeleted where n.id = :notificationId and n.userId = :userId")
    int softDelete(String userId, long notificationId, OffsetDateTime softDeleted);


    @Modifying
    @Query("update NotificationEntity n set n.softDeleted = :softDeleted where n.userId = :userId")
    void deleteAllByUserId(String userId, OffsetDateTime softDeleted);


    @Modifying
    @Query("update NotificationEntity n set n.softDeleted = :softDeleted where n.userId = :userId and n.notificationType in :removedNotificationTypes")
    void deleteAllByUserIdAndNotificationTypeIn(String userId, List<String> removedNotificationTypes, OffsetDateTime softDeleted);


    @Query("select n from NotificationEntity n  where " + " (exists (select e from NotificationPreferencesEntity e where e.userId = :userId) and n.notificationType in ( select apn from NotificationPreferencesEntity p join p.emailNotifications apn  where p.userId = :userId and p.emailNotificationsEnabled = true )) " + " and n.userId = :userId and n.creationDate  >= :from and n.creationDate <= :to order by n.creationDate desc")
    List<NotificationEntity> findEmailNotificationsForUserId(String userId, OffsetDateTime from, OffsetDateTime to);

}
