// Package server provides HTTP endpoints for status monitoring and statistics
package server

import (
	"context"
	"net/http"
	"os"
	"time"

	"git.eeqj.de/sneak/routewatch/internal/database"
	"git.eeqj.de/sneak/routewatch/internal/logger"
	"git.eeqj.de/sneak/routewatch/internal/streamer"
	"github.com/go-chi/chi/v5"
)

// ASNFetcherStats contains WHOIS fetcher statistics.
type ASNFetcherStats struct {
	SuccessesLastHour int
	ErrorsLastHour    int
	CurrentInterval   time.Duration
	ConsecutiveFails  int
}

// ASNFetcher is an interface for queuing ASN WHOIS lookups.
type ASNFetcher interface {
	QueueImmediate(asn int)
	GetStats() ASNFetcherStats
}

// Server provides HTTP endpoints for status monitoring
type Server struct {
	router     *chi.Mux
	db         database.Store
	streamer   *streamer.Streamer
	logger     *logger.Logger
	srv        *http.Server
	asnFetcher ASNFetcher
}

// New creates a new HTTP server
func New(db database.Store, streamer *streamer.Streamer, logger *logger.Logger) *Server {
	s := &Server{
		db:       db,
		streamer: streamer,
		logger:   logger,
	}

	s.setupRoutes()

	return s
}

// Start starts the HTTP server
func (s *Server) Start() error {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	const (
		readHeaderTimeout = 40 * time.Second
		readTimeout       = 60 * time.Second
		writeTimeout      = 60 * time.Second
		idleTimeout       = 120 * time.Second
	)

	s.srv = &http.Server{
		Addr:              ":" + port,
		Handler:           s.router,
		ReadHeaderTimeout: readHeaderTimeout,
		ReadTimeout:       readTimeout,
		WriteTimeout:      writeTimeout,
		IdleTimeout:       idleTimeout,
	}

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

	// Start in goroutine but log when actually listening
	go func() {
		s.logger.Info("HTTP server listening", "addr", s.srv.Addr)
		if err := s.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			s.logger.Error("HTTP server error", "error", err)
		}
	}()

	return nil
}

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

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

	return s.srv.Shutdown(ctx)
}

// SetASNFetcher sets the ASN WHOIS fetcher for on-demand lookups.
func (s *Server) SetASNFetcher(fetcher ASNFetcher) {
	s.asnFetcher = fetcher
}
