package rag

import (
	"context"
	"encoding/json"
	"time"

	FikoYTCtx "server/sistem/fikoyt_ctx"
	fiko_mongo "server/sistem/fikoyt_mongo"

	"github.com/gofiber/fiber/v3"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
)

const YetkiVT = "FikoYT.sistem.rag.yetkiler"

// Varsayılan olarak herkesin kullanabileceği tool'lar — TEMKİNLİ çekirdek:
// sadece kullanıcının kendi dünyası (soyağacı, paylaşımlar) ve zararsız yardımcılar.
// Hassas tool'lar (istatistik, ham kayıt okuma, mail, kullanıcı sorgulama...) Süper Yönetici
// veya admin panelden (RAG Yetkileri) kişiye özel atama gerektirir.
var varsayilanToollar = map[string]bool{
	"soru_sor":                true,
	"kayit_say":               true,
	"paylasim_ara":            true,
	"dinamik_bilesen_listele": true,
	"soyagaci_akrabalar":      true,
	"soyagaci_kisi_bul":       true,
}

// Süper Admin'in her zaman erişebildiği tool'lar
var superAdminToollar = map[string]bool{
	"hareketler_ara":          true,
	"hareket_getir":           true,
	"vt_listele":              true,
	"istatistik":              true,
	"hareket_ekle":            true,
	"hareket_guncelle":        true,
	"hareket_sil":             true,
	"aggregate_sorgula":       true,
	"kullanici_sorgula":       true,
	"sistem_saglik":           true,
	"soyagaci_akrabalar":      true,
	"soyagaci_kisi_bul":       true,
	"kisi_detay":              true,
	"uye_bul":                 true,
	"firma_sorgula":           true,
	"cihaz_sorgula":           true,
	"cihaz_canli_durum":       true,
	"aktif_kullanicilar":      true,
	"mail_sorgula":            true,
	"parametre_setleri":       true,
	"paylasim_ara":            true,
	"dinamik_bilesen_listele": true,
	"filitre_olustur":         true,
	"hareket_toplu_islem":     true,
}

// KullaniciYetkileriniAl — kullanıcının erişebildiği tool listesini döner
func KullaniciYetkileriniAl(kullaniciId interface{}) map[string]bool {
	yetkiler := map[string]bool{}

	// Varsayılan tool'ları ekle
	for k := range varsayilanToollar {
		yetkiler[k] = true
	}

	// Custom tool'lardan yalnızca "herkese açık" işaretliler varsayılana girer;
	// kapalılar Süper Yönetici veya kişiye özel atama (RAG Yetkileri) gerektirir.
	for _, ct := range customToollarYukle() {
		if ct.HerkeseAcik {
			yetkiler["custom_"+ct.Isim] = true
		}
	}

	if kullaniciId == nil {
		return yetkiler
	}

	ctx := context.TODO()
	kol := fiko_mongo.GetMongoDBClient().Database("fikoyt").Collection("hareketler")

	// Kullanıcı ID'yi hex'e çevir
	var kullaniciHex string
	switch v := kullaniciId.(type) {
	case primitive.ObjectID:
		kullaniciHex = v.Hex()
	case string:
		kullaniciHex = v
	}

	// Kullanıcıya özel yetki kaydı ara
	var yetkiKaydi bson.M
	kol.FindOne(ctx, bson.M{
		"vt":                 YetkiVT,
		"veri.kullanici_id":  kullaniciHex,
	}).Decode(&yetkiKaydi)

	if yetkiKaydi != nil {
		if veri, ok := yetkiKaydi["veri"].(bson.M); ok {
			if toollar, ok := veri["toollar"].(bson.A); ok {
				for _, t := range toollar {
					if ts, ok := t.(string); ok {
						yetkiler[ts] = true
					}
				}
			}
		}
		return yetkiler
	}

	// Kullanıcının rollerini kontrol et — Süper Yönetici ise tüm tool'lar açık
	var uye bson.M
	if oid, err := primitive.ObjectIDFromHex(kullaniciHex); err == nil {
		fiko_mongo.GetMongoDBClient().Database("fikoyt").Collection("goUyeler").FindOne(ctx, bson.M{"_id": oid}).Decode(&uye)
	}

	if uye != nil {
		if yetkilerRaw, ok := uye["yetkiler"]; ok {
			switch yl := yetkilerRaw.(type) {
			case bson.A:
				for _, y := range yl {
					if ys, ok := y.(string); ok && (ys == "Super Yonetici" || ys == "Süper Yönetici") {
						for k := range superAdminToollar {
							yetkiler[k] = true
						}
						for _, ct := range customToollarYukle() {
							yetkiler["custom_"+ct.Isim] = true
						}
						return yetkiler
					}
				}
			}
		}
	}

	return yetkiler
}

