package testutils

import (
	"testing"

	"veza-backend-api/internal/models"

	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestSetupTestDB(t *testing.T) {
	db := SetupTestDB()
	require.NotNil(t, db)
	defer CleanupTestDB(db)

	// Vérifier que les tables sont créées
	assert.True(t, db.Migrator().HasTable(&models.User{}))
	assert.True(t, db.Migrator().HasTable(&models.Track{}))
	assert.True(t, db.Migrator().HasTable(&models.Playlist{}))
	assert.True(t, db.Migrator().HasTable(&models.Room{}))
	assert.True(t, db.Migrator().HasTable(&models.Message{}))
}

func TestCleanupTestDB(t *testing.T) {
	db := SetupTestDB()
	require.NotNil(t, db)

	err := CleanupTestDB(db)
	assert.NoError(t, err)

	// Vérifier que la DB est fermée en essayant une requête
	sqlDB, _ := db.DB()
	assert.Error(t, sqlDB.Ping())
}

func TestResetTestDB(t *testing.T) {
	db := SetupTestDB()
	require.NotNil(t, db)
	defer CleanupTestDB(db)

	// Réinitialiser la DB d'abord pour s'assurer qu'elle est vide
	err := ResetTestDB(db)
	require.NoError(t, err)

	// Vérifier que la DB est vide
	var count int64
	db.Model(&models.User{}).Count(&count)
	assert.Equal(t, int64(0), count, "DB should be empty after reset")

	// Créer des données de test
	user, err := CreateTestUser(db)
	require.NoError(t, err)
	require.NotNil(t, user)

	// Vérifier que les données existent
	db.Model(&models.User{}).Count(&count)
	assert.Equal(t, int64(1), count, "Should have exactly 1 user after creation")

	// Réinitialiser la DB
	err = ResetTestDB(db)
	assert.NoError(t, err)

	// Vérifier que les données ont été supprimées
	db.Model(&models.User{}).Count(&count)
	assert.Equal(t, int64(0), count, "DB should be empty after reset")
}

func TestGetDBStats(t *testing.T) {
	db := SetupTestDB()
	require.NotNil(t, db)
	defer CleanupTestDB(db)

	stats, err := GetDBStats(db)
	require.NoError(t, err)
	require.NotNil(t, stats)

	// Vérifier que les stats sont valides
	assert.GreaterOrEqual(t, stats.MaxOpenConnections, 0)
}

func TestSetupTestDB_CanCreateRecords(t *testing.T) {
	db := SetupTestDB()
	require.NotNil(t, db)
	defer CleanupTestDB(db)

	// Créer un utilisateur de test
	user, err := CreateTestUser(db)
	require.NoError(t, err)
	require.NotNil(t, user)

	// Vérifier que l'utilisateur a un ID
	assert.NotEqual(t, uuid.Nil, user.ID)

	// Vérifier que l'utilisateur peut être récupéré
	var retrievedUser models.User
	err = db.First(&retrievedUser, user.ID).Error
	require.NoError(t, err)
	assert.Equal(t, user.Username, retrievedUser.Username)
	assert.Equal(t, user.Email, retrievedUser.Email)
}
