package com.honey.honey.repository;

import com.honey.honey.model.Session;
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.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
public interface SessionRepository extends JpaRepository<Session, Long> {
    Optional<Session> findBySessionIdHash(String sessionIdHash);
    
    /**
     * Counts active (non-expired) sessions for a user.
     */
    @Query("SELECT COUNT(s) FROM Session s WHERE s.userId = :userId AND s.expiresAt > :now")
    long countActiveSessionsByUserId(@Param("userId") Integer userId, @Param("now") LocalDateTime now);
    
    /**
     * Finds oldest active sessions for a user, ordered by created_at ASC.
     * Used to delete oldest sessions when max limit is exceeded.
     */
    @Query("SELECT s FROM Session s WHERE s.userId = :userId AND s.expiresAt > :now ORDER BY s.createdAt ASC")
    List<Session> findOldestActiveSessionsByUserId(@Param("userId") Integer userId, @Param("now") LocalDateTime now, Pageable pageable);
    
    /**
     * Counts all sessions (active + expired) for a user.
     */
    long countByUserId(Integer userId);
    
    /**
     * Finds oldest sessions (active or expired) for a user, ordered by created_at ASC.
     * Used to delete oldest sessions when max limit is exceeded.
     */
    @Query("SELECT s FROM Session s WHERE s.userId = :userId ORDER BY s.createdAt ASC")
    List<Session> findOldestSessionsByUserId(@Param("userId") Integer userId, Pageable pageable);
    
    /**
     * Batch deletes expired sessions (up to batchSize).
     * Returns the number of deleted rows.
     * Note: MySQL requires LIMIT to be a literal or bound parameter, so we use a native query.
     */
    @Modifying(clearAutomatically = true, flushAutomatically = true)
    @Query(value = "DELETE FROM sessions WHERE expires_at < :now LIMIT :batchSize", nativeQuery = true)
    int deleteExpiredSessionsBatch(@Param("now") LocalDateTime now, @Param("batchSize") int batchSize);
    
    @Modifying
    @Query("DELETE FROM Session s WHERE s.sessionIdHash = :sessionIdHash")
    void deleteBySessionIdHash(@Param("sessionIdHash") String sessionIdHash);
}