// ToolYetkisiVarMi — belirli bir tool için yetki kontrolü
func ToolYetkisiVarMi(kullaniciId interface{}, toolIsmi string) bool {
	yetkiler := KullaniciYetkileriniAl(kullaniciId)
	return yetkiler[toolIsmi]
}

// --- Admin API Handler'ları ---

func yetkiListeHandler(c fiber.Ctx) error {
	fkRaw := c.Locals("FikoYTCtx")
	if fkRaw == nil {
		return c.Status(401).JSON(fiber.Map{"hata": "Oturum bulunamadı"})
	}
	fk := fkRaw.(*FikoYTCtx.FikoYTCtx)
	if fk.AktifKullanici == nil || !fk.AktifKullanici.YetkiVarmi("Super Yonetici") {
		return c.Status(403).JSON(fiber.Map{"hata": "Yetkiniz yok"})
	}

	kol := fiko_mongo.GetMongoDBClient().Database("fikoyt").Collection("hareketler")
	cursor, err := kol.Find(context.TODO(), bson.M{"vt": YetkiVT}, options.Find().SetSort(bson.M{"guncelleme": -1}))
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"hata": err.Error()})
	}

	var sonuclar []bson.M
	cursor.All(context.TODO(), &sonuclar)
	if sonuclar == nil {
		sonuclar = []bson.M{}
	}

	return c.JSON(sonuclar)
}

func yetkiKaydetHandler(c fiber.Ctx) error {
	fkRaw := c.Locals("FikoYTCtx")
	if fkRaw == nil {
		return c.Status(401).JSON(fiber.Map{"hata": "Oturum bulunamadı"})
	}
	fk := fkRaw.(*FikoYTCtx.FikoYTCtx)
	if fk.AktifKullanici == nil || !fk.AktifKullanici.YetkiVarmi("Super Yonetici") {
		return c.Status(403).JSON(fiber.Map{"hata": "Yetkiniz yok"})
	}

	var istek struct {
		KullaniciID string   `json:"kullanici_id"`
		Toollar     []string `json:"toollar"`
	}
	json.Unmarshal(c.Body(), &istek)

	if istek.KullaniciID == "" {
		return c.Status(400).JSON(fiber.Map{"hata": "kullanici_id gerekli"})
	}

	kol := fiko_mongo.GetMongoDBClient().Database("fikoyt").Collection("hareketler")

	// Kullanıcı ismini çek
	var kullaniciIsmi string
	if oid, err := primitive.ObjectIDFromHex(istek.KullaniciID); err == nil {
		var uye bson.M
		fiko_mongo.GetMongoDBClient().Database("fikoyt").Collection("goUyeler").FindOne(context.TODO(), bson.M{"_id": oid}).Decode(&uye)
		if uye != nil {
			isim, _ := uye["isim"].(string)
			soyIsim, _ := uye["soyIsim"].(string)
			kullaniciIsmi = isim + " " + soyIsim
		}
	}

	filter := bson.M{
		"vt":                YetkiVT,
		"veri.kullanici_id": istek.KullaniciID,
	}

	toollarA := bson.A{}
	for _, t := range istek.Toollar {
		toollarA = append(toollarA, t)
	}

	update := bson.M{
		"$set": bson.M{
			"vt": YetkiVT,
			"veri": bson.M{
				"kullanici_id":    istek.KullaniciID,
				"kullanici_ismi":  kullaniciIsmi,
				"toollar":         toollarA,
			},
			"guncelleme": time.Now(),
		},
		"$setOnInsert": bson.M{
			"olusturma": time.Now(),
		},
	}

	kol.UpdateOne(context.TODO(), filter, update, options.Update().SetUpsert(true))

	return c.JSON(fiber.Map{"basarili": true})
}

