package aapitemplate

import (
	"github.com/tech/sendico/server/interface/api/sresponse"
)

type HandlerResolver func(sresponse.AccountHandlerFunc) sresponse.AccountHandlerFunc

type Config interface {
	WithNoCreate() Config
	WithCreateHandler(handler sresponse.AccountHandlerFunc) Config
	WithNoList() Config
	WithListHandler(handler sresponse.AccountHandlerFunc) Config
	WithNoGet() Config
	WithGetHandler(handler sresponse.AccountHandlerFunc) Config
	WithNoUpdate() Config
	WithUpdateHandler(handler sresponse.AccountHandlerFunc) Config
	WithNoDelete() Config
	WithDeleteHandler(handler sresponse.AccountHandlerFunc) Config
	WithReorderHandler(reorder ReorderConfig) Config
}

type AAPIConfig struct {
	CreateResolver  HandlerResolver
	ListResolver    HandlerResolver
	GetResolver     HandlerResolver
	UpdateResolver  HandlerResolver
	DeleteResolver  HandlerResolver
	ArchiveResolver HandlerResolver
	Reorder         *ReorderConfig
}

// WithNoCreate disables the create endpoint by replacing its resolver.
func (cfg *AAPIConfig) WithNoCreate() *AAPIConfig {
	cfg.CreateResolver = disableResolver
	return cfg
}

// WithCreateHandler overrides the create endpoint by replacing its resolver.
func (cfg *AAPIConfig) WithCreateHandler(handler sresponse.AccountHandlerFunc) *AAPIConfig {
	cfg.CreateResolver = overrideResolver(handler)
	return cfg
}

// WithNoList disables the list endpoint.
func (cfg *AAPIConfig) WithNoList() *AAPIConfig {
	cfg.ListResolver = disableResolver
	return cfg
}

// WithListHandler overrides the list endpoint.
func (cfg *AAPIConfig) WithListHandler(handler sresponse.AccountHandlerFunc) *AAPIConfig {
	cfg.ListResolver = overrideResolver(handler)
	return cfg
}

// WithNoGet disables the get endpoint.
func (cfg *AAPIConfig) WithNoGet() *AAPIConfig {
	cfg.GetResolver = disableResolver
	return cfg
}

// WithGetHandler overrides the get endpoint.
func (cfg *AAPIConfig) WithGetHandler(handler sresponse.AccountHandlerFunc) *AAPIConfig {
	cfg.GetResolver = overrideResolver(handler)
	return cfg
}

// WithNoUpdate disables the update endpoint.
func (cfg *AAPIConfig) WithNoUpdate() *AAPIConfig {
	cfg.UpdateResolver = disableResolver
	return cfg
}

// WithUpdateHandler overrides the update endpoint.
func (cfg *AAPIConfig) WithUpdateHandler(handler sresponse.AccountHandlerFunc) *AAPIConfig {
	cfg.UpdateResolver = overrideResolver(handler)
	return cfg
}

// WithNoDelete disables the delete endpoint.
func (cfg *AAPIConfig) WithNoDelete() *AAPIConfig {
	cfg.DeleteResolver = disableResolver
	return cfg
}

// WithDeleteHandler overrides the delete endpoint.
func (cfg *AAPIConfig) WithDeleteHandler(handler sresponse.AccountHandlerFunc) *AAPIConfig {
	cfg.DeleteResolver = overrideResolver(handler)
	return cfg
}

func (cfg *AAPIConfig) WithNoArchive() *AAPIConfig {
	cfg.ArchiveResolver = disableResolver
	return cfg
}

func (cfg *AAPIConfig) WithArchiveHandler(handler sresponse.AccountHandlerFunc) *AAPIConfig {
	cfg.ArchiveResolver = overrideResolver(handler)
	return cfg
}

// defaultResolver returns the default handler unchanged.
func defaultResolver(defaultHandler sresponse.AccountHandlerFunc) sresponse.AccountHandlerFunc {
	return defaultHandler
}

// disableResolver always returns nil, disabling the endpoint.
func disableResolver(_ sresponse.AccountHandlerFunc) sresponse.AccountHandlerFunc {
	return nil
}

// overrideResolver returns a resolver that always returns the given custom handler.
func overrideResolver(custom sresponse.AccountHandlerFunc) HandlerResolver {
	return func(_ sresponse.AccountHandlerFunc) sresponse.AccountHandlerFunc {
		return custom
	}
}

func NewConfig() *AAPIConfig {
	return &AAPIConfig{
		CreateResolver:  defaultResolver,
		ListResolver:    defaultResolver,
		GetResolver:     defaultResolver,
		UpdateResolver:  defaultResolver,
		DeleteResolver:  defaultResolver,
		ArchiveResolver: defaultResolver,
		Reorder:         nil,
	}
}
