package fiko_mongo

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/fiber/v3/middleware/session"
	"github.com/gofiber/storage/mongodb"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var Client *mongo.Client
var Session *session.Store
var MongoStore *mongodb.Storage
var SessionConfig session.Config

func Init(app *fiber.App) {
	// MongoDB bağlantı URL'si
	databaseURL := "mongodb://127.0.0.1:8001/"
	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)

	// MongoDB bağlantısını kuruyoruz
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(databaseURL))
	if err != nil {
		log.Fatal(err)
	}

	// Bağlantıyı global Client değişkenine atıyoruz
	Client = client
	// log.Println("MongoDB'ye başarıyla bağlanıldı")
	setSessionMotor(app)
	setRoutes(app)

}

// GetMongoDBClient fonksiyonu mevcut MongoDB bağlantısını döndürür
func GetMongoDBClient() *mongo.Client {
	return Client
}

func GetSession() *session.Store {
	return Session
}

func setSessionMotor(_ *fiber.App) { // Session middleware
	// store := fiko_mongo_store.NewMongoStorage(GetMongoDBClient(), "fikoyt", "go_sessions")
	MongoStore = mongodb.New(mongodb.Config{
		Host:       "127.0.0.1",
		Port:       8001,
		Database:   "fikoyt",
		Collection: "go_sessions",
		Reset:      false,
	})

	// Session middleware yapılandırması
	SessionConfig = session.Config{
		Storage: MongoStore, CookieSecure: true, CookieHTTPOnly: true, CookieSameSite: "lax", Expiration: 24 * time.Hour, KeyLookup: "cookie:sid",
	}
	Session = session.New(SessionConfig)

}

func setRoutes(app *fiber.App) {
	app.Get("/fikomongo", func(c fiber.Ctx) error {
		ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
		// MongoDB koleksiyonundan veri almak
		collection := GetMongoDBClient().Database("fikoyt").Collection("hareketler")

		// Find sorgusuna limit ve skip parametrelerini ekleyerek verileri alıyoruz
		findOptions := options.Find()
		findOptions.SetLimit(2)
		findOptions.SetSkip(0)

		cursor, err := collection.Find(ctx, bson.D{}, findOptions)
		if err != nil {
			log.Fatal(err)
		}
		defer cursor.Close(ctx)

		// Verileri tutacak bir dilim
		var results []bson.M
		cursor.All(ctx, &results)

		// Eğer cursor'dan çıkarken hata varsa
		if err := cursor.Err(); err != nil {
			log.Fatal(err)
		}
		/////////////////////////////////////
		s, err := GetSession().Get(c)
		if err != nil {
			return err
		}

		//
		data := map[string]interface{}{"power": 10, "voltage": 5, "current": 2}

		// Map'i JSON formatına dönüştürüyoruz
		// jsonData, err := json.Marshal(results)
		// if err != nil {
		// 	return err
		// }

		s.Set("test", data)
		if err := s.Save(); err != nil {
			fmt.Println(err)
		}
		defer s.Save()
		// defer s.Destroy()

		// fmt.Println(results)
		// JSON verisini döndür
		return c.Status(200).JSON(s.Get("test"))
	})
}

// func Init(app *fiber.App) {
// 	// MongoDB bağlantı URL'si
// 	databaseURL := "mongodb://127.0.0.1:8001/"
// 	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
// 	client, err := mongo.Connect(ctx, options.Client().ApplyURI(databaseURL))
// 	if err != nil {
// 		log.Fatal(err)
// 	}

// 	// MongoDB koleksiyonundan veri almak
// 	collection := client.Database("fikoyt").Collection("hareketler")

// 	// Find sorgusuna limit ve skip parametrelerini ekleyerek verileri alıyoruz
// 	findOptions := options.Find()
// 	findOptions.SetLimit(2)
// 	findOptions.SetSkip(0)

// 	cursor, err := collection.Find(ctx, bson.D{}, findOptions)
// 	if err != nil {
// 		log.Fatal(err)
// 	}
// 	defer cursor.Close(ctx)

// 	// Verileri tutacak bir dilim
// 	var results []bson.M
// 	cursor.All(ctx, &results)

// 	// Eğer cursor'dan çıkarken hata varsa
// 	if err := cursor.Err(); err != nil {
// 		log.Fatal(err)
// 	}

// 	// Fiber route: /fikomongo
// 	app.Get("/fikomongo", func(c *fiber.Ctx) error {
// 		// JSON verisini döndür
// 		return c.Status(200).JSON(results)
// 	})
// }
