package kok

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"io"
	"mime/multipart"
	"net/http"
	"time"
	uyar "server/apps/uyar_dokum/uyar"
	FikoYTCtx "server/sistem/fikoyt_ctx"
	FikoYTHata "server/sistem/fikoyt_ctx/fikoyt_hata"
	fiko_mongo "server/sistem/fikoyt_mongo"
	"server/sistem/push"

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

func NoCacheMiddleware(c fiber.Ctx) error {
	c.Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0")
	c.Set("Pragma", "no-cache")
	c.Set("Expires", "0")
	return c.Next()
}

func KokRouting(app *fiber.App) {

	app.Use("/", static.New("./statik"))

	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.Get("/eklenti/:anahtar/:surum/plugin.exe", eklentiDosyaHandler)
	app.Get("/bridge/manifest.json", bridgeManifestHandler)
	app.Get("/bridge/:surum/bridge.exe", bridgeExeHandler)
	fapiv1 := app.Group("/fapiv1")

	fapiv1.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"https://fikoyt.com", "https://www.fikoyt.com", "https://fikoyt.com:443", "https://www.fikoyt.com:443", "https://fikoyt.com:444", "https://fikoyt.com:446", "https://fikoyt.com:449", "https://fikoyt.com:9000", "https://www.fikoyt.com:9000", "https://fikoyt.com:4200", "https://localhost:4200", "http://localhost:4200", "http://localhost:4201", "http://localhost:4400", "https://fikoyt:4200"},                 // String dilimi olarak belirt
		AllowMethods:     []string{"GET", "POST", "HEAD", "PUT", "DELETE", "PATCH", "OPTIONS", "TRACE"}, // İzin verilen HTTP metodları
		AllowHeaders:     []string{"*", "Content-Type", "Authorization", "Mode", "cihaz_kimlik", "cihaz_bilgi", "uygulama", "access-control-allow-origin", "access-control-allow-credentials", "cihaz_tipi", "Content-Type", "X-Requested-With", "Fsid"},
		AllowCredentials: true, AllowPrivateNetwork: true, ExposeHeaders: []string{"*", "Content-Length", "Content-Type", "X-Requested-With"},
	}))

	fapiv1.Post("/fikoyt.com.test", fikoyt_sistem_test)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.uye.ol", fikoyt_sistem_uye_ol)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.admin.uye.ekle", fikoyt_sistem_admin_uye_ekle)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.sifre.degistir", fikoyt_sistem_sifre_degistir)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.kaydet", fikoyt_sistem_bridge_cihaz_kaydet)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.listele", fikoyt_sistem_bridge_cihaz_listele)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.adi-degistir", fikoyt_sistem_bridge_cihaz_adi_degistir)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.izin-iste", fikoyt_sistem_bridge_cihaz_izin_iste)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.izin-kapat", fikoyt_sistem_bridge_cihaz_izin_kapat)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.izin-ver", fikoyt_sistem_bridge_cihaz_izin_ver)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.senkron", fikoyt_sistem_bridge_cihaz_senkron)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.karar", fikoyt_sistem_bridge_cihaz_karar)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.izin-bildir", fikoyt_sistem_bridge_cihaz_izin_bildir)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.abone-token", fikoyt_sistem_bridge_abone_token)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.loglar", fikoyt_sistem_bridge_cihaz_loglar)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.eklenti.katalog", fikoyt_sistem_bridge_eklenti_katalog)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.eklenti.paket", fikoyt_sistem_bridge_eklenti_paket)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.eklenti-istegi", fikoyt_sistem_bridge_cihaz_eklenti_istegi)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.kaldir", fikoyt_sistem_bridge_cihaz_kaldir)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.surec-istegi", fikoyt_sistem_bridge_cihaz_surec_istegi)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.guncelle-istegi", fikoyt_sistem_bridge_cihaz_guncelle_istegi)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.bridge.cihaz.indirme-oturumu", fikoyt_sistem_bridge_cihaz_indirme_oturumu)
	fapiv1.Get("/fikoyt.com.FikoYT.sistem.bridge.indir/:id", bridgeIndirHandler, NoCacheMiddleware)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.giris.yap", fikoyt_sistem_giris_yap)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.cikis.yap", fikoyt_sistem_cikis_yap)

	fapiv1.Get("/fikoyt.com.FikoYT.sistem.dosyalar.:id.resim", fikoyt_sistem_dosyalar_id_resim, NoCacheMiddleware)
	fapiv1.Get("/fikoyt.com.FikoYT.sistem.dosyalar.:id.dosya", fikoyt_sistem_dosyalar_id, NoCacheMiddleware)
	fapiv1.Get("/fikoyt.com.FikoYT.sistem.dosyalar.:id.dosyaThumb", fikoyt_sistem_dosyalar_thumb, NoCacheMiddleware)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.dosyalar.:id.poster.degistir", fikoyt_sistem_dosyalar_poster_degistir)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.anket.oy", fikoyt_sistem_anket_oy)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.kisi.adlari", fikoyt_sistem_kisi_adlari)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.dosyalar.:id.dosya.sil", fikoyt_sistem_dosyalar_sil)

	fapiv1.Get("/fikoyt.com.FikoYT.sistem.kullanici.:kid.profilResmi", fikoyt_sistem_kullanici_profil_resmi, NoCacheMiddleware)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.kullanici.:kid.profilResmi.degistir", fikoyt_sistem_kullanici_profil_resmi_degistir)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.kullanici.:kid.profilResmi.sil", fikoyt_sistem_kullanici_profil_resmi_sil)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.kullanici.:kid.parola.degistir", fikoyt_sistem_kullanici_parola_degistir)

	fapiv1.Post("/fikoyt.com.FikoYT.sistem.aktif-kullanici.bilgi", fikoyt_sistem_aktif_kullanici_bilgi)

	fapiv1.Get("/fikoyt.com.FikoYT.sistem.aktif-kullanici.profilResmi", fikoyt_sistem_aktif_kullanici_profil_resmi, NoCacheMiddleware)

	fapiv1.Get("/fikoyt.com.FikoYT.sistem.windows.guncelleme.bilgi", fikoyt_sistem_bilgi_guncelleme)

	// n8n Webhook Proxy - CORS sorununu aşmak için
	fapiv1.Post("/n8n-bildirim", n8nBildirimProxy)

	// Whisper STT (Speech-to-Text) Proxy
	fapiv1.Post("/whisper/transkript", whisperTranskriptProxy)

	// Bildirim Sistemi
	uyar.BildirimRouting(fapiv1)

	// Tetikleyici Sistemi
	uyar.TetikleyiciRouting(fapiv1)

	// Mail Gonderme Servisi
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.mail.gonder", mailGonderHandler)

	// Push Bildirim Servisi
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.push.vapid-public-key", pushVapidPublicKeyHandler)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.push.abonelik-kaydet", pushAbonelikKaydetHandler)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.push.abonelik-sil", pushAbonelikSilHandler)
	fapiv1.Post("/fikoyt.com.FikoYT.sistem.push.gonder", pushGonderHandler)
}

