package main

// system_status.go — GET /api/system icin ozellik/motor durum listesini uretir.
//
// Neden ayri dosya? main.go DI kurulumuyla mesgul; buradaki liste ise saf bir
// "config → gorunur durum" donusumudur ve TEK YERDE tutulmalidir (iki yerden
// uretilirse ekranla backend birbirini tutmaz).
//
// Kural: gizli degerler (API anahtarlari, tam yollar) ASLA gonderilmez; yalnizca
// "var/yok" bilgisi verilir.

import (
	"fmt"
	"strings"

	"fiko-ai/config"
	"fiko-ai/internal/api"
)

// systemFeatures, tum ozellikleri gruplanmis sirayla dondurur.
//
// `Enabled` = sunucuda acik; `Configured` = acik olmak icin gereken ayarlar tam.
// Ayrim onemlidir: "kapali" ile "eksik ayarli" ayni sey degildir (bkz.
// api.FeatureStatus yorumu).
func systemFeatures(cfg config.Config) []api.FeatureStatus {
	fs := []api.FeatureStatus{
		// ---- Konusma ----
		{
			Key: "llm", Title: "Dil modeli (Ollama)", Group: "Konuşma",
			Enabled:    strings.TrimSpace(cfg.Ollama.BaseURL) != "",
			Configured: strings.TrimSpace(cfg.Ollama.BaseURL) != "" && strings.TrimSpace(cfg.Ollama.Model) != "",
			Provider:   "ollama",
			Detail:     modelDetail(cfg.Ollama.Model),
		},
		// ---- Ses ----
		{
			Key: "stt", Title: "Konuşma tanıma (STT)", Group: "Ses",
			Enabled: cfg.STT.Enabled, Configured: sttConfigured(cfg.STT),
			Provider: cfg.STT.Provider, Detail: sttDetail(cfg.STT),
		},
		{
			Key: "tts", Title: "Sesli okuma (TTS)", Group: "Ses",
			Enabled: cfg.TTS.Enabled, Configured: ttsConfigured(cfg.TTS),
			Provider: cfg.TTS.Provider, Detail: ttsDetail(cfg.TTS),
		},
		// ---- Araclar ----
		{
			Key: "tools.fs", Title: "Dosya araçları", Group: "Araçlar",
			Enabled: true, Configured: true, Detail: "fs.*",
		},
		{
			Key: "tools.web", Title: "İnternet araçları", Group: "Araçlar",
			Enabled:    cfg.Tools.WebEnabled && cfg.Tools.HTTPEnabled,
			Configured: cfg.Tools.WebEnabled && cfg.Tools.HTTPEnabled,
			Provider:   cfg.Tools.WebSearchProvider,
			Detail:     "web.fetch / web.search / web.exchange_rate",
		},
		{
			Key: "tools.biz", Title: "Şirket (biz.*)", Group: "Araçlar",
			Enabled: cfg.Tools.BizEnabled, Configured: cfg.Tools.BizEnabled,
			Detail: bizDetail(cfg.Tools.BizPath),
		},
		{
			Key: "tools.http", Title: "Uzak (HTTP) tool'lar", Group: "Araçlar",
			Enabled: cfg.Tools.HTTPEnabled, Configured: cfg.Tools.HTTPEnabled,
			Detail: httpToolDetail(cfg.Tools.HTTPAllowPrivate),
		},
		{
			Key: "tools.exec", Title: "Süreç çalıştırma", Group: "Araçlar",
			Enabled: cfg.Tools.ExecEnabled, Configured: len(cfg.Tools.ExecAllowed) > 0,
			Detail: execDetail(cfg.Tools.ExecEnabled, cfg.Tools.ExecAllowed),
		},
		// ---- Veri ----
		{
			// MongoDB YOKSA veri bellekte tutulur ve sunucu kapanınca KAYBOLUR.
			// Bu yuzden "daima hazır" denmez: ayar gerçekten tanımlı mı bildirilir.
			Key: "mongo", Title: "Kalıcı depolama (MongoDB)", Group: "Veri",
			Enabled:    mongoEnabled(cfg),
			Configured: mongoEnabled(cfg),
			Detail:     mongoDetail(cfg.Mongo.URI),
		},
		{
			Key: "memory", Title: "Kalıcı hafıza", Group: "Veri",
			Enabled: cfg.Memory.Enabled, Configured: cfg.Memory.Enabled,
		},
		{
			// Bilgi tabanı anahtar-kelime araması her zaman çalışır; VECTOR arama
			// ise Ollama embedding modeline bağlıdır. İkisi ayrı ayrı bildirilir.
			Key: "knowledge", Title: "Bilgi tabanı (RAG)", Group: "Veri",
			Enabled:    knowledgeEnabled(cfg),
			Configured: knowledgeEnabled(cfg),
			Detail:     knowledgeDetail(cfg.Knowledge.VectorSearch, vectorOK(cfg)),
		},
	}

	out := make([]api.FeatureStatus, 0, len(fs))
	for _, f := range fs {
		f.Hint = hintFor(f)
		out = append(out, f)
	}
	return out
}

// sttConfigured: yalnizca URL sart.
//
// API anahtari OPSIYONELDIR: HTTP istemcisi anahtar varsa gonderir, yoksa gondermez
// (bkz. stt/openai.go). Yerel motorlar (faster-whisper sunucusu) anahtarsiz calisir;
// anahtari zorunlu saymak, calisan sistemi "eksik" gosteriyordu (canli bulgu).
func sttConfigured(s config.STT) bool {
	return strings.TrimSpace(s.URL) != ""
}

