package admin_kullanicilar

import (
	"context"
	"regexp"
	FikoYTCtx "server/sistem/fikoyt_ctx"
	FikoYTHata "server/sistem/fikoyt_ctx/fikoyt_hata"
	FikoYTMap "server/sistem/fikoyt_map"

	"github.com/gofiber/fiber/v3"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func Init(app *fiber.App, api fiber.Router) {
	Api := api.Group("/kullanicilar")

	Api.Get("/", func(c fiber.Ctx) error {
		FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

		kullanicilar := FikoYT.Koleksiyon("goUyeler")

		// Hariç tutulacak alanlar
		projection := fiber.Map{
			"parola":         0,
			"epostaOnayKodu": 0,
			"anlasma":        0,
			"aktifDurum":     0,
		}

		opts := &options.FindOptions{
			Projection: projection,
		}

		cursor, err := kullanicilar.Find(context.TODO(), fiber.Map{}, opts)
		if err != nil {
			return c.JSON([]FikoYTMap.FikoYTMap{})
			// c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			// 	"error": "Veritabanı hatası: " + err.Error(),
			// })
		}
		defer cursor.Close(context.TODO())

		var liste []FikoYTMap.FikoYTMap
		if err := cursor.All(context.TODO(), &liste); err != nil {
			return c.JSON([]FikoYTMap.FikoYTMap{})
			// c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			// 	"error": "Veri çözümleme hatası: " + err.Error(),
			// })
		}

		FikoYT.AktifKullanici.OlayYolla("FikoYT.sistem.cihaz.bağlandı.toplamlar", FikoYT.AktifKullanici.AktifCihazlar())

		return c.JSON(FikoYT.AktifKullanici.Yetkiler)
	})

	Api.Post("/toplamlar", toplamlar)

	Api.Post("/liste", kullanicilar_liste)

	Api.Post("/ekle", kullanicilar_ekle)

	Api.Post("/sil", kullanicilar_sil)

	Api.Post("/sil-geri-al", kullanicilar_sil_geri_al)

}

func toplamlar(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

	uyeler := FikoYT.Koleksiyon("goUyeler")
	var snc_uyeler_toplam (int64) = 0
	snc_uyeler_toplam, _ = uyeler.CountDocuments(context.TODO(), fiber.Map{})
	///
	soketler := FikoYT.Koleksiyon("goSoketler")

	sayi, _ := soketler.Distinct(context.TODO(), "kullanici", fiber.Map{
		"kullanici": fiber.Map{"$ne": nil},
	})
	///
	var snc_sistem_kullanici_toplam (int64) = 0
	snc_sistem_kullanici_toplam, _ = uyeler.CountDocuments(context.TODO(), bson.M{
		"yetkiler": bson.M{
			"$in": bson.A{"Süper Yönetici"},
		},
		"uygulamalar": bson.M{"$in": bson.A{"Uyar Döküm"}},
	})
	///
	///
	var snc_deaktif_kullanici_toplam (int64) = 0
	snc_deaktif_kullanici_toplam, _ = uyeler.CountDocuments(context.TODO(), fiber.Map{
		"aktifDurum": fiber.Map{"$ne": "Aktif"},
	})
	///

	ssssayi, _ := soketler.CountDocuments(context.TODO(), fiber.Map{
		"aktifDurum": fiber.Map{"$ne": "Aktif"},
	})

	FikoYT.Cevap.AyarlaDurumKodu(200)

	FikoYT.Cevap.Sonuc = fiber.Map{"kullanici": snc_uyeler_toplam, "aktif_kullanici": len(sayi), "deaktif_kullanici": snc_deaktif_kullanici_toplam, "sistem_kullanici": snc_sistem_kullanici_toplam, "soket_sayisi": ssssayi}

	return c.JSON(fiber.Map{"kullanici": snc_uyeler_toplam, "aktif_kullanici": len(sayi), "deaktif_kullanici": snc_deaktif_kullanici_toplam, "sistem_kullanici": snc_sistem_kullanici_toplam, "soket_sayisi": ssssayi})
}

func kullanicilar_liste(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

	// objectIDStr := FikoYT.Sezon.Get("aktifKullaniciID")

	// if objectIDStr == "" {
	// 	return nil
	// }

	// if objectIDStr == nil {
	// 	return nil
	// }

	// objectID, err := primitive.ObjectIDFromHex(objectIDStr.(string))
	// if err != nil {
	// 	return nil
	// }

	goUyeler := FikoYT.Koleksiyon("goUyeler")

	cursor, err := goUyeler.Find(context.TODO(), fiber.Map{ /*"silindi": fiber.Map{ "$ne": true }*/ }, &options.FindOptions{
		Projection: fiber.Map{
			"parola":         0,
			"epostaOnayKodu": 0,
			"anlasma":        0,
			"aktifDurum":     0,
		},
	})
	if err != nil {
		return nil
	}
	defer cursor.Close(context.TODO())

	var uyeler []FikoYTMap.FikoYTMap
	if err := cursor.All(context.TODO(), &uyeler); err != nil {
		return c.JSON([]FikoYTMap.FikoYTMap{})
	}

	if len(uyeler) == 0 {
		return c.JSON([]FikoYTMap.FikoYTMap{})
	}

	///
	FikoYT.Cevap.AyarlaDurumKodu(200)

	FikoYT.Cevap.Sonuc = uyeler
	// fmt.Println(FikoYT.Sezon.Get("aktifKullaniciID").(string))

	return c.Status(200).JSON(uyeler)
}

func kullanicilar_ekle(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

	// if len(FikoYT.Istek.Dosyalar) > 0 {
	// 	dosya := FikoYT.Istek.Dosyalar[0]
	// 	dosya.Kaydet()
	// 	dosya.Isle()
	// 	dosya.KaydetGridFs(fiber.Map{"test": "deneme"})
	// 	dosya.TemizleDosyalar()
	// }

	// if true {
	// 	return nil
	// }
	bosalanlar := FikoYT.Istek.Json.BosAlanlar()
	if len(bosalanlar) > 0 {
		for i := 0; i < len(bosalanlar); i++ {
			bosalan := bosalanlar[i]
			FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataTurHatasi(bosalan).FikoYTHata)
		}

		// FikoYT.Cevap.AyarlaDurumKodu(499)
		// FikoYT.Cevap.Durum.Hata = true

		// return nil
	}

	// Birden fazla hata örneği
	if FikoYT.Istek.Json["anlasma"] == false && FikoYT.Istek.Json["anlasmaOnaylama"] == nil {
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataAnlasmaOnaylama().FikoYTHata)
	}

	///
	rawEposta, varMi := FikoYT.Istek.Json["ePosta"]
	if varMi && rawEposta != nil {
		eposta, ok := rawEposta.(string)
		if ok && eposta != "" {
			epostaPattern := `^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$`
			matched, _ := regexp.MatchString(epostaPattern, eposta)
			if !matched {
				FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataTurHatasi("E-Posta").FikoYTHata)
			}
		}
	}

	///

	if FikoYT.Istek.Json["parola"] != FikoYT.Istek.Json["parolaTekrar"] {
		if FikoYT.Istek.Json["parola"] != "" || FikoYT.Istek.Json["parolaTekrar"] != "" {
			FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataAyniDegilHatasi("Parola", "Parola Tekrar", nil).FikoYTHata)
		}
	}

	///
	kullaniciAdi := FikoYT.Istek.Json["kullaniciAdi"]
	goUyeler := FikoYT.Koleksiyon("goUyeler")
	if kullaniciAdi != nil {
		var kytUye FikoYTMap.FikoYTMap
		_ = goUyeler.FindOne(context.TODO(), fiber.Map{"kullaniciAdi": kullaniciAdi}).Decode(&kytUye)
		if kytUye != nil {
			FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKullaniciMevcutHatasi(kullaniciAdi.(string), nil).FikoYTHata)
		}
	}

	///
	eposta := FikoYT.Istek.Json["ePosta"]
	if eposta != nil {
		var kytEposta FikoYTMap.FikoYTMap
		_ = goUyeler.FindOne(context.TODO(), fiber.Map{"ePosta": eposta}).Decode(&kytEposta)
		if kytEposta != nil {
			FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataEPostaMevcutHatasi(eposta.(string), nil).FikoYTHata)
		}
	}
	///

	if len(FikoYT.Cevap.Durum.Hatalar) > 0 {
		FikoYT.Cevap.AyarlaDurumKodu(499)
		FikoYT.Cevap.Durum.Hata = true
		// FikoYT.Cevap.Sonuc = false
		return nil
	}

	///
	// FikoYT.Cevap.Sonuc = nil
	FikoYT.Cevap.AyarlaDurumKodu(200)

	FikoYT.Istek.Json["aktifDurum"] = "Aktif"

	FikoYT.Istek.Json["parola"] = ParolaSifrele(FikoYT.Istek.Json["parola"].(string))
	delete(FikoYT.Istek.Json, "parolaTekrar")
	// fmt.Println(FikoYT.Istek.Json)
	epostaOnayKodu := EpostaOnayKoduFonksiyonu(FikoYT.Istek.Json["isim"].(string), FikoYT.Istek.Json["soyIsim"].(string), FikoYT.Istek.Json["kullaniciAdi"].(string))

	FikoYT.Istek.Json["epostaOnayKodu"] = epostaOnayKodu

	rslt, _ :=
		goUyeler.InsertOne(context.TODO(), FikoYT.Istek.Json)

	if len(FikoYT.Istek.Dosyalar) > 0 {
		dosya := FikoYT.Istek.Dosyalar[0]
		dosya.Kaydet()
		dosya.Isle()
		dosya.KaydetGridFs(fiber.Map{"yol": "./profilResimleri", "kid": rslt.InsertedID})

		dosya.TemizleDosyalar()

	}
	FikoYT.Cevap.Sonuc = true

	return c.Status(200).JSON(true)
}

