package server

import (
	"fmt"
	"net/http"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"go.fifitido.net/ytdl-web/pkg/middlewarex"
	"golang.org/x/exp/slog"
)

type Server interface {
	MountController(path string, controller Controller)
	ListenAndServe() error
}

type DefaultServer struct {
	r    chi.Router
	opts *Options
}

var _ Server = (*DefaultServer)(nil)

func New(options ...*Options) *DefaultServer {
	var opts *Options
	if len(options) > 0 {
		opts = options[0]
	} else {
		opts = DefaultOptions()
	}

	r := chi.NewRouter()

	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(middlewarex.SlogRequestLogger(opts.Logger))
	r.Use(middleware.Recoverer)

	return &DefaultServer{
		r:    r,
		opts: opts,
	}
}

func (s *DefaultServer) MountController(path string, controller Controller) {
	s.r.Route(path, controller.Router)
}

func (s *DefaultServer) ListenAndServe() error {
	listenAddr := fmt.Sprintf("%s:%d", s.opts.ListenAddr, s.opts.ListenPort)
	s.opts.Logger.Info("Starting HTTP server", slog.String("addr", s.opts.ListenAddr), slog.Int("port", s.opts.ListenPort))
	return http.ListenAndServe(listenAddr, s.r)
}
