package benefactorservice

import (
	"context"
	"time"

	"git.gocasts.ir/ebhomengo/niki/entity"
)

type Config struct {
	LengthOfOtpCode int           `koanf:"length_of_otp_code"`
	OtpChars        string        `koanf:"otp_chars"`
	OtpExpireTime   time.Duration `koanf:"otp_expire_time"`
}

type Repository interface {
	IsExistBenefactorByPhoneNumber(ctx context.Context, phoneNumber string) (bool, entity.Benefactor, error)
	CreateBenefactor(ctx context.Context, benefactor entity.Benefactor) (entity.Benefactor, error)
	IsExistBenefactorByID(ctx context.Context, id uint) (bool, error)
}

type AuthGenerator interface {
	CreateAccessToken(benefactor entity.Authenticable) (string, error)
	CreateRefreshToken(benefactor entity.Authenticable) (string, error)
}

type RedisOtp interface {
	IsExistPhoneNumber(ctx context.Context, phoneNumber string) (bool, error)
	SaveCodeWithPhoneNumber(ctx context.Context, phoneNumber string, code string, expireTime time.Duration) error
	GetCodeByPhoneNumber(ctx context.Context, phoneNumber string) (string, error)
	DeleteCodeByPhoneNumber(ctx context.Context, phoneNumber string) (bool, error)
}

type OtpSmsProviderClient interface {
	SendForNewUser(phoneNumber string, code string)
	SendForRegisteredUser(phoneNumber string, code string)
}

type Service struct {
	config            Config
	redisOtp          RedisOtp
	smsProviderClient OtpSmsProviderClient
	auth              AuthGenerator
	repo              Repository
}

func New(cfg Config, redisOtp RedisOtp, smsProviderClient OtpSmsProviderClient,
	auth AuthGenerator, repo Repository,
) Service {
	return Service{
		config:            cfg,
		redisOtp:          redisOtp,
		smsProviderClient: smsProviderClient,
		auth:              auth,
		repo:              repo,
	}
}
