package main

import (
	"flag"
	"fmt"
	"log"
	"medi-wol/internal/database"
	"medi-wol/internal/handlers"
	"medi-wol/internal/scheduler"
	"medi-wol/internal/wol"
	"os"
	"os/signal"
	"strconv"
	"syscall"

	"github.com/gin-gonic/gin"
)

func main() {
	// Kommandozeilenparameter definieren
	var port int
	flag.IntVar(&port, "port", 0, "Port für den Server (Standard: 8080 oder PORT Umgebungsvariable)")
	flag.Parse()

	// Port aus Umgebungsvariable oder Standardwert
	if port == 0 {
		if envPort := os.Getenv("PORT"); envPort != "" {
			if parsedPort, err := strconv.Atoi(envPort); err == nil {
				port = parsedPort
			} else {
				log.Printf("Warnung: Ungültige PORT Umgebungsvariable '%s', verwende Standard-Port 8080", envPort)
				port = 8080
			}
		} else {
			port = 8080
		}
	}

	// Port-Validierung
	if port < 1 || port > 65535 {
		log.Fatal("Fehler: Port muss zwischen 1 und 65535 liegen")
	}

	// Datenbank initialisieren
	db, err := database.InitDB()
	if err != nil {
		log.Fatal("Fehler beim Initialisieren der Datenbank:", err)
	}
	defer db.Close()

	// Wake-on-LAN Service initialisieren
	wolService := wol.NewService()

	// Scheduler initialisieren und starten
	scheduler := scheduler.NewScheduler(db, wolService)
	scheduler.Start()
	defer scheduler.Stop()

	// Handler initialisieren
	pcHandler := handlers.NewPCHandler(db, wolService)

	// Gin Router konfigurieren
	r := gin.Default()

	// HTML-Templates laden
	r.LoadHTMLGlob("web/templates/*")

	// Routen definieren
	r.GET("/", pcHandler.Index)
	r.GET("/logs", pcHandler.Logs)
	r.GET("/api/pcs", pcHandler.GetAllPCs)
	r.POST("/api/pcs", pcHandler.CreatePC)
	r.PUT("/api/pcs/:id", pcHandler.UpdatePC)
	r.DELETE("/api/pcs/:id", pcHandler.DeletePC)
	r.POST("/api/pcs/:id/wake", pcHandler.WakePC)
	r.GET("/api/pcs/status", pcHandler.GetPCStatus)

	// Log-Routen
	r.GET("/api/logs", pcHandler.GetAllLogs)
	r.GET("/api/logs/pc/:id", pcHandler.GetLogsByPCID)
	r.GET("/api/logs/pc/:id/recent", pcHandler.GetRecentLogsByPCID)

	// Statische Dateien bereitstellen (nach den spezifischen Routen)
	r.Static("/static", "./web/static")

	// Graceful Shutdown konfigurieren
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	// Server in Goroutine starten
	go func() {
		serverAddr := fmt.Sprintf(":%d", port)
		log.Printf("Medi-WOL startet auf Port %d...", port)
		log.Printf("Web-Oberfläche verfügbar unter: http://localhost%s", serverAddr)

		if err := r.Run(serverAddr); err != nil {
			log.Fatal("Fehler beim Starten des Servers:", err)
		}
	}()

	// Auf Shutdown-Signal warten
	<-quit
	log.Println("Server wird heruntergefahren...")
}