func yetkiSilHandler(c fiber.Ctx) error {
	fkRaw := c.Locals("FikoYTCtx")
	if fkRaw == nil {
		return c.Status(401).JSON(fiber.Map{"hata": "Oturum bulunamadı"})
	}
	fk := fkRaw.(*FikoYTCtx.FikoYTCtx)
	if fk.AktifKullanici == nil || !fk.AktifKullanici.YetkiVarmi("Super Yonetici") {
		return c.Status(403).JSON(fiber.Map{"hata": "Yetkiniz yok"})
	}

	idStr := c.Params("id")
	oid, err := primitive.ObjectIDFromHex(idStr)
	if err != nil {
		return c.Status(400).JSON(fiber.Map{"hata": "Geçersiz ID"})
	}

	kol := fiko_mongo.GetMongoDBClient().Database("fikoyt").Collection("hareketler")
	kol.DeleteOne(context.TODO(), bson.M{"_id": oid, "vt": YetkiVT})

	return c.JSON(fiber.Map{"basarili": true})
}

// TumToolIsimleri — admin panelde göstermek için tüm tool listesi (custom tool'lar dahil).
// "varsayilan" bayrağı varsayilanToollar setiyle senkron tutulur.
func TumToolIsimleri() []fiber.Map {
	liste := []fiber.Map{
		{"id": "soru_sor", "baslik": "Soru Sor (RAG)", "kategori": "temel", "varsayilan": true},
		{"id": "kayit_say", "baslik": "Kayıt Say", "kategori": "temel", "varsayilan": true},
		{"id": "hareketler_ara", "baslik": "Kayıt Ara", "kategori": "hassas"},
		{"id": "hareket_getir", "baslik": "Kayıt Getir", "kategori": "hassas"},
		{"id": "vt_listele", "baslik": "VT Listele", "kategori": "sistem"},
		{"id": "istatistik", "baslik": "İstatistik", "kategori": "sistem"},

		{"id": "soyagaci_akrabalar", "baslik": "Akraba Listele", "kategori": "soyagaci", "varsayilan": true},
		{"id": "soyagaci_kisi_bul", "baslik": "Kişi Bul", "kategori": "soyagaci", "varsayilan": true},
		{"id": "kisi_detay", "baslik": "Kişi Detay", "kategori": "soyagaci"},
		{"id": "uye_bul", "baslik": "Üye Bul", "kategori": "kullanici"},

		{"id": "firma_sorgula", "baslik": "Firma Sorgula", "kategori": "firma"},
		{"id": "cihaz_sorgula", "baslik": "Cihaz Sorgula", "kategori": "cihaz"},
		{"id": "cihaz_canli_durum", "baslik": "Canlı Cihaz Durumu", "kategori": "cihaz"},
		{"id": "aktif_kullanicilar", "baslik": "Aktif Kullanıcılar", "kategori": "sistem"},
		{"id": "sistem_saglik", "baslik": "Sistem Sağlık", "kategori": "sistem"},
		{"id": "mail_sorgula", "baslik": "Mail Sorgula", "kategori": "iletisim"},
		{"id": "parametre_setleri", "baslik": "Parametre Setleri", "kategori": "konfigurasyon"},
		{"id": "paylasim_ara", "baslik": "Paylaşım Ara", "kategori": "paylasim", "varsayilan": true},
		{"id": "dinamik_bilesen_listele", "baslik": "Dinamik Bileşen Listele", "kategori": "bilesen", "varsayilan": true},
		{"id": "filitre_olustur", "baslik": "Filtre Oluştur", "kategori": "gelismis"},
		{"id": "hareket_toplu_islem", "baslik": "Toplu İşlem", "kategori": "gelismis"},
		{"id": "aggregate_sorgula", "baslik": "Aggregate Sorgu", "kategori": "gelismis"},

		{"id": "hareket_ekle", "baslik": "Kayıt Ekle", "kategori": "yazma"},
		{"id": "hareket_guncelle", "baslik": "Kayıt Güncelle", "kategori": "yazma"},
		{"id": "hareket_sil", "baslik": "Kayıt Sil", "kategori": "tehlikeli"},
		{"id": "kullanici_sorgula", "baslik": "Kullanıcı Sorgula", "kategori": "hassas"},
	}

	// Custom tool'lar da yetki panelinde görünsün — kişi bazlı atanabilir
	for _, t := range customToollarYukle() {
		baslik := t.Baslik
		if baslik == "" {
			baslik = t.Isim
		}
		liste = append(liste, fiber.Map{
			"id":         "custom_" + t.Isim,
			"baslik":     baslik + " ⚙",
			"kategori":   "ozel",
			"varsayilan": t.HerkeseAcik,
		})
	}

	return liste
}

func toolListeHandler(c fiber.Ctx) error {
	return c.JSON(TumToolIsimleri())
}
