package antigravity

import (
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestDefaultModels(t *testing.T) {
	models := DefaultModels()

	// Should return models (Claude + Gemini)
	assert.NotEmpty(t, models)
	assert.GreaterOrEqual(t, len(models), len(claudeModels)+len(geminiModels))

	// Check all models have required fields
	for _, m := range models {
		assert.NotEmpty(t, m.ID, "Model ID should not be empty")
		assert.NotEmpty(t, m.DisplayName, "DisplayName should not be empty")
		assert.Equal(t, "model", m.Type)
		assert.NotEmpty(t, m.CreatedAt)
	}

	// Check that Claude models are present
	claudeFound := false
	for _, m := range models {
		if strings.HasPrefix(m.ID, "claude-") {
			claudeFound = true
			break
		}
	}
	assert.True(t, claudeFound, "Should have Claude models")

	// Check that Gemini models are present
	geminiFound := false
	for _, m := range models {
		if strings.HasPrefix(m.ID, "gemini-") {
			geminiFound = true
			break
		}
	}
	assert.True(t, geminiFound, "Should have Gemini models")
}

func TestDefaultGeminiModels(t *testing.T) {
	models := DefaultGeminiModels()

	// Should return only Gemini models
	assert.Equal(t, len(geminiModels), len(models))

	// Check all models have required fields
	for _, m := range models {
		assert.True(t, strings.HasPrefix(m.Name, "models/"), "Name should have models/ prefix")
		assert.NotEmpty(t, m.DisplayName)
		assert.Equal(t, defaultGeminiMethods, m.SupportedGenerationMethods)
	}
}

func TestFallbackGeminiModelsList(t *testing.T) {
	resp := FallbackGeminiModelsList()

	assert.NotEmpty(t, resp.Models)
	assert.Equal(t, len(geminiModels), len(resp.Models))
}

func TestFallbackGeminiModel(t *testing.T) {
	tests := []struct {
		name         string
		input        string
		expectedName string
	}{
		{
			name:         "with models/ prefix",
			input:        "gemini-2.5-flash",
			expectedName: "models/gemini-2.5-flash",
		},
		{
			name:         "without models/ prefix",
			input:        "gemini-3-pro",
			expectedName: "models/gemini-3-pro",
		},
		{
			name:         "already has prefix",
			input:        "models/gemini-2.5-flash",
			expectedName: "models/gemini-2.5-flash",
		},
		{
			name:         "empty string",
			input:        "",
			expectedName: "models/unknown",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := FallbackGeminiModel(tt.input)
			assert.Equal(t, tt.expectedName, result.Name)
			assert.Equal(t, defaultGeminiMethods, result.SupportedGenerationMethods)
		})
	}
}

func TestClaudeModelsNotEmpty(t *testing.T) {
	// Verify internal claudeModels slice is not empty
	assert.NotEmpty(t, claudeModels)

	for _, m := range claudeModels {
		assert.NotEmpty(t, m.ID)
		assert.NotEmpty(t, m.DisplayName)
	}
}

func TestGeminiModelsNotEmpty(t *testing.T) {
	// Verify internal geminiModels slice is not empty
	assert.NotEmpty(t, geminiModels)

	for _, m := range geminiModels {
		assert.NotEmpty(t, m.ID)
		assert.NotEmpty(t, m.DisplayName)
	}
}
