package http

import (
	"context"
	"fmt"
	"gitea.pena/PenaSide/common/log_mw"
	"gitea.pena/PenaSide/hlog"
	"gitea.pena/SQuiz/common/middleware"
	"github.com/gofiber/fiber/v2"
	"go.uber.org/zap"
)

type ServerConfig struct {
	Logger      *zap.Logger
	Controllers []Controller
	Hlogger     hlog.Logger
}

type Server struct {
	Logger      *zap.Logger
	Controllers []Controller
	app         *fiber.App
}

func NewServer(config ServerConfig) *Server {
	app := fiber.New()
	app.Use(middleware.JWTAuth())
	app.Use(log_mw.ContextLogger(config.Hlogger))
	//app.Get("/liveness", healthchecks.Liveness)
	//app.Get("/readiness", healthchecks.Readiness(&workerErr)) //todo parametrized readiness. should discuss ready reason
	s := &Server{
		Logger:      config.Logger,
		Controllers: config.Controllers,
		app:         app,
	}

	s.registerRoutes()

	return s
}

func (s *Server) Start(addr string) error {
	if err := s.app.Listen(addr); err != nil {
		s.Logger.Error("Failed to start server", zap.Error(err))
		return err
	}
	return nil
}

func (s *Server) Shutdown(ctx context.Context) error {
	return s.app.Shutdown()
}

func (s *Server) registerRoutes() {
	for _, c := range s.Controllers {
		router := s.app.Group(c.Name())
		c.Register(router)
	}
}

type Controller interface {
	Register(router fiber.Router)
	Name() string
}

func (s *Server) ListRoutes() {
	fmt.Println("Registered routes:")
	for _, stack := range s.app.Stack() {
		for _, route := range stack {
			fmt.Printf("%s %s\n", route.Method, route.Path)
		}
	}
}
