package service

import (
	"context"
	"errors"
	"fmt"
	"log"
	"net/http"
	"sync"
	"time"
)

// HTTPServer 封装HTTP服务器功能
type HTTPServer struct {
	server *http.Server
	wg     sync.WaitGroup
}

// NewServer 创建一个新的HTTP服务器实例
func NewServer(addr string, handler http.Handler) *HTTPServer {
	return &HTTPServer{
		server: &http.Server{
			Addr:    addr,
			Handler: handler,
		},
	}
}

// Start 启动HTTP服务器（在协程中），支持context
func (s *HTTPServer) Start(ctx context.Context) error {
	log.Printf("HTTP服务器正在启动，监听地址: %s", s.server.Addr)

	// 监听context取消信号
	shutdownChan := make(chan struct{})
	go func() {
		<-ctx.Done()
		log.Println("接收到context取消信号，开始关闭服务器...")
		close(shutdownChan)
	}()

	s.wg.Add(1)
	go func() {
		defer s.wg.Done()

		if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Printf("服务器启动失败: %v", err)
			return
		}
	}()

	// 给服务器一点启动时间
	time.Sleep(100 * time.Millisecond)

	// 等待服务器启动完成或context取消
	select {
	case <-shutdownChan:
		// 如果context在启动过程中被取消，立即关闭服务器
		if err := s.Stop(); err != nil {
			log.Printf("启动过程中关闭服务器失败: %v", err)
		}
		return ctx.Err()
	default:
		log.Println("HTTP服务器启动成功")
		return nil
	}
}

// Stop 优雅关闭HTTP服务器
func (s *HTTPServer) Stop() error {
	log.Println("正在关闭HTTP服务器...")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := s.server.Shutdown(ctx); err != nil {
		return fmt.Errorf("服务器关闭失败: %v", err)
	}

	// 等待服务器协程结束
	s.wg.Wait()
	log.Println("HTTP服务器已成功关闭")
	return nil
}

// StartWithContext 可选：提供一个更简洁的启动方法（如果你需要）
func (s *HTTPServer) StartWithContext(ctx context.Context) <-chan error {
	errChan := make(chan error, 1)

	go func() {
		errChan <- s.Start(ctx)
		close(errChan)
	}()

	return errChan
}
