package verificationimp

import (
	"context"
	"time"

	api "github.com/tech/sendico/pkg/api/http"
	"github.com/tech/sendico/pkg/db/refreshtokens"
	"github.com/tech/sendico/pkg/messaging"
	"github.com/tech/sendico/pkg/mlogger"
	"github.com/tech/sendico/pkg/mservice"
	eapi "github.com/tech/sendico/server/interface/api"
	"github.com/tech/sendico/server/interface/middleware"
)

type Config struct {
	CodeLength  int
	TTL         time.Duration
	MaxAttempts int
	Cooldown    time.Duration
	ResendLimit int
}

func defaultConfig() Config {
	return Config{
		CodeLength:  6,
		TTL:         10 * time.Minute,
		MaxAttempts: 5,
		Cooldown:    time.Minute,
		ResendLimit: 5,
	}
}

func DefaultConfig() Config {
	return defaultConfig()
}

type VerificationAPI struct {
	logger      mlogger.Logger
	config      Config
	store       *ConfirmationStore
	rtdb        refreshtokens.DB
	producer    messaging.Producer
	tokenConfig middleware.TokenConfig
	signature   middleware.Signature
}

func (a *VerificationAPI) Name() mservice.Type {
	return mservice.Verification
}

func (a *VerificationAPI) Finish(_ context.Context) error {
	return nil
}

func CreateAPI(a eapi.API) (*VerificationAPI, error) {
	cdb, err := a.DBFactory().NewVerificationsDB()
	if err != nil {
		return nil, err
	}
	rtdb, err := a.DBFactory().NewRefreshTokensDB()
	if err != nil {
		return nil, err
	}

	p := &VerificationAPI{
		logger:      a.Logger().Named(mservice.Verification),
		config:      defaultConfig(),
		store:       NewStore(cdb),
		rtdb:        rtdb,
		producer:    a.Register().Messaging().Producer(),
		tokenConfig: a.Config().Mw.Token,
		signature:   middleware.SignatureConf(a.Config().Mw),
	}

	a.Register().PendingAccountHandler(p.Name(), "/", api.Post, p.requestCode)
	a.Register().PendingAccountHandler(p.Name(), "/resend", api.Post, p.requestCode)
	a.Register().PendingAccountHandler(p.Name(), "/verify", api.Post, p.verifyCode)
	return p, nil
}
