package http

import (
	"context"
	"fmt"
	"log/slog"
	"net/http"
	"time"

	"git.eeqj.de/sneak/ipapi/internal/config"
	"github.com/go-chi/chi/v5"
)

// Server manages the HTTP server lifecycle.
type Server struct {
	config     *config.Config
	logger     *slog.Logger
	router     chi.Router
	httpServer *http.Server
}

// NewServer creates a new HTTP server instance.
func NewServer(cfg *config.Config, logger *slog.Logger, router chi.Router) (*Server, error) {
	return &Server{
		config: cfg,
		logger: logger,
		router: router,
	}, nil
}

// Start begins listening for HTTP requests.
func (s *Server) Start(_ context.Context) error {
	addr := fmt.Sprintf(":%d", s.config.Port)
	s.httpServer = &http.Server{
		Addr:         addr,
		Handler:      s.router,
		ReadTimeout:  15 * time.Second, //nolint:mnd
		WriteTimeout: 15 * time.Second, //nolint:mnd
		IdleTimeout:  60 * time.Second, //nolint:mnd
	}

	s.logger.Info("Starting HTTP server", "addr", addr)

	go func() {
		if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			s.logger.Error("HTTP server error", "error", err)
		}
	}()

	return nil
}

// Stop gracefully shuts down the HTTP server.
func (s *Server) Stop(ctx context.Context) error {
	if s.httpServer == nil {
		return nil
	}

	s.logger.Info("Stopping HTTP server")

	const shutdownTimeout = 30 * time.Second
	shutdownCtx, cancel := context.WithTimeout(ctx, shutdownTimeout)
	defer cancel()

	return s.httpServer.Shutdown(shutdownCtx)
}
