package kok

import (
	"context"
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"regexp"
	FikoYTCtx "server/sistem/fikoyt_ctx"
	FikoYTHata "server/sistem/fikoyt_ctx/fikoyt_hata"
	FikoYTMap "server/sistem/fikoyt_map"
	fiko_mongo "server/sistem/fikoyt_mongo"
	"time"

	"github.com/gofiber/contrib/monitor"
	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/fiber/v3/middleware/session"
)

func KokRouting(app *fiber.App) {

	app.Get("/", func(c fiber.Ctx) error {
		// panic("asdasda")
		// user := c.Locals("FikoYT").(fiber.Map)
		session := c.Locals("session").(*session.Session)

		s, err := fiko_mongo.GetSessionData(session, "test")
		if err != nil {

		}

		return c.Status(200).JSON(s)
	})
	///
	app.Get("/metrics", monitor.New(monitor.Config{Title: "FikoYT Metrikler"}))

	///
	app.Post("/fapi/fikoyt.com.FikoYT.sistem.Uye.Ol", func(c fiber.Ctx) error {
		FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

		// if len(FikoYT.Dosyalar) > 0 {
		// 	FikoYT.Dosyalar[0].Kaydet()
		// 	FikoYT.Dosyalar[0].Isle()
		// }

		// Birden fazla hata örneği
		if FikoYT.Istek.Json["anlasma"] == false {
			FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataAnlasmaOnaylama().FikoYTHata)
		}
		///
		epostaPattern := `^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$`
		matched, _ := regexp.MatchString(epostaPattern, FikoYT.Istek.Json["ePosta"].(string))
		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

			return nil
		}

		///
		// FikoYT.Cevap.Sonuc = nil
		FikoYT.Cevap.AyarlaDurumKodu(200)

		FikoYT.Istek.Json["aktifDurum"] = "Mail Onayı Bekliyor"

		FikoYT.Istek.Json["parola"] = parolaSifrele(FikoYT.Istek.Json["parola"].(string))
		delete(FikoYT.Istek.Json, "parolaTekrar")

		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 epostaOnayKoduFonksiyonu(ad, soyad, kullaniciAdi string) string {
	// Bugün tarihine 1 gün ekleyelim
	a := time.Now().Add(24 * time.Hour)

	// Verileri birleştir
	dataToHash := ad + " " + soyad + kullaniciAdi + a.String()

	// Gizli anahtar (bu anahtar sizin tarafınızdan belirlenmeli)
	secretKey := []byte("FikoYT+1299")

	// HMAC-SHA256 kullanarak veri hashing
	hash := hmac.New(sha256.New, secretKey)
	hash.Write([]byte(dataToHash))
	hashedCode := hash.Sum(nil)

	// Hash kodu hex formatında döndürüyoruz
	return fmt.Sprintf("%x", hashedCode)
}

func parolaSifrele(parola string) string {
	// Verileri birleştir
	dataToHash := parola

	// Gizli anahtar (bu anahtar sizin tarafınızdan belirlenmeli)
	secretKey := []byte("FikoYT+1299")

	// HMAC-SHA256 kullanarak veri hashing
	hash := hmac.New(sha256.New, secretKey)
	hash.Write([]byte(dataToHash))
	hashedCode := hash.Sum(nil)

	// Hash kodu hex formatında döndürüyoruz
	return fmt.Sprintf("%x", hashedCode)
}

// HMAC ile Parola Doğrulama
func ParolaDogrula(parola, storedHash string) bool {
	// Gizli anahtar (bunu gerçek bir uygulamada gizli tutun)
	secretKey := []byte("FikoYT+1299")

	// Parolayı HMAC-SHA256 ile hash'le
	hash := hmac.New(sha256.New, secretKey)
	hash.Write([]byte(parola))
	calculatedHash := fmt.Sprintf("%x", hash.Sum(nil))

	// Hash'leri karşılaştır
	return storedHash == calculatedHash
}
