package services

import (
	"context"
	"github.com/google/uuid"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap/zaptest"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"

	"veza-backend-api/internal/models"
)

func setupTestPlaybackFilterServiceDB(t *testing.T) (*gorm.DB, *PlaybackFilterService) {
	db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
	require.NoError(t, err)

	db.Exec("PRAGMA foreign_keys = ON")

	err = db.AutoMigrate(&models.User{}, &models.Track{}, &models.PlaybackAnalytics{})
	require.NoError(t, err)

	logger := zaptest.NewLogger(t)
	service := NewPlaybackFilterService(db, logger)

	return db, service
}

func TestNewPlaybackFilterService(t *testing.T) {
	db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
	logger := zaptest.NewLogger(t)

	service := NewPlaybackFilterService(db, logger)

	assert.NotNil(t, service)
	assert.Equal(t, db, service.db)
	assert.NotNil(t, service.logger)
}

func TestNewPlaybackFilterService_NilLogger(t *testing.T) {
	db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})

	service := NewPlaybackFilterService(db, nil)

	assert.NotNil(t, service)
	assert.NotNil(t, service.logger)
}

func TestPlaybackFilterService_Filter_NoFilters(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		PauseCount:     2,
		SeekCount:      3,
		CompletionRate: 66.67,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		PauseCount:     1,
		SeekCount:      2,
		CompletionRate: 83.33,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)

	// Filtrer sans filtres
	filter := PlaybackFilter{}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(2), total)
	assert.Len(t, results, 2)
}

func TestPlaybackFilterService_Filter_ByUserID(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer users et track
	user1ID := uuid.New()
	user2ID := uuid.New()
	trackID := uuid.New()
	user1 := &models.User{ID: user1ID, Username: "user1", Email: "user1@example.com", IsActive: true}
	user2 := &models.User{ID: user2ID, Username: "user2", Email: "user2@example.com", IsActive: true}
	db.Create(user1)
	db.Create(user2)
	track := &models.Track{
		ID:       trackID,
		UserID:   user1ID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics pour différents users
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         user1ID,
		PlayTime:       120,
		CompletionRate: 66.67,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         user2ID,
		PlayTime:       150,
		CompletionRate: 83.33,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)

	// Filtrer par user ID
	filter := PlaybackFilter{UserID: &user1ID}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(1), total)
	assert.Len(t, results, 1)
	assert.Equal(t, user1ID, results[0].UserID)
}

func TestPlaybackFilterService_Filter_ByDateRange(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics à différentes dates
	now := time.Now()
	startDate := now.AddDate(0, 0, -5)
	endDate := now.AddDate(0, 0, -2)

	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 66.67,
		StartedAt:      now.AddDate(0, 0, -6), // En dehors de la plage
		CreatedAt:      now.AddDate(0, 0, -6),
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		CompletionRate: 83.33,
		StartedAt:      now.AddDate(0, 0, -3), // Dans la plage
		CreatedAt:      now.AddDate(0, 0, -3),
	}
	analytics3 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       180,
		CompletionRate: 100.0,
		StartedAt:      now.AddDate(0, 0, -1), // En dehors de la plage
		CreatedAt:      now.AddDate(0, 0, -1),
	}
	db.Create(analytics1)
	db.Create(analytics2)
	db.Create(analytics3)

	// Filtrer par plage de dates
	filter := PlaybackFilter{
		StartDate: &startDate,
		EndDate:   &endDate,
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(1), total)
	assert.Len(t, results, 1)
	assert.Equal(t, int64(150), int64(results[0].PlayTime))
}

func TestPlaybackFilterService_Filter_ByPeriod(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 66.67,
		StartedAt:      now.AddDate(0, 0, -8), // Il y a 8 jours
		CreatedAt:      now.AddDate(0, 0, -8),
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		CompletionRate: 83.33,
		StartedAt:      now.AddDate(0, 0, -3), // Il y a 3 jours (dans la semaine)
		CreatedAt:      now.AddDate(0, 0, -3),
	}
	db.Create(analytics1)
	db.Create(analytics2)

	// Filtrer par période "week"
	period := "week"
	filter := PlaybackFilter{Period: &period}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(1), total)
	assert.Len(t, results, 1)
	assert.Equal(t, int64(150), int64(results[0].PlayTime))
}

