package kokDB

import (
	"context"
	"fmt"
	FikoYTCtx "server/sistem/fikoyt_ctx"
	FikoYTMap "server/sistem/fikoyt_map"

	"github.com/gofiber/fiber/v3"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func convertStagesToPipeline(stages []interface{}) (mongo.Pipeline, error) {
	var pipeline mongo.Pipeline
	for _, stage := range stages {
		var doc map[string]interface{}

		switch s := stage.(type) {
		case map[string]interface{}:
			doc = s
		case FikoYTMap.FikoYTMap:
			doc = map[string]interface{}(s) // Tip dönüşümü
		default:
			return nil, fmt.Errorf("stage tipi map[string]interface{} değil, %T", stage)
		}

		bsonDoc := bson.D{}
		for k, v := range doc {
			bsonDoc = append(bsonDoc, bson.E{Key: k, Value: v})
		}
		pipeline = append(pipeline, bsonDoc)
	}
	return pipeline, nil
}

func fikoyt_sistem_db_agregate(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	db := c.Params("db")

	koleksiyon := FikoYT.Koleksiyon(db)
	// var dbMap FikoYTMap.FikoYTMap
	ctx := context.TODO()

	var results []bson.M

	FikoYT.Istek.Json.IsleObjectId()

	aggrRaw, ok := FikoYT.Istek.Json["aggregate"]
	if !ok {
		return c.Status(200).JSON(FikoYTMap.FikoYTMap{})
	}

	aggrSlice, ok := aggrRaw.([]interface{})
	if !ok {
		return c.Status(200).JSON(FikoYTMap.FikoYTMap{})
	}

	pipeline, err := convertStagesToPipeline(aggrSlice)
	if err != nil {
		fmt.Println("Pipeline dönüşüm hatası:", err)
		return c.Status(200).JSON(FikoYTMap.FikoYTMap{})
	}

	cursor, err := koleksiyon.Aggregate(ctx, pipeline, &options.AggregateOptions{})
	// Varsayılanlar
	if err != nil {

		return nil
	}

	defer cursor.Close(ctx)

	cursor.All(ctx, &results)

	// prettyJson, _ := json.MarshalIndent(pipeline, "", "  ")
	// fmt.Println("Pipeline JSON:", string(prettyJson))

	// DB'den gelen sonuç (örnek)
	FikoYT.Cevap.Sonuc = results

	return c.JSON(results)
}

func fikoyt_sistem_db_ekle(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	db := c.Params("db")

	koleksiyon := FikoYT.Koleksiyon(db)

	// var dbMap FikoYTMap.FikoYTMap
	// ctx := context.TODO()

	FikoYT.Istek.Json.IsleObjectId()
	// koleksiyon.CountDocuments(context.TODO(), FikoYTMap.FikoYTMap{})
	//------------------------------------->

	var sonuclar interface{} = nil
	var err interface{} = nil

	switch FikoYT.Istek.JsonTip {
	case "Object":
		sonuclar, err = FikoYT.EkleYadaGuncelle(koleksiyon, FikoYT.Istek.Json)
		if err != nil {
			fmt.Println(err)
			sonuclar = err
		}
	case "Array":
		sonuclar, err = FikoYT.EkleYadaGuncelle(koleksiyon, FikoYT.Istek.JsonArray)
		if err != nil {
			fmt.Println(err)
			sonuclar = err
		}
	default:

	}
	// rslt, err := koleksiyon.InsertOne(ctx, FikoYT.Istek.Json)

	//------------------------------------->
	if len(FikoYT.Istek.Dosyalar) > 0 {
		dosya := FikoYT.Istek.Dosyalar[0]
		dosya.Kaydet()
		dosya.Isle()
		dosya.KaydetGridFs(fiber.Map{"yol": "./hareketler/" + db, "kid": FikoYT.AktifKullanici.Id})

		dosya.TemizleDosyalar()

	}

	// DB'den gelen sonuç (örnek)
	FikoYT.Cevap.Sonuc = sonuclar

	return c.JSON(sonuclar)
}

func fikoyt_sistem_db_sil(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	db := c.Params("db")

	koleksiyon := FikoYT.Koleksiyon(db)
	ctx := context.TODO()

	// Gelen filtreleri işle
	FikoYT.Istek.Json.IsleObjectId()

	// Silme işlemi sonucu
	var sonuc *mongo.DeleteResult
	var err error

	switch FikoYT.Istek.JsonTip {
	case "Object":
		sonuc, err = koleksiyon.DeleteMany(ctx, FikoYT.Istek.Json)
	case "Array":
		// Array ile gelen filtrelerin her biri için silme işlemi yapılır
		var toplamSilinen int64 = 0
		for _, filtre := range FikoYT.Istek.JsonArray {
			if m, ok := filtre.(FikoYTMap.FikoYTMap); ok {
				m.IsleObjectId()
				if r, e := koleksiyon.DeleteMany(ctx, m); e == nil {
					toplamSilinen += r.DeletedCount
				}
			}
		}
		// Custom response için sahte DeleteResult döndürüyoruz
		sonuc = &mongo.DeleteResult{DeletedCount: toplamSilinen}
	default:
		return c.Status(400).JSON(fiber.Map{"hata": "Geçersiz JsonTip"})
	}

	if err != nil {
		fmt.Println("Silme hatası:", err)
		return c.Status(500).JSON(fiber.Map{"hata": err.Error()})
	}

	FikoYT.Cevap.Sonuc = sonuc
	return c.JSON(sonuc)
}
