package main

import (
	"app/shelfly/handlers"
	"app/shelfly/internal/db"
	"app/shelfly/internal/library"
	"app/shelfly/internal/route"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {

	// 1. Démarrer le routeur principal
	r := mux.NewRouter()

	// 2. Initialiser la DB
	bd := db.InitDB()

	// 2.1
	library.CreateDefaultFolder(bd)

	// 3. Routes non protégées : on les monte sur le routeur principal
	route.RoutesPublic(r, bd)

	// 4. Créer un sous-routeur pour les routes protégées
	protected := r.PathPrefix("/").Subrouter()

	// 5. Appliquer le middleware JWT à ce sous-routeur
	protected.Use(handlers.AuthMiddleware)
	// 6. Enregistrer les routes protégées sur ce sous-routeur
	route.RoutesProtected(protected, bd)
	//setupPortMappingWithFallback(4000, 4000)
	// 6.5. Exposer le dossier upload
	fs := http.StripPrefix("/upload/", http.FileServer(http.Dir("/app/upload")))
	r.PathPrefix("/upload/").Handler(fs)
	



	// 7. Lancer le serveur sur le port 4000
	log.Fatal(http.ListenAndServe(":4000", r))

}

// Fonction principale à appeler dans main()
// func setupPortMappingWithFallback(internalPort, externalPort uint16) {
// 	success := setupUPnPWithRenewal(internalPort, externalPort)
// 	if !success {
// 		log.Println("🔁 UPnP indisponible, tentative NAT-PMP...")
// 		setupNATPMP(internalPort, externalPort)
// 	}
// }

// // UPnP avec renouvellement automatique
// func setupUPnPWithRenewal(internalPort, externalPort uint16) bool {
// 	clients, _, err := internetgateway1.NewWANIPConnection1Clients()
// 	if err != nil {
// 		log.Println("Erreur découverte UPnP :", err)
// 		return false
// 	}
// 	if len(clients) == 0 {
// 		log.Println("Aucun client UPnP détecté.")
// 		return false
// 	}

// 	localIP := getLocalIP()
// 	log.Println("IP locale détectée :", localIP)
// 	if localIP == "" {
// 		log.Println("Impossible d’obtenir l’IP locale")
// 		return false
// 	}

// 	client := clients[0]
// 	protocol := "TCP"
// 	description := "GoAutoExposition"
// 	duration := uint32(3600)

// 	mapPort := func() error {
// 		err := client.AddPortMapping("", externalPort, protocol, internalPort, localIP, true, description, duration)
// 		if err != nil {
// 			log.Println("UPnP mapping échoué :", err)
// 			return err
// 		}
// 		log.Printf("✅ [UPnP] Port %d externe redirigé vers %s:%d", externalPort, localIP, internalPort)
// 		return nil
// 	}

// 	// Premier essai
// 	if err := mapPort(); err != nil {
// 		return false
// 	}

// 	// Renouvellement
// 	go func() {
// 		for {
// 			time.Sleep(55 * time.Minute)
// 			mapPort()
// 		}
// 	}()

// 	return true
// }

// // NAT-PMP fallback
// func setupNATPMP(internalPort, externalPort uint16) {
// 	gatewayIP := getGatewayIP()
// 	if gatewayIP == "" {
// 		log.Println("Impossible d’obtenir la gateway pour NAT-PMP")
// 		return
// 	}

// 	client := natpmp.NewClient(net.ParseIP(gatewayIP))
// 	_, err := client.AddPortMapping("tcp", int(internalPort), int(externalPort), 3600)
// 	if err != nil {
// 		log.Println("NAT-PMP mapping échoué :", err)
// 	} else {
// 		log.Printf("✅ [NAT-PMP] Port %d externe redirigé vers local :%d via NAT-PMP", externalPort, internalPort)
// 	}
// }

// // Obtenir IP locale
// func getLocalIP() string {
// 	conn, err := net.Dial("udp", "8.8.8.8:80")
// 	if err != nil {
// 		return ""
// 	}
// 	defer conn.Close()
// 	localAddr := conn.LocalAddr().(*net.UDPAddr)
// 	return localAddr.IP.String()
// }

// // Obtenir IP de la passerelle (gateway) locale
// func getGatewayIP() string {
// 	ip, err := gateway.DiscoverGateway()
// 	if err != nil {
// 		log.Println("Erreur récupération gateway réelle :", err)
// 		return ""
// 	}
// 	return ip.String()
// }