func mailGonderHandler(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)

	if FikoYT.AktifKullanici == nil {
		FikoYT.Cevap.AyarlaDurumKodu(401)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Oturum gerekli", nil).FikoYTHata)
		return nil
	}

	alici, _ := FikoYT.Istek.Json["alici"].(string)
	konu, _ := FikoYT.Istek.Json["konu"].(string)
	icerik, _ := FikoYT.Istek.Json["icerik"].(string)

	if alici == "" || konu == "" {
		FikoYT.Cevap.AyarlaDurumKodu(400)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Alıcı ve konu zorunlu", nil).FikoYTHata)
		return nil
	}

	err := FikoYT.Mail.Gonder(alici, konu, icerik)
	if err != nil {
		FikoYT.Cevap.Sonuc = fiber.Map{"basarili": false, "hata": err.Error()}
	} else {
		FikoYT.Cevap.Sonuc = fiber.Map{"basarili": true}
	}
	return nil
}

// whisperTranskriptProxy - Whisper STT servisine ses dosyası gönderir (FikoYTCtx uyumlu)
func whisperTranskriptProxy(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	whisperURL := "http://fikoyt-whisper:8000/v1/audio/transcriptions"

	// Multipart form verisini oku
	form, err := c.MultipartForm()
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(400)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Multipart form okunamadı", nil).FikoYTHata)
		return nil
	}

	dosyalar := form.File["file"]
	if len(dosyalar) == 0 {
		FikoYT.Cevap.AyarlaDurumKodu(400)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Ses dosyası bulunamadı", nil).FikoYTHata)
		return nil
	}

	dosya := dosyalar[0]
	src, err := dosya.Open()
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Dosya açılamadı", nil).FikoYTHata)
		return nil
	}
	defer src.Close()

	// Multipart body oluştur
	var buf bytes.Buffer
	writer := multipart.NewWriter(&buf)

	// Ses dosyasını ekle
	part, err := writer.CreateFormFile("file", dosya.Filename)
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Form oluşturulamadı", nil).FikoYTHata)
		return nil
	}
	io.Copy(part, src)

	// Model parametresi
	writer.WriteField("model", "Systran/faster-whisper-medium")

	// Dil (varsa)
	dil := c.FormValue("language", "")
	if dil != "" {
		writer.WriteField("language", dil)
	}

	// verbose_json: segment timestamp'leri ile birlikte döner
	writer.WriteField("response_format", "verbose_json")

	writer.Close()

	// Whisper servisine POST
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr, Timeout: 120 * time.Second}

	req, err := http.NewRequest("POST", whisperURL, &buf)
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("İstek oluşturulamadı", nil).FikoYTHata)
		return nil
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, err := client.Do(req)
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Whisper servisine bağlanılamadı: "+err.Error(), nil).FikoYTHata)
		return nil
	}
	defer resp.Body.Close()

	respBody, _ := io.ReadAll(resp.Body)

	// Whisper yanıtını parse et
	var whisperSonuc interface{}
	json.Unmarshal(respBody, &whisperSonuc)

	FikoYT.Cevap.AyarlaDurumKodu(200)
	FikoYT.Cevap.Sonuc = whisperSonuc

	return c.Status(200).JSON(whisperSonuc)
}

