package routers

import (
	"os"

	"github.com/go-chi/chi/v5"

	api "github.com/tech/sendico/pkg/api/http"
	"github.com/tech/sendico/pkg/auth"
	"github.com/tech/sendico/pkg/db/account"
	"github.com/tech/sendico/pkg/db/refreshtokens"
	"github.com/tech/sendico/pkg/db/verification"
	"github.com/tech/sendico/pkg/mlogger"
	"github.com/tech/sendico/pkg/mservice"
	"github.com/tech/sendico/server/interface/api/sresponse"
	"github.com/tech/sendico/server/interface/middleware"
	rauthorized "github.com/tech/sendico/server/internal/api/routers/authorized"
	rpublic "github.com/tech/sendico/server/internal/api/routers/public"
)

type Dispatcher struct {
	logger    mlogger.Logger
	public    APIRouter
	protected ProtectedAPIRouter
}

func (d *Dispatcher) Handler(service mservice.Type, endpoint string, method api.HTTPMethod, handler sresponse.HandlerFunc) {
	d.public.InstallHandler(service, endpoint, method, handler)
}

func (d *Dispatcher) AccountHandler(service mservice.Type, endpoint string, method api.HTTPMethod, handler sresponse.AccountHandlerFunc) {
	d.protected.AccountHandler(service, endpoint, method, handler)
}

func (d *Dispatcher) PendingAccountHandler(service mservice.Type, endpoint string, method api.HTTPMethod, handler sresponse.PendingAccountHandlerFunc) {
	d.protected.PendingAccountHandler(service, endpoint, method, handler)
}

func NewDispatcher(logger mlogger.Logger, router chi.Router, db account.DB, vdb verification.DB, rtdb refreshtokens.DB, enforcer auth.Enforcer, config *middleware.Config) *Dispatcher {
	d := &Dispatcher{
		logger: logger.Named("api_dispatcher"),
	}

	d.logger.Debug("Installing endpoints middleware...")
	endpoint := os.Getenv(config.EndPointEnv)
	signature := middleware.SignatureConf(config)
	router.Group(func(r chi.Router) {
		d.public = rpublic.NewRouter(d.logger, endpoint, db, vdb, rtdb, r, &config.Token, &signature)
	})
	router.Group(func(r chi.Router) {
		d.protected = rauthorized.NewRouter(d.logger, endpoint, r, db, rtdb, enforcer, &config.Token, &signature)
	})

	return d
}
