package config

import (
	"strings"
	"testing"

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

func TestGenerateConfigDocs(t *testing.T) {
	docs := GenerateConfigDocs()

	// Vérifier le header
	assert.Contains(t, docs, "# Configuration Variables")
	assert.Contains(t, docs, "Veza backend API")

	// Vérifier que les variables documentées sont présentes
	assert.Contains(t, docs, "APP_ENV")
	assert.Contains(t, docs, "APP_PORT")
	assert.Contains(t, docs, "JWT_SECRET")
	assert.Contains(t, docs, "DATABASE_URL")
	assert.Contains(t, docs, "REDIS_URL")
	assert.Contains(t, docs, "LOG_LEVEL")

	// Vérifier la structure de base
	assert.Contains(t, docs, "**Type**:")
	assert.Contains(t, docs, "**Required**:")
	assert.Contains(t, docs, "**Description**:")
}

func TestGenerateConfigDocs_Structure(t *testing.T) {
	docs := GenerateConfigDocs()

	// Vérifier qu'il y a des sections pour chaque variable
	lines := strings.Split(docs, "\n")

	// Devrait contenir des sections ## pour chaque variable
	sectionCount := 0
	for _, line := range lines {
		if strings.HasPrefix(line, "## ") && line != "## Overview" {
			sectionCount++
		}
	}

	// Au moins quelques variables devraient être documentées
	assert.Greater(t, sectionCount, 5, "Should have multiple variable sections")
}

func TestGenerateConfigDocs_ContainsRequiredFields(t *testing.T) {
	docs := GenerateConfigDocs()

	// Vérifier qu'une variable requise est documentée comme telle
	assert.Contains(t, docs, "JWT_SECRET")
	jwtSection := strings.Split(docs, "## JWT_SECRET")[1]
	jwtSection = strings.Split(jwtSection, "---")[0]

	assert.Contains(t, jwtSection, "✅ Yes", "JWT_SECRET should be marked as required")

	// Vérifier qu'une variable optionnelle est documentée
	assert.Contains(t, docs, "APP_ENV")
	appEnvSection := strings.Split(docs, "## APP_ENV")[1]
	appEnvSection = strings.Split(appEnvSection, "---")[0]

	assert.Contains(t, appEnvSection, "❌ No", "APP_ENV should be marked as not required")
}

func TestGenerateConfigDocs_ContainsExamples(t *testing.T) {
	docs := GenerateConfigDocs()

	// Vérifier qu'il y a des exemples
	assert.Contains(t, docs, "**Example**:")
	assert.Contains(t, docs, "```bash")
	assert.Contains(t, docs, "export")
}

func TestGenerateConfigDocs_ContainsDefaults(t *testing.T) {
	docs := GenerateConfigDocs()

	// Vérifier qu'il y a des valeurs par défaut
	assert.Contains(t, docs, "**Default**:")
	assert.Contains(t, docs, "development") // Default pour APP_ENV
	assert.Contains(t, docs, "8080")        // Default pour APP_PORT
}

func TestGetAllEnvVarDocs(t *testing.T) {
	docs := GetAllEnvVarDocs()

	// Vérifier que la map contient des entrées
	assert.Greater(t, len(docs), 0, "Should have environment variables documented")

	// Vérifier quelques variables clés
	assert.Contains(t, docs, "APP_ENV")
	assert.Contains(t, docs, "JWT_SECRET")
	assert.Contains(t, docs, "DATABASE_URL")

	// Vérifier la structure d'une variable
	appEnvDoc := docs["APP_ENV"]
	assert.Equal(t, "APP_ENV", appEnvDoc.Name)
	assert.Equal(t, "string", appEnvDoc.Type)
	assert.False(t, appEnvDoc.Required)
	assert.Equal(t, "development", appEnvDoc.Default)
	assert.NotEmpty(t, appEnvDoc.Description)

	// Vérifier une variable requise
	jwtSecretDoc := docs["JWT_SECRET"]
	assert.True(t, jwtSecretDoc.Required, "JWT_SECRET should be required")
}

func TestEnvVarDoc_Complete(t *testing.T) {
	// Vérifier que toutes les entrées de envVarsDocs sont complètes
	allDocs := GetAllEnvVarDocs()

	for key, doc := range allDocs {
		assert.NotEmpty(t, doc.Name, "Name should not be empty for %s", key)
		assert.NotEmpty(t, doc.Type, "Type should not be empty for %s", key)
		assert.NotEmpty(t, doc.Description, "Description should not be empty for %s", key)

		// Si ce n'est pas requis, devrait avoir une valeur par défaut
		if !doc.Required {
			// Note: certaines variables peuvent avoir une valeur par défaut vide (c'est OK)
		}

		// Si c'est requis, ne devrait pas avoir de valeur par défaut (ou valeur vide)
		if doc.Required {
			assert.Empty(t, doc.Default, "Required variable %s should not have a default value", key)
		}
	}
}