func TestPlaybackFilterService_Filter_ByCompletionRate(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics avec différents taux de complétion
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 50.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		CompletionRate: 75.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics3 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       180,
		CompletionRate: 95.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)
	db.Create(analytics3)

	// Filtrer par taux de complétion minimum
	minCompletion := 70.0
	filter := PlaybackFilter{MinCompletionRate: &minCompletion}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(2), total)
	assert.Len(t, results, 2)
	for _, result := range results {
		assert.GreaterOrEqual(t, result.CompletionRate, 70.0)
	}
}

func TestPlaybackFilterService_Filter_ByPlayTime(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics avec différents temps de lecture
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       60,
		CompletionRate: 33.33,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 66.67,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics3 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       180,
		CompletionRate: 100.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)
	db.Create(analytics3)

	// Filtrer par temps de lecture minimum et maximum
	minPlayTime := 100
	maxPlayTime := 150
	filter := PlaybackFilter{
		MinPlayTime: &minPlayTime,
		MaxPlayTime: &maxPlayTime,
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(1), total)
	assert.Len(t, results, 1)
	assert.Equal(t, 120, results[0].PlayTime)
}

func TestPlaybackFilterService_Filter_CombinedFilters(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer users et track
	user1ID := uuid.New()
	user2ID := uuid.New()
	trackID := uuid.New()
	user1 := &models.User{ID: user1ID, Username: "user1", Email: "user1@example.com", IsActive: true}
	user2 := &models.User{ID: user2ID, Username: "user2", Email: "user2@example.com", IsActive: true}
	db.Create(user1)
	db.Create(user2)
	track := &models.Track{
		ID:       trackID,
		UserID:   user1ID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         user1ID,
		PlayTime:       120,
		CompletionRate: 66.67,
		StartedAt:      now.AddDate(0, 0, -3),
		CreatedAt:      now.AddDate(0, 0, -3),
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         user2ID,
		PlayTime:       150,
		CompletionRate: 83.33,
		StartedAt:      now.AddDate(0, 0, -3),
		CreatedAt:      now.AddDate(0, 0, -3),
	}
	analytics3 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         user1ID,
		PlayTime:       180,
		CompletionRate: 100.0,
		StartedAt:      now.AddDate(0, 0, -8),
		CreatedAt:      now.AddDate(0, 0, -8),
	}
	db.Create(analytics1)
	db.Create(analytics2)
	db.Create(analytics3)

	// Filtrer avec plusieurs critères combinés
	startDate := now.AddDate(0, 0, -5)
	endDate := now
	minCompletion := 60.0
	filter := PlaybackFilter{
		UserID:            &user1ID,
		StartDate:         &startDate,
		EndDate:           &endDate,
		MinCompletionRate: &minCompletion,
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(1), total)
	assert.Len(t, results, 1)
	assert.Equal(t, user1ID, results[0].UserID)
	assert.Equal(t, 120, results[0].PlayTime)
}

func TestPlaybackFilterService_Filter_WithPagination(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer plusieurs analytics
	now := time.Now()
	for i := 0; i < 5; i++ {
		analytics := &models.PlaybackAnalytics{
			TrackID:        trackID,
			UserID:         userID,
			PlayTime:       120 + i*10,
			CompletionRate: 66.67 + float64(i),
			StartedAt:      now,
			CreatedAt:      now,
		}
		db.Create(analytics)
	}

	// Filtrer avec pagination
	filter := PlaybackFilter{
		Page:  1,
		Limit: 2,
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(5), total) // Total de tous les résultats
	assert.Len(t, results, 2)        // Seulement 2 résultats par page
}

func TestPlaybackFilterService_Filter_WithSorting(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics avec différents temps de lecture
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       100,
		CompletionRate: 55.56,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		CompletionRate: 83.33,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics3 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 66.67,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)
	db.Create(analytics3)

	// Filtrer avec tri par play_time ascendant
	filter := PlaybackFilter{
		SortBy:    "play_time",
		SortOrder: "asc",
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	assert.Equal(t, int64(3), total)
	assert.Len(t, results, 3)
	// Vérifier que les résultats sont triés par play_time croissant
	assert.Equal(t, 100, results[0].PlayTime)
	assert.Equal(t, 120, results[1].PlayTime)
	assert.Equal(t, 150, results[2].PlayTime)
}

func TestPlaybackFilterService_Filter_InvalidTrackID(t *testing.T) {
	_, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	filter := PlaybackFilter{}
	results, total, err := service.Filter(ctx, uuid.Nil, filter)

	assert.Error(t, err)
	assert.Contains(t, err.Error(), "invalid track ID")
	assert.Nil(t, results)
	assert.Equal(t, int64(0), total)
}

