package com.gnx.telemedicine.repository;

import com.gnx.telemedicine.model.RefreshToken;
import com.gnx.telemedicine.model.UserModel;
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.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * Repository for refresh token operations.
 */
@Repository
public interface RefreshTokenRepository extends JpaRepository<RefreshToken, UUID> {
    
    /**
     * Find refresh token by token string.
     */
    Optional<RefreshToken> findByToken(String token);
    
    /**
     * Find all refresh tokens for a user.
     */
    List<RefreshToken> findByUser(UserModel user);
    
    /**
     * Find all valid (not revoked and not expired) refresh tokens for a user.
     */
    @Query("SELECT rt FROM RefreshToken rt WHERE rt.user = :user AND rt.revoked = false AND rt.expiryDate > :now")
    List<RefreshToken> findValidTokensByUser(@Param("user") UserModel user, @Param("now") Instant now);
    
    /**
     * Find refresh token by token and user.
     */
    Optional<RefreshToken> findByTokenAndUser(String token, UserModel user);
    
    /**
     * Delete all expired refresh tokens.
     */
    @Modifying
    @Query("DELETE FROM RefreshToken rt WHERE rt.expiryDate < :now")
    void deleteExpiredTokens(@Param("now") Instant now);
    
    /**
     * Revoke all refresh tokens for a user.
     */
    @Modifying
    @Query("UPDATE RefreshToken rt SET rt.revoked = true, rt.revokedAt = :now, rt.revokedReason = :reason WHERE rt.user = :user AND rt.revoked = false")
    void revokeAllTokensForUser(@Param("user") UserModel user, @Param("now") Instant now, @Param("reason") String reason);
    
    /**
     * Delete all refresh tokens for a user.
     */
    void deleteByUser(UserModel user);
    
    /**
     * Count active (not revoked and not expired) refresh tokens for a user.
     */
    @Query("SELECT COUNT(rt) FROM RefreshToken rt WHERE rt.user = :user AND rt.revoked = false AND rt.expiryDate > :now")
    long countActiveTokensByUser(@Param("user") UserModel user, @Param("now") Instant now);
}

