package models

import (
	"testing"
	"time"
)

// TestUser tests the User model
func TestUser(t *testing.T) {
	t.Run("Create User", func(t *testing.T) {
		user := &User{
			Username:     "testuser",
			Email:        "test@example.com",
			PasswordHash: "hashedpassword",
			Status:       "active",
			Timezone:     "Asia/Shanghai",
			Language:     "zh-CN",
		}

		if user.Username != "testuser" {
			t.Errorf("Expected username 'testuser', got '%s'", user.Username)
		}

		if user.Email != "test@example.com" {
			t.Errorf("Expected email 'test@example.com', got '%s'", user.Email)
		}

		if user.Status != "active" {
			t.Errorf("Expected status 'active', got '%s'", user.Status)
		}
	})

	t.Run("User Validation", func(t *testing.T) {
		tests := []struct {
			name     string
			user     User
			expected bool
		}{
			{
				name: "Valid User",
				user: User{
					Username:     "validuser",
					Email:        "valid@example.com",
					PasswordHash: "validpassword",
					Status:       "active",
				},
				expected: true,
			},
			{
				name: "Empty Username",
				user: User{
					Username:     "",
					Email:        "valid@example.com",
					PasswordHash: "validpassword",
				},
				expected: false,
			},
			{
				name: "Empty Email",
				user: User{
					Username:     "validuser",
					Email:        "",
					PasswordHash: "validpassword",
				},
				expected: false,
			},
			{
				name: "Empty Password",
				user: User{
					Username:     "validuser",
					Email:        "valid@example.com",
					PasswordHash: "",
				},
				expected: false,
			},
		}

		for _, tt := range tests {
			t.Run(tt.name, func(t *testing.T) {
				isValid := validateUser(tt.user)
				if isValid != tt.expected {
					t.Errorf("Expected %v, got %v", tt.expected, isValid)
				}
			})
		}
	})

	t.Run("User Timestamps", func(t *testing.T) {
		user := &User{
			Username:     "testuser",
			Email:        "test@example.com",
			PasswordHash: "hashedpassword",
			CreatedAt:    time.Now(),
			UpdatedAt:    time.Now(),
		}

		if user.CreatedAt.IsZero() {
			t.Error("CreatedAt should not be zero")
		}

		if user.UpdatedAt.IsZero() {
			t.Error("UpdatedAt should not be zero")
		}
	})
}

// validateUser is a helper function for testing user validation
func validateUser(user User) bool {
	if user.Username == "" {
		return false
	}
	if user.Email == "" {
		return false
	}
	if user.PasswordHash == "" {
		return false
	}
	return true
}

// TestUserPreference tests the UserPreference model
func TestUserPreference(t *testing.T) {
	t.Run("Create UserPreference", func(t *testing.T) {
		preference := &UserPreference{
			UserID:          1,
			DailyGoal:       50,
			WeeklyGoal:      350,
			ReminderEnabled: true,
			DifficultyLevel: "beginner",
			LearningMode:    "casual",
		}

		if preference.UserID != 1 {
			t.Errorf("Expected UserID 1, got %d", preference.UserID)
		}

		if preference.DailyGoal != 50 {
			t.Errorf("Expected DailyGoal 50, got %d", preference.DailyGoal)
		}

		if preference.DifficultyLevel != "beginner" {
			t.Errorf("Expected DifficultyLevel 'beginner', got '%s'", preference.DifficultyLevel)
		}
	})

	t.Run("Preference Validation", func(t *testing.T) {
		tests := []struct {
			name       string
			preference UserPreference
			expected   bool
		}{
			{
				name: "Valid Preference",
				preference: UserPreference{
					UserID:          1,
					DailyGoal:       50,
					WeeklyGoal:      350,
					DifficultyLevel: "beginner",
					LearningMode:    "casual",
				},
				expected: true,
			},
			{
				name: "Invalid UserID",
				preference: UserPreference{
					UserID:          0,
					DailyGoal:       50,
					DifficultyLevel: "beginner",
				},
				expected: false,
			},
			{
				name: "Negative Daily Goal",
				preference: UserPreference{
					UserID:          1,
					DailyGoal:       -10,
					DifficultyLevel: "beginner",
				},
				expected: false,
			},
			{
				name: "Invalid Difficulty Level",
				preference: UserPreference{
					UserID:          1,
					DailyGoal:       50,
					DifficultyLevel: "invalid",
				},
				expected: false,
			},
		}

		for _, tt := range tests {
			t.Run(tt.name, func(t *testing.T) {
				isValid := validateUserPreference(tt.preference)
				if isValid != tt.expected {
					t.Errorf("Expected %v, got %v", tt.expected, isValid)
				}
			})
		}
	})
}

// validateUserPreference is a helper function for testing user preference validation
func validateUserPreference(preference UserPreference) bool {
	if preference.UserID <= 0 {
		return false
	}
	if preference.DailyGoal < 0 || preference.WeeklyGoal < 0 {
		return false
	}
	validDifficultyLevels := []string{"beginner", "intermediate", "advanced"}
	validDifficulty := false
	for _, level := range validDifficultyLevels {
		if preference.DifficultyLevel == level {
			validDifficulty = true
			break
		}
	}
	if !validDifficulty {
		return false
	}
	return true
}

// TestUserSocialLink tests the UserSocialLink model
func TestUserSocialLink(t *testing.T) {
	t.Run("Create UserSocialLink", func(t *testing.T) {
		socialLink := &UserSocialLink{
			UserID:   1,
			Platform: "github",
			URL:      "https://github.com/testuser",
		}

		if socialLink.UserID != 1 {
			t.Errorf("Expected UserID 1, got %d", socialLink.UserID)
		}

		if socialLink.Platform != "github" {
			t.Errorf("Expected Platform 'github', got '%s'", socialLink.Platform)
		}

		if socialLink.URL != "https://github.com/testuser" {
			t.Errorf("Expected URL 'https://github.com/testuser', got '%s'", socialLink.URL)
		}
	})

	t.Run("Social Link Validation", func(t *testing.T) {
		tests := []struct {
			name       string
			socialLink UserSocialLink
			expected   bool
		}{
			{
				name: "Valid Social Link",
				socialLink: UserSocialLink{
					UserID:   1,
					Platform: "github",
					URL:      "https://github.com/testuser",
				},
				expected: true,
			},
			{
				name: "Invalid UserID",
				socialLink: UserSocialLink{
					UserID:   0,
					Platform: "github",
					URL:      "https://github.com/testuser",
				},
				expected: false,
			},
			{
				name: "Empty Platform",
				socialLink: UserSocialLink{
					UserID:   1,
					Platform: "",
					URL:      "https://github.com/testuser",
				},
				expected: false,
			},
			{
				name: "Empty URL",
				socialLink: UserSocialLink{
					UserID:   1,
					Platform: "github",
					URL:      "",
				},
				expected: false,
			},
		}

		for _, tt := range tests {
			t.Run(tt.name, func(t *testing.T) {
				isValid := validateUserSocialLink(tt.socialLink)
				if isValid != tt.expected {
					t.Errorf("Expected %v, got %v", tt.expected, isValid)
				}
			})
		}
	})
}

// validateUserSocialLink is a helper function for testing user social link validation
func validateUserSocialLink(socialLink UserSocialLink) bool {
	if socialLink.UserID <= 0 {
		return false
	}
	if socialLink.Platform == "" {
		return false
	}
	if socialLink.URL == "" {
		return false
	}
	return true
}