package fiko_socket_io

import (
	"fmt"
	"reflect"
	FikoYTMap "server/sistem/fikoyt_map"
	"time"

	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/fiber/v3/middleware/adaptor"
	EIOLog "github.com/zishang520/engine.io/v2/log"
	"github.com/zishang520/engine.io/v2/types"
	"github.com/zishang520/socket.io/v2/socket"
)

var FikoSocketIo *socket.Server

func Ayarla(app *fiber.App) {
	EIOLog.DEBUG = true
	socketioSettings := socket.DefaultServerOptions()
	socketioSettings.SetServeClient(true)
	// c.SetConnectionStateRecovery(&socket.ConnectionStateRecovery{})
	socketioSettings.SetAllowEIO3(true)
	socketioSettings.SetAllowUpgrades(true)
	socketioSettings.SetTransports(types.NewSet("polling", "websocket", "webtransport"))

	socketioSettings.SetPingInterval(2000 * time.Millisecond)
	socketioSettings.SetPingTimeout(2000 * time.Millisecond)
	socketioSettings.SetMaxHttpBufferSize(1000000)
	socketioSettings.SetConnectTimeout(3000 * time.Millisecond)
	socketioSettings.SetCors(&types.Cors{
		Origin:      "*",
		Credentials: true,
	})
	FikoSocketIo = socket.NewServer(nil, nil)

	FikoSocketIo.On("connection", func(clients ...interface{}) {
		client := clients[0].(*socket.Socket)

		// fmt.Println(clients...)

		ClientBaglandi(client)
	})

	//
	app.Get("/socket.io/", adaptor.HTTPHandler(FikoSocketIo.ServeHandler(socketioSettings)))
	app.Post("/socket.io/", adaptor.HTTPHandler(FikoSocketIo.ServeHandler(socketioSettings)))

	// FikoSocketIo.Use(func(socket *socket.Socket, next func(*socket.ExtendedError)) {
	// 	fmt.Println(socket.Request().Headers())
	// 	next(nil)
	// })
	// FikoSocketIo.FetchSockets()
}

// hasKey kontrol fonksiyonu
func hasKey(data interface{}, key string) bool {
	if reflect.TypeOf(data).Kind() == reflect.Map {
		return reflect.ValueOf(data).MapIndex(reflect.ValueOf(key)).IsValid()
	}
	return false
}

func ClientBaglandi(client *socket.Socket) {
	client.Use(func(a []any, next func(error)) {
		//  delete(a[0].(map[string]interface{}), "deviceUuid")

		// fmt.Println("Burada----->", a[1])
		// if reflect.TypeOf(a[len(a)-2]).Kind() == reflect.Map {
		// 	if hasKey(a[1], "FikoYT") {
		// 		fmt.Println("Burada----->", a[1], len(a))

		if len(a) == 0 {
			a = append(a, FikoYTMap.FikoYTMap{"FikoYT": FikoYTMap.FikoYTMap{"kid": nil, "cihaz_kimlik": nil}})
			a = append(a, nil)
		} else if len(a) == 1 {
			a = append(a, FikoYTMap.FikoYTMap{"FikoYT": FikoYTMap.FikoYTMap{"kid": nil, "cihaz_kimlik": nil}})
			a = append(a, nil)
		} else if len(a) == 2 {
			a = append(a, FikoYTMap.FikoYTMap{"FikoYT": FikoYTMap.FikoYTMap{"kid": nil, "cihaz_kimlik": nil}})
			a = append(a, nil)
		} else if reflect.TypeOf(a[len(a)-2]).Kind() != reflect.Map || !reflect.ValueOf(a[len(a)-2]).MapIndex(reflect.ValueOf("FikoYT")).IsValid() {
			// Eğer sondan ikinci eleman geçerli bir "FikoYT" anahtarı içeren bir harita değilse
			if reflect.TypeOf(a[len(a)-1]).Kind() != reflect.Func {
				// Son eleman fonksiyon değilse, FikoYT haritasını ekle
				a = append(a, FikoYTMap.FikoYTMap{"FikoYT": FikoYTMap.FikoYTMap{"kid": nil, "cihaz_kimlik": nil}})
				a = append(a, nil)
			} else {
				// Son eleman fonksiyon ise, FikoYT haritasını fonksiyon öncesine ekle
				a = append(a[:len(a)-1], append([]any{FikoYTMap.FikoYTMap{"FikoYT": FikoYTMap.FikoYTMap{"kid": nil, "cihaz_kimlik": nil}}}, a[len(a)-1:]...)...)
			}
			fmt.Println("Burada----->", a, len(a))
		}
		// 	//
		// 	// }
		// }

		next(nil)
	})
}
