package main

import (
	"flag"
	"log/slog"
	"net/http"
	"os"
	"os/signal"
	"syscall"

	"github.com/go-chi/chi/v5"
	"nerd-monitor/internal/api"
	"nerd-monitor/internal/auth"
	"nerd-monitor/internal/store"
	"nerd-monitor/internal/ui"
)

func main() {
	var (
		addr     = flag.String("addr", "0.0.0.0", "server address")
		port     = flag.String("port", "8080", "server port")
		username = flag.String("username", "admin", "admin username")
		password = flag.String("password", "admin", "admin password")
	)
	flag.Parse()

	// Set up verbose logging
	slog.SetLogLoggerLevel(slog.LevelDebug)

	// Initialize dependencies
	s := store.New()
	authMgr := auth.New(*username, *password)
	apiHandler := api.New(s)
	uiHandler := ui.New(s, authMgr)

	// Setup router
	r := chi.NewRouter()

	// Public routes (no auth required)
	r.Post("/api/report", apiHandler.ReportStats)
	r.Get("/api/agents", apiHandler.ListAgents)
	r.Get("/api/agents/{id}", apiHandler.GetAgent)
	r.Get("/login", uiHandler.Login)
	r.Post("/login", uiHandler.Login)

	// Public routes (no auth required)
	r.Post("/api/report", apiHandler.ReportStats)
	r.Get("/api/agents", apiHandler.ListAgents)
	r.Get("/api/agents/{id}", apiHandler.GetAgent)

	// Protected routes (auth required)
	r.Group(func(protectedRoutes chi.Router) {
		protectedRoutes.Use(authMgr.Middleware)
		protectedRoutes.Get("/", uiHandler.Dashboard)
		protectedRoutes.Get("/agents/{id}", uiHandler.AgentDetail)
		protectedRoutes.Get("/api/dashboard/table", uiHandler.GetDashboardTable)
		protectedRoutes.Get("/api/agents/{id}/stats", uiHandler.GetAgentStats)
		protectedRoutes.Get("/api/events", uiHandler.Events)
		protectedRoutes.Post("/agents/{id}/hostname", uiHandler.UpdateAgentHostname)
		protectedRoutes.Post("/logout", uiHandler.Logout)
		protectedRoutes.Post("/api/agents/remove-stale", uiHandler.RemoveStaleAgents)
		protectedRoutes.Post("/api/agents/{id}/delete", uiHandler.DeleteAgent)
	})

	// Setup server
	server := &http.Server{
		Addr:    *addr + ":" + *port,
		Handler: r,
	}

	// Graceful shutdown
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	go func() {
		<-sigChan
		slog.Info("Shutting down server...")
		server.Close()
		os.Exit(0)
	}()

	slog.Info("Starting server", "addr", *addr+":"+*port, "url", "http://"+*addr+":"+*port)
	slog.Info("Login credentials", "username", *username, "password", *password)
	if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		slog.Error("Server error", "error", err)
		os.Exit(1)
	}
}
