package server

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

	"linkmaster-node/internal/config"
	"linkmaster-node/internal/handler"
	"linkmaster-node/internal/recovery"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type HTTPServer struct {
	ipv4Server *http.Server
	ipv6Server *http.Server
	logger     *zap.Logger
	wg         sync.WaitGroup
}

func NewHTTPServer(cfg *config.Config) *HTTPServer {
	if !cfg.Debug {
		gin.SetMode(gin.ReleaseMode)
	}

	router := gin.New()
	router.Use(gin.Recovery())
	router.Use(recoveryMiddleware)

	// 初始化持续测试处理器
	handler.InitContinuousHandler(cfg)
	
	// 启动任务清理goroutine
	handler.StartTaskCleanup()

	// 注册路由
	api := router.Group("/api")
	{
		api.POST("/test", handler.HandleTest)
		api.POST("/continuous/start", handler.HandleContinuousStart)
		api.POST("/continuous/stop", handler.HandleContinuousStop)
		api.GET("/continuous/status", handler.HandleContinuousStatus)
		api.GET("/health", handler.HandleHealth)
	}

	// IPv4 服务器
	ipv4Server := &http.Server{
		Addr:    fmt.Sprintf("0.0.0.0:%d", cfg.Server.Port),
		Handler: router,
	}

	// IPv6 服务器
	ipv6Server := &http.Server{
		Addr:    fmt.Sprintf("[::]:%d", cfg.Server.Port),
		Handler: router,
	}

	logger, _ := zap.NewProduction()

	return &HTTPServer{
		ipv4Server: ipv4Server,
		ipv6Server: ipv6Server,
		logger:     logger,
	}
}

func (s *HTTPServer) Start() error {
	// 先启动 IPv4 服务器（避免端口冲突）
	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		// 使用 net.Listen 明确监听 IPv4，便于错误处理
		listener, err := net.Listen("tcp4", s.ipv4Server.Addr)
		if err != nil {
			s.logger.Error("IPv4服务器监听失败", zap.String("addr", s.ipv4Server.Addr), zap.Error(err))
			return
		}
		
		s.logger.Info("HTTP服务器启动 (IPv4)", zap.String("addr", s.ipv4Server.Addr))
		if err := s.ipv4Server.Serve(listener); err != nil && err != http.ErrServerClosed {
			s.logger.Error("IPv4服务器启动失败", zap.Error(err))
		}
	}()

	// 等待一小段时间，确保 IPv4 先启动
	time.Sleep(100 * time.Millisecond)

	// 再启动 IPv6 服务器
	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		// 检查系统是否支持 IPv6
		listener, err := net.Listen("tcp6", s.ipv6Server.Addr)
		if err != nil {
			s.logger.Warn("IPv6不支持或已禁用，跳过IPv6监听", zap.String("addr", s.ipv6Server.Addr), zap.Error(err))
			return
		}
		
		s.logger.Info("HTTP服务器启动 (IPv6)", zap.String("addr", s.ipv6Server.Addr))
		if err := s.ipv6Server.Serve(listener); err != nil && err != http.ErrServerClosed {
			s.logger.Error("IPv6服务器启动失败", zap.Error(err))
		}
	}()

	// 立即返回，服务器在后台运行
	return nil
}

func (s *HTTPServer) Shutdown(ctx context.Context) error {
	var errs []error

	// 关闭 IPv4 服务器
	if s.ipv4Server != nil {
		if err := s.ipv4Server.Shutdown(ctx); err != nil {
			errs = append(errs, fmt.Errorf("关闭IPv4服务器失败: %w", err))
		} else {
			s.logger.Info("IPv4服务器已关闭")
		}
	}

	// 关闭 IPv6 服务器
	if s.ipv6Server != nil {
		if err := s.ipv6Server.Shutdown(ctx); err != nil {
			errs = append(errs, fmt.Errorf("关闭IPv6服务器失败: %w", err))
		} else {
			s.logger.Info("IPv6服务器已关闭")
		}
	}

	// 等待所有 goroutine 完成
	s.wg.Wait()

	if len(errs) > 0 {
		return fmt.Errorf("关闭服务器时发生错误: %v", errs)
	}

	return nil
}

func recoveryMiddleware(c *gin.Context) {
	defer recovery.Recover()
	c.Next()
}

