package restapi

import (
	"fmt"
	"net/http"
	"os"
	"strings"

	"github.com/danielmiessler/fabric/internal/plugins/db/fsdb"
	"github.com/gin-gonic/gin"
)

// ConfigHandler defines the handler for configuration-related operations
type ConfigHandler struct {
	db *fsdb.Db
	// configurations *fsdb.EnvFilePath("$HOME/.config/fabric/.env")
}

func NewConfigHandler(r *gin.Engine, db *fsdb.Db) *ConfigHandler {
	handler := &ConfigHandler{
		db: db,
		// configurations: db.Configurations,
	}

	r.GET("/config", handler.GetConfig)
	r.POST("/config/update", handler.UpdateConfig)

	return handler
}

func (h *ConfigHandler) GetConfig(c *gin.Context) {
	if h.db == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": ".env file not found"})
		return
	}

	if !h.db.IsEnvFileExists() {
		c.JSON(http.StatusOK, gin.H{
			"openai":     "",
			"anthropic":  "",
			"groq":       "",
			"mistral":    "",
			"gemini":     "",
			"ollama":     "",
			"openrouter": "",
			"silicon":    "",
			"deepseek":   "",
			"grokai":     "",
		})
		return
	}

	err := h.db.LoadEnvFile()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	config := map[string]string{
		"openai":     os.Getenv("OPENAI_API_KEY"),
		"anthropic":  os.Getenv("ANTHROPIC_API_KEY"),
		"groq":       os.Getenv("GROQ_API_KEY"),
		"mistral":    os.Getenv("MISTRAL_API_KEY"),
		"gemini":     os.Getenv("GEMINI_API_KEY"),
		"ollama":     os.Getenv("OLLAMA_URL"),
		"openrouter": os.Getenv("OPENROUTER_API_KEY"),
		"silicon":    os.Getenv("SILICON_API_KEY"),
		"deepseek":   os.Getenv("DEEPSEEK_API_KEY"),
		"grokai":     os.Getenv("GROKAI_API_KEY"),
		"lmstudio":   os.Getenv("LM_STUDIO_API_BASE_URL"),
	}

	c.JSON(http.StatusOK, config)
}

func (h *ConfigHandler) UpdateConfig(c *gin.Context) {
	if h.db == nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Database not initialized"})
		return
	}

	var config struct {
		OpenAIApiKey     string `json:"openai_api_key"`
		AnthropicApiKey  string `json:"anthropic_api_key"`
		GroqApiKey       string `json:"groq_api_key"`
		MistralApiKey    string `json:"mistral_api_key"`
		GeminiApiKey     string `json:"gemini_api_key"`
		OllamaURL        string `json:"ollama_url"`
		OpenRouterApiKey string `json:"openrouter_api_key"`
		SiliconApiKey    string `json:"silicon_api_key"`
		DeepSeekApiKey   string `json:"deepseek_api_key"`
		GrokaiApiKey     string `json:"grokai_api_key"`
		LMStudioURL      string `json:"lm_studio_base_url"`
	}

	if err := c.ShouldBindJSON(&config); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	envVars := map[string]string{
		"OPENAI_API_KEY":         config.OpenAIApiKey,
		"ANTHROPIC_API_KEY":      config.AnthropicApiKey,
		"GROQ_API_KEY":           config.GroqApiKey,
		"MISTRAL_API_KEY":        config.MistralApiKey,
		"GEMINI_API_KEY":         config.GeminiApiKey,
		"OLLAMA_URL":             config.OllamaURL,
		"OPENROUTER_API_KEY":     config.OpenRouterApiKey,
		"SILICON_API_KEY":        config.SiliconApiKey,
		"DEEPSEEK_API_KEY":       config.DeepSeekApiKey,
		"GROKAI_API_KEY":         config.GrokaiApiKey,
		"LM_STUDIO_API_BASE_URL": config.LMStudioURL,
	}

	var envContent strings.Builder
	for key, value := range envVars {
		if value != "" {
			envContent.WriteString(fmt.Sprintf("%s=%s\n", key, value))
			os.Setenv(key, value)
		}
	}

	// Save configuration to file
	if err := h.db.SaveEnv(envContent.String()); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if err := h.db.LoadEnvFile(); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Configuration updated successfully"})
}