/**/

func kullanicilar_sil(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

	// Süper Yönetici yetkisine sahip değilse, silme işlemi gerçekleştirilmez.
	// Sistemde sadece Süper Yönetici yetkisine sahip olan kullanıcılar, diğer kullanıcıları silebilir.
	if !FikoYT.AktifKullanici.YetkiVarmi("Süper Yönetici") {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Yetersiz Yetki"
		FikoYT.Cevap.AyarlaDurumKodu(502)
		return nil
	}

	kid := FikoYT.Istek.Json["kid"]

	if kid == nil {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Kullanıcı Bulunamadı"
		FikoYT.Cevap.AyarlaDurumKodu(404)
		return nil
	}

	if kid == "" {
		return nil
	}

	// fmt.Println(kid == FikoYT.AktifKullanici.Id)
	// fmt.Println(kid)
	// fmt.Println(FikoYT.AktifKullanici.Id)

	if kid == FikoYT.AktifKullanici.Id {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Kendinizi Silemezsiniz"
		FikoYT.Cevap.AyarlaDurumKodu(404)

		return nil
	}

	goUyeler := FikoYT.Koleksiyon("goUyeler")

	var kytUye FikoYTMap.FikoYTMap
	err := goUyeler.FindOne(
		context.TODO(),
		fiber.Map{"_id": kid},
		&options.FindOneOptions{
			Projection: fiber.Map{
				"parola":         0,
				"epostaOnayKodu": 0,
				"anlasma":        0,
				"aktifDurum":     0,
			},
		},
	).Decode(&kytUye)

	if err != nil {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Kullanıcı Bulunamadı"
		FikoYT.Cevap.AyarlaDurumKodu(404)
		return nil
	}
	kytUye["silindi"] = true
	goUyeler.UpdateOne(c.Context(), fiber.Map{"_id": kid}, fiber.Map{"$set": kytUye})

	return nil
}

