package testserver

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

	"dance-lessons-coach/pkg/config"
	"dance-lessons-coach/pkg/server"

	"github.com/rs/zerolog/log"
)

type Server struct {
	httpServer *http.Server
	port       int
	baseURL    string
}

func NewServer() *Server {
	return &Server{
		port: 9191,
	}
}

func (s *Server) Start() error {
	s.baseURL = fmt.Sprintf("http://localhost:%d", s.port)

	// Create real server instance from pkg/server
	cfg := createTestConfig(s.port)
	realServer := server.NewServer(cfg, context.Background())

	// Start HTTP server in same process
	s.httpServer = &http.Server{
		Addr:    fmt.Sprintf(":%d", s.port),
		Handler: realServer.Router(),
	}

	go func() {
		if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			if err != http.ErrServerClosed {
				log.Error().Err(err).Msg("Test server failed")
			}
		}
	}()

	// Wait for server to be ready
	return s.waitForServerReady()
}

func (s *Server) waitForServerReady() error {
	maxAttempts := 30
	attempt := 0

	for attempt < maxAttempts {
		resp, err := http.Get(fmt.Sprintf("%s/api/ready", s.baseURL))
		if err == nil && resp.StatusCode == http.StatusOK {
			resp.Body.Close()
			return nil
		}
		if resp != nil {
			resp.Body.Close()
		}
		attempt++
		time.Sleep(100 * time.Millisecond)
	}

	return fmt.Errorf("server did not become ready after %d attempts", maxAttempts)
}

func (s *Server) Stop() error {
	if s.httpServer == nil {
		return nil
	}

	// Shutdown HTTP server gracefully
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	return s.httpServer.Shutdown(ctx)
}

func (s *Server) GetBaseURL() string {
	return s.baseURL
}

func createTestConfig(port int) *config.Config {
	return &config.Config{
		Server: config.ServerConfig{
			Host: "localhost",
			Port: port,
		},
		Shutdown: config.ShutdownConfig{
			Timeout: 5 * time.Second,
		},
		Logging: config.LoggingConfig{
			JSON:  false,
			Level: "trace",
		},
		Telemetry: config.TelemetryConfig{
			Enabled: false,
		},
		API: config.APIConfig{
			V2Enabled: true, // Enable v2 for testing
		},
		Auth: config.AuthConfig{
			JWTSecret:           "default-secret-key-please-change-in-production",
			AdminMasterPassword: "admin123",
		},
	}
}