func TestPlaybackFilterService_Filter_TrackNotFound(t *testing.T) {
	_, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	filter := PlaybackFilter{}
	results, total, err := service.Filter(ctx, uuid.New(), filter)

	assert.Error(t, err)
	assert.Contains(t, err.Error(), "track not found")
	assert.Nil(t, results)
	assert.Equal(t, int64(0), total)
}

func TestPlaybackFilterService_GetFilteredStats(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		PauseCount:     2,
		SeekCount:      3,
		CompletionRate: 66.67,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		PauseCount:     1,
		SeekCount:      2,
		CompletionRate: 95.0, // ≥90%
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)

	// Obtenir les statistiques filtrées
	filter := PlaybackFilter{}
	stats, err := service.GetFilteredStats(ctx, trackID, filter)

	require.NoError(t, err)
	assert.NotNil(t, stats)
	assert.Equal(t, int64(2), stats.TotalSessions)
	assert.Equal(t, int64(270), stats.TotalPlayTime)
	assert.InDelta(t, 135.0, stats.AveragePlayTime, 0.1)
	assert.Equal(t, int64(3), stats.TotalPauses)
	assert.InDelta(t, 1.5, stats.AveragePauses, 0.1)
	assert.Equal(t, int64(5), stats.TotalSeeks)
	assert.InDelta(t, 2.5, stats.AverageSeeks, 0.1)
	assert.InDelta(t, 80.835, stats.AverageCompletion, 0.1)
	assert.InDelta(t, 50.0, stats.CompletionRate, 0.1) // 1 session sur 2 avec ≥90%
}

func TestPlaybackFilterService_GetFilteredStats_WithFilters(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics
	now := time.Now()
	analytics1 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 50.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	analytics2 := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       150,
		CompletionRate: 95.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics1)
	db.Create(analytics2)

	// Obtenir les statistiques avec filtre de completion rate
	minCompletion := 80.0
	filter := PlaybackFilter{MinCompletionRate: &minCompletion}
	stats, err := service.GetFilteredStats(ctx, trackID, filter)

	require.NoError(t, err)
	assert.NotNil(t, stats)
	assert.Equal(t, int64(1), stats.TotalSessions) // Seulement 1 session avec ≥80%
	assert.Equal(t, int64(150), stats.TotalPlayTime)
}

func TestPlaybackFilterService_Filter_InvalidPeriod(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Filtrer avec période invalide
	period := "invalid"
	filter := PlaybackFilter{Period: &period}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	// La période invalide est ignorée, donc tous les résultats sont retournés
	assert.GreaterOrEqual(t, total, int64(0))
	assert.NotNil(t, results)
}

func TestPlaybackFilterService_Filter_InvalidSortField(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Filtrer avec champ de tri invalide
	filter := PlaybackFilter{
		SortBy:    "invalid_field",
		SortOrder: "asc",
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	// Le champ invalide est remplacé par "created_at" par défaut
	assert.GreaterOrEqual(t, total, int64(0))
	assert.NotNil(t, results)
}

func TestPlaybackFilterService_Filter_CompletionRateBounds(t *testing.T) {
	db, service := setupTestPlaybackFilterServiceDB(t)
	ctx := context.Background()

	// Créer user et track
	userID := uuid.New()
	trackID := uuid.New()
	user := &models.User{ID: userID, Username: "testuser", Email: "test@example.com", IsActive: true}
	db.Create(user)
	track := &models.Track{
		ID:       trackID,
		UserID:   userID,
		Title:    "Test Track",
		FilePath: "/test.mp3",
		FileSize: 1024,
		Format:   "MP3",
		Duration: 180,
		IsPublic: true,
		Status:   models.TrackStatusCompleted,
	}
	db.Create(track)

	// Créer des analytics
	now := time.Now()
	analytics := &models.PlaybackAnalytics{
		TrackID:        trackID,
		UserID:         userID,
		PlayTime:       120,
		CompletionRate: 75.0,
		StartedAt:      now,
		CreatedAt:      now,
	}
	db.Create(analytics)

	// Tester avec des valeurs hors limites (devraient être corrigées)
	minCompletion := -10.0 // Devrait être corrigé à 0
	maxCompletion := 150.0 // Devrait être corrigé à 100
	filter := PlaybackFilter{
		MinCompletionRate: &minCompletion,
		MaxCompletionRate: &maxCompletion,
	}
	results, total, err := service.Filter(ctx, trackID, filter)

	require.NoError(t, err)
	// Les valeurs hors limites sont corrigées, donc le résultat devrait être trouvé
	assert.Equal(t, int64(1), total)
	assert.Len(t, results, 1)
}