// ttsConfigured: yalnizca URL sart (anahtar opsiyonel, bkz. sttConfigured).
func ttsConfigured(t config.TTS) bool {
	return strings.TrimSpace(t.URL) != ""
}

func modelDetail(model string) string {
	if m := strings.TrimSpace(model); m != "" {
		return m
	}
	return "OLLAMA_MODEL boş"
}

func sttDetail(s config.STT) string {
	if strings.TrimSpace(s.URL) == "" {
		return "STT_URL boş"
	}
	return s.Provider + " motoru hazır"
}

func ttsDetail(t config.TTS) string {
	if strings.TrimSpace(t.URL) == "" {
		return "TTS_URL boş"
	}
	return t.Provider + " motoru hazır"
}

// bizDetail veri dosyasini gosterir; dosya yoksa bellek ici calisilir (veri kaybolur).
// bizDetail, verinin kalici olup olmadigini soyler. Dosya YOLU gonderilmez:
// mutlak yol kullanici dizinini (ve bazen kullanici adini) ifsa eder.
func bizDetail(path string) string {
	if strings.TrimSpace(path) == "" {
		return "bellek içi (yeniden başlatınca kaybolur)"
	}
	return "kalıcı JSON dosyası"
}

// httpToolDetail SSRF korumasinin durumunu soyler: uretimde kapali olmalidir.
func httpToolDetail(allowPrivate bool) string {
	if allowPrivate {
		return "ÖZEL AĞ AÇIK (SSRF koruması kapalı)"
	}
	return "SSRF koruması açık"
}

func execDetail(enabled bool, allowed []string) string {
	switch {
	case !enabled:
		return "TOOLS_EXEC_ENABLED=false"
	case len(allowed) == 0:
		return "izin listesi boş (hiçbir program çalışmaz)"
	default:
		return fmt.Sprintf("%d program", len(allowed))
	}
}

// mongoDetail, MongoDB'nin YALNIZCA varlik durumunu soyler.
//
// GUVENLIK: URI ASLA gonderilmez. URI kullanici adi, sifre ve host icerebilir
// ("mongodb://fiko:sifre@10.0.0.5:27017") — ekran goruntusu, log veya tarayici
// gecmisinde kalir. Onceki surum URI'yi oldugu gibi yaziyordu.
func mongoDetail(uri string) string {
	if strings.TrimSpace(uri) == "" {
		return "yok (bellek içi — veriler sunucu kapanınca kaybolur)"
	}
	return "bağlantı tanımlı"
}

// knowledgeDetail, arama modunu ACIKCA soyler: vektor + anahtar-kelime birlikte
// calisir; vektor arama embedding modeline baglidir ve model yoksa KAPALI kalir.
func knowledgeDetail(vectorSearch string, vector bool) string {
	mode := "auto"
	if v := strings.TrimSpace(vectorSearch); v != "" {
		mode = v
	}
	if !vector {
		return "anahtar-kelime (vektor arama için Ollama embedding modeli gerekli)"
	}
	return "vektor + anahtar-kelime (" + mode + ")"
}

// hintFor, duruma gore kullaniciya ne yapmasi gerektigini soyler.
func hintFor(f api.FeatureStatus) string {
	if f.Enabled && f.Configured {
		return ""
	}
	switch f.Key {
	case "stt":
		// Yalnizca "acik mi" degil, "NE eksik" oldugunu soyle: openai seciliyse
		// eksik olan API anahtari, URL degildir (eski mesaj yanlis yol gosteriyordu).
		if f.Configured {
			return "STT_ENABLED=true yap"
		}
		return "STT_URL'i motor adresiyle doldur, sonra STT_ENABLED=true"
	case "tts":
		if f.Configured {
			return "TTS_ENABLED=true yap"
		}
		return "TTS_URL'i motor adresiyle doldur, sonra TTS_ENABLED=true"
	case "llm":
		return "Ollama'yı çalıştır (ollama serve) ve OLLAMA_MODEL ver"
	case "tools.biz":
		return "TOOLS_BIZ_ENABLED=true yap (şirket araçları kaydedilsin)"
	case "tools.web":
		return "TOOLS_HTTP_ENABLED=true yap"
	case "tools.exec":
		return "TOOLS_EXEC_ENABLED=true + TOOLS_EXEC_ALLOW=<tam yol>"
	case "memory":
		return "MEMORY_ENABLED=true yap"
	case "mongo":
		// Veri kaybolmasi en kotu senaryo; kullaniciya acikca soyle.
		return "MONGO_URI ver (yoksa veriler bellekte kalir ve sunucu kapaninca kaybolur)"
	case "knowledge":
		return "Ollama ve MONGO_URI ver (vektor arama embedding modeli ister)"
	default:
		return ""
	}
}

// mongoEnabled: kalici depolama gercekten tanimli mi?
func mongoEnabled(cfg config.Config) bool {
	return strings.TrimSpace(cfg.Mongo.URI) != ""
}

// vectorOK: Ollama embedding modeli tanimli mi (vektor arama buna bagli)?
func vectorOK(cfg config.Config) bool {
	return strings.TrimSpace(cfg.Ollama.BaseURL) != "" && strings.TrimSpace(cfg.Ollama.EmbedModel) != ""
}

// knowledgeEnabled: bilgi tabani yapilandirilmis mi?
func knowledgeEnabled(cfg config.Config) bool {
	return strings.TrimSpace(cfg.Ollama.BaseURL) != "" || strings.TrimSpace(cfg.Mongo.URI) != ""
}
