package com.gnx.telemedicine.repository;

import com.gnx.telemedicine.model.Message;
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.List;
import java.util.UUID;

@Repository
public interface MessageRepository extends JpaRepository<Message, UUID> {
    
    @Query("SELECT m FROM Message m WHERE " +
           "((m.sender.id = :userId1 AND m.receiver.id = :userId2) OR " +
           "(m.sender.id = :userId2 AND m.receiver.id = :userId1)) " +
           "AND (m.sender.id != :currentUserId OR (m.deletedBySender IS NULL OR m.deletedBySender = false)) " +
           "AND (m.receiver.id != :currentUserId OR (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false)) " +
           "ORDER BY m.createdAt ASC")
    List<Message> findConversationBetweenUsers(@Param("userId1") UUID userId1, @Param("userId2") UUID userId2, @Param("currentUserId") UUID currentUserId);

    @Query("SELECT COUNT(m) FROM Message m WHERE m.receiver.id = :userId AND m.isRead = false " +
           "AND (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false)")
    Long countUnreadMessages(@Param("userId") UUID userId);

    @Query("SELECT COUNT(m) FROM Message m WHERE m.receiver.id = :userId AND m.sender.id = :senderId AND m.isRead = false " +
           "AND (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false)")
    Long countUnreadMessagesFromSender(@Param("userId") UUID userId, @Param("senderId") UUID senderId);

    @Modifying
    @Query("UPDATE Message m SET m.isRead = true WHERE m.receiver.id = :userId AND m.sender.id = :senderId AND m.isRead = false " +
           "AND (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false)")
    void markMessagesAsRead(@Param("userId") UUID userId, @Param("senderId") UUID senderId);

    @Query("SELECT m FROM Message m WHERE m.receiver.id = :userId AND m.isRead = false " +
           "AND (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false) " +
           "ORDER BY m.createdAt DESC")
    List<Message> findUnreadMessages(@Param("userId") UUID userId);

    @Query("SELECT DISTINCT CASE " +
           "WHEN m.sender.id = :userId THEN m.receiver.id " +
           "ELSE m.sender.id END " +
           "FROM Message m WHERE (m.sender.id = :userId OR m.receiver.id = :userId) " +
           "AND (m.sender.id != :userId OR (m.deletedBySender IS NULL OR m.deletedBySender = false)) " +
           "AND (m.receiver.id != :userId OR (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false))")
    List<UUID> findConversationPartners(@Param("userId") UUID userId);
    
    @Query("SELECT MAX(m.createdAt) FROM Message m WHERE " +
           "((m.sender.id = :userId1 AND m.receiver.id = :userId2) OR " +
           "(m.sender.id = :userId2 AND m.receiver.id = :userId1)) " +
           "AND (m.sender.id != :currentUserId OR (m.deletedBySender IS NULL OR m.deletedBySender = false)) " +
           "AND (m.receiver.id != :currentUserId OR (m.deletedByReceiver IS NULL OR m.deletedByReceiver = false))")
    java.time.LocalDateTime getLastMessageTime(@Param("userId1") UUID userId1, @Param("userId2") UUID userId2, @Param("currentUserId") UUID currentUserId);

    @Modifying(clearAutomatically = true)
    @Query("UPDATE Message m SET m.deletedBySender = true WHERE m.id = :messageId AND m.sender.id = :userId")
    void softDeleteMessageBySender(@Param("messageId") UUID messageId, @Param("userId") UUID userId);

    @Modifying(clearAutomatically = true)
    @Query("UPDATE Message m SET m.deletedByReceiver = true WHERE m.id = :messageId AND m.receiver.id = :userId")
    void softDeleteMessageByReceiver(@Param("messageId") UUID messageId, @Param("userId") UUID userId);

    @Modifying(clearAutomatically = true)
    @Query("UPDATE Message m SET m.deletedBySender = true WHERE m.sender.id = :userId AND m.receiver.id = :otherUserId")
    void softDeleteConversationBySender(@Param("userId") UUID userId, @Param("otherUserId") UUID otherUserId);

    @Modifying(clearAutomatically = true)
    @Query("UPDATE Message m SET m.deletedByReceiver = true WHERE m.receiver.id = :userId AND m.sender.id = :otherUserId")
    void softDeleteConversationByReceiver(@Param("userId") UUID userId, @Param("otherUserId") UUID otherUserId);
}

