package com.betriebsratkanzlei.legalconsenthub.notification

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.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import java.util.UUID

@Repository
interface NotificationRepository : JpaRepository<Notification, UUID> {

    fun findByRecipientIdOrderByCreatedAtDesc(recipientId: String?, pageable: Pageable): Page<Notification>
    fun findByRecipientIdAndIsReadFalseOrderByCreatedAtDesc(recipientId: String?): List<Notification>
    fun countByRecipientIdAndIsReadFalse(recipientId: String?): Long

    @Query("""
        SELECT n FROM Notification n WHERE 
        (n.recipient.id = :recipientId) OR 
        (n.recipient IS NULL AND CONCAT(n.organizationId, ':', n.role) IN :orgRolePairs) OR
        (n.recipient IS NULL AND n.organizationId IN :organizationIds AND (n.role IS NULL OR n.role = ''))
        ORDER BY n.createdAt DESC
    """)
    fun findUserNotificationsByOrgRole(
        @Param("recipientId") recipientId: String,
        @Param("organizationIds") organizationIds: List<String>,
        @Param("orgRolePairs") orgRolePairs: List<String>,
        pageable: Pageable
    ): Page<Notification>

    @Query("""
        SELECT n FROM Notification n WHERE 
        ((n.recipient.id = :recipientId) OR 
        (n.recipient IS NULL AND CONCAT(n.organizationId, ':', n.role) IN :orgRolePairs) OR
        (n.recipient IS NULL AND n.organizationId IN :organizationIds AND (n.role IS NULL OR n.role = '')))
        AND n.isRead = false
        ORDER BY n.createdAt DESC
    """)
    fun findUnreadUserNotificationsByOrgRole(
        @Param("recipientId") recipientId: String,
        @Param("organizationIds") organizationIds: List<String>,
        @Param("orgRolePairs") orgRolePairs: List<String>
    ): List<Notification>

    @Query("""
        SELECT COUNT(n) FROM Notification n WHERE 
        ((n.recipient.id = :recipientId) OR 
        (n.recipient IS NULL AND CONCAT(n.organizationId, ':', n.role) IN :orgRolePairs) OR
        (n.recipient IS NULL AND n.organizationId IN :organizationIds AND (n.role IS NULL OR n.role = '')))
        AND n.isRead = false
    """)
    fun countUnreadUserNotifications(
        @Param("recipientId") recipientId: String,
        @Param("organizationIds") organizationIds: List<String>,
        @Param("orgRolePairs") orgRolePairs: List<String>
    ): Long

    @Modifying
    @Query("""
        UPDATE Notification n SET n.isRead = true WHERE 
        (n.recipient.id = :recipientId) OR 
        (n.recipient IS NULL AND CONCAT(n.organizationId, ':', n.role) IN :orgRolePairs) OR
        (n.recipient IS NULL AND n.organizationId IN :organizationIds AND (n.role IS NULL OR n.role = ''))
    """)
    fun markAllUserNotificationsAsRead(
        @Param("recipientId") recipientId: String,
        @Param("organizationIds") organizationIds: List<String>,
        @Param("orgRolePairs") orgRolePairs: List<String>
    )

    @Modifying
    @Query("UPDATE Notification n SET n.isRead = true WHERE n.recipient.id = :recipientId")
    fun markAllAsReadByRecipientId(@Param("recipientId") recipientId: String)
}