func pushVapidPublicKeyHandler(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	key, err := FikoYT.Push.VapidPublicKey()
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("VAPID key alınamadı: "+err.Error(), nil).FikoYTHata)
		return nil
	}
	FikoYT.Cevap.Sonuc = fiber.Map{"vapidPublicKey": key}
	return nil
}

func pushAbonelikKaydetHandler(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	if FikoYT.AktifKullanici == nil {
		FikoYT.Cevap.AyarlaDurumKodu(401)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Oturum gerekli", nil).FikoYTHata)
		return nil
	}

	var abonelik push.PushAbonelik
	endpoint, _ := FikoYT.Istek.Json["endpoint"].(string)
	keys, _ := FikoYT.Istek.Json["keys"].(map[string]interface{})
	if endpoint == "" || keys == nil {
		FikoYT.Cevap.AyarlaDurumKodu(400)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Geçersiz abonelik verisi", nil).FikoYTHata)
		return nil
	}
	abonelik.Endpoint = endpoint
	abonelik.Keys.P256dh, _ = keys["p256dh"].(string)
	abonelik.Keys.Auth, _ = keys["auth"].(string)

	kullaniciId := FikoYT.AktifKullanici.Id
	err := FikoYT.Push.AbonelikKaydet(kullaniciId, abonelik)
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Abonelik kaydedilemedi: "+err.Error(), nil).FikoYTHata)
		return nil
	}
	FikoYT.Cevap.Sonuc = fiber.Map{"basarili": true}
	return nil
}

func pushAbonelikSilHandler(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	if FikoYT.AktifKullanici == nil {
		FikoYT.Cevap.AyarlaDurumKodu(401)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Oturum gerekli", nil).FikoYTHata)
		return nil
	}
	endpoint, _ := FikoYT.Istek.Json["endpoint"].(string)
	if endpoint == "" {
		FikoYT.Cevap.AyarlaDurumKodu(400)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Endpoint gerekli", nil).FikoYTHata)
		return nil
	}
	kullaniciId := FikoYT.AktifKullanici.Id
	err := FikoYT.Push.AbonelikSil(kullaniciId, endpoint)
	if err != nil {
		FikoYT.Cevap.AyarlaDurumKodu(500)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Abonelik silinemedi: "+err.Error(), nil).FikoYTHata)
		return nil
	}
	FikoYT.Cevap.Sonuc = fiber.Map{"basarili": true}
	return nil
}

func pushGonderHandler(c fiber.Ctx) error {
	FikoYT := c.Locals("FikoYTCtx").(*FikoYTCtx.FikoYTCtx)
	if FikoYT.AktifKullanici == nil {
		FikoYT.Cevap.AyarlaDurumKodu(401)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("Oturum gerekli", nil).FikoYTHata)
		return nil
	}
	aliciId, _ := FikoYT.Istek.Json["aliciId"].(string)
	baslik, _ := FikoYT.Istek.Json["baslik"].(string)
	mesaj, _ := FikoYT.Istek.Json["mesaj"].(string)
	url, _ := FikoYT.Istek.Json["url"].(string)
	if aliciId == "" || baslik == "" {
		FikoYT.Cevap.AyarlaDurumKodu(400)
		FikoYT.Cevap.Durum.Hatalar.Ekle(FikoYTHata.YeniFikoYTHataKomutCalistirilirkenHata("aliciId ve baslik zorunlu", nil).FikoYTHata)
		return nil
	}
	err := FikoYT.Push.Gonder(aliciId, push.PushMesaj{Baslik: baslik, Mesaj: mesaj, Url: url})
	if err != nil {
		FikoYT.Cevap.Sonuc = fiber.Map{"basarili": false, "hata": err.Error()}
	} else {
		FikoYT.Cevap.Sonuc = fiber.Map{"basarili": true}
	}
	return nil
}

// n8nBildirimProxy - n8n webhook'una proxy yapar (CORS bypass)
func n8nBildirimProxy(c fiber.Ctx) error {
	// n8n webhook URL
	n8nURL := "https://fikoyt.com:5678/fikoyt-8n/d58e199a-6da5-4cd7-98d7-c497d47b4410"

	// Request body'yi al
	body := c.Body()

	// SSL sertifika doğrulamasını devre dışı bırak (self-signed için)
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}

	// n8n'e POST isteği gönder
	resp, err := client.Post(n8nURL, "application/json", bytes.NewBuffer(body))
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "n8n bağlantı hatası", "detay": err.Error()})
	}
	defer resp.Body.Close()

	// Response'u oku
	respBody, _ := io.ReadAll(resp.Body)

	return c.Status(resp.StatusCode).Send(respBody)
}