/**/

func kullanicilar_sil_geri_al(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

	// Süper Yönetici yetkisine sahip değilse, silme işlemi gerçekleştirilmez.
	// Sistemde sadece Süper Yönetici yetkisine sahip olan kullanıcılar, diğer kullanıcıları silebilir.
	if !FikoYT.AktifKullanici.YetkiVarmi("Süper Yönetici") {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Yetersiz Yetki"
		FikoYT.Cevap.AyarlaDurumKodu(502)
		return nil
	}

	kid := FikoYT.Istek.Json["kid"]

	if kid == nil {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Kullanıcı Bulunamadı"
		FikoYT.Cevap.AyarlaDurumKodu(404)
		return nil
	}

	if kid == "" {
		return nil
	}

	// fmt.Println(kid == FikoYT.AktifKullanici.Id)
	// fmt.Println(kid)
	// fmt.Println(FikoYT.AktifKullanici.Id)

	if kid == FikoYT.AktifKullanici.Id {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Kendinizi Silemezsiniz"
		FikoYT.Cevap.AyarlaDurumKodu(404)

		return nil
	}

	goUyeler := FikoYT.Koleksiyon("goUyeler")

	var kytUye FikoYTMap.FikoYTMap
	err := goUyeler.FindOne(
		context.TODO(),
		fiber.Map{"_id": kid},
		&options.FindOneOptions{
			Projection: fiber.Map{
				"parola":         0,
				"epostaOnayKodu": 0,
				"anlasma":        0,
				"aktifDurum":     0,
			},
		},
	).Decode(&kytUye)

	if err != nil {
		FikoYT.Cevap.Durum.Hata = true
		FikoYT.Cevap.Durum.Mesaj = "Kullanıcı Bulunamadı"
		FikoYT.Cevap.AyarlaDurumKodu(404)
		return nil
	}
	kytUye["silindi"] = false
	goUyeler.UpdateOne(c.Context(), fiber.Map{"_id": kid}, fiber.Map{"$set": kytUye})

	return nil
}
