package model

import (
	"fmt"
	"time"

	"github.com/tech/sendico/pkg/db/storable"
	"github.com/tech/sendico/pkg/merrors"
	"go.mongodb.org/mongo-driver/v2/bson"
)

type VerificationPurpose string

const (
	PurposeAccountActivation VerificationPurpose = "account_activation"
	PurposeEmailChange       VerificationPurpose = "email_change"
	PurposePasswordReset     VerificationPurpose = "password_reset"
	PurposeMagicLogin        VerificationPurpose = "magic_login"
	PurposeLogin             VerificationPurpose = "login"
	PurposePayout            VerificationPurpose = "payout"
)

func VPToString(code VerificationPurpose) string {
	return string(code)
}

func VPFromString(s string) (VerificationPurpose, error) {
	switch s {
	case string(PurposeAccountActivation):
		return PurposeAccountActivation, nil
	case string(PurposeEmailChange):
		return PurposeEmailChange, nil
	case string(PurposePasswordReset):
		return PurposePasswordReset, nil
	case string(PurposeMagicLogin):
		return PurposeMagicLogin, nil
	case string(PurposeLogin):
		return PurposeLogin, nil
	case string(PurposePayout):
		return PurposePayout, nil
	default:
		return "", merrors.InvalidArgument(fmt.Sprintf("invalid verification purpose: %s", s))
	}
}

type VerificationToken struct {
	storable.Base `bson:",inline" json:",inline"`

	Target          string              `bson:"target,omitempty" json:"target"`
	AccountRef      bson.ObjectID       `bson:"accountRef" json:"accountRef"`
	Purpose         VerificationPurpose `bson:"purpose" json:"purpose"`
	IdempotencyKey  *string             `bson:"idempotencyKey,omitempty" json:"-"`
	VerifyTokenHash string              `bson:"verifyTokenHash" json:"-"`
	Salt            *string             `bson:"salt,omitempty" json:"-"`
	UsedAt          *time.Time          `bson:"usedAt,omitempty" json:"-"`
	ExpiresAt       time.Time           `bson:"expiresAt" json:"-"`
	MaxRetries      *int                `bson:"maxRetries,omitempty" json:"-"`
	Attempts        int                 `bson:"attempts" json:"-"`
}
