package currency

import (
	"context"
	"log"

	"go.uber.org/zap"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
)

type currencyRepository interface {
	FindCurrenciesList(ctx context.Context, name string) (*models.CurrencyList, errors.Error)
	ReplaceCurrencies(ctx context.Context, list *models.CurrencyList) (*models.CurrencyList, errors.Error)
	Insert(ctx context.Context, list *models.CurrencyList) (*models.CurrencyList, errors.Error)
}

type Deps struct {
	Logger     *zap.Logger
	Repository currencyRepository
}

type Service struct {
	logger     *zap.Logger
	repository currencyRepository
}

func New(deps Deps) *Service {
	if deps.Logger == nil {
		log.Panicln("logger is nil on <New (currency service)>")
	}

	if deps.Repository == nil {
		log.Panicln("repository is nil on <New (currency service)>")
	}

	return &Service{
		logger:     deps.Logger,
		repository: deps.Repository,
	}
}

func (receiver *Service) GetCurrencies(ctx context.Context) ([]string, errors.Error) {
	currencyList, err := receiver.repository.FindCurrenciesList(ctx, models.DefaultCurrencyListName)
	if err != nil && err.Type() != errors.ErrNotFound {
		receiver.logger.Error(
			"failed to get currencies on <GetCurrencies> of <CurrencyService>",
			zap.Error(err),
		)

		return []string{}, err
	}

	if err != nil && err.Type() == errors.ErrNotFound {
		return []string{}, nil
	}

	return currencyList.Currencies, nil
}

func (receiver *Service) PutCurrencies(ctx context.Context, currencies []string) ([]string, errors.Error) {
	currencyList, err := receiver.repository.ReplaceCurrencies(ctx, &models.CurrencyList{
		Name:       models.DefaultCurrencyListName,
		Currencies: currencies,
	})
	if err != nil && err.Type() != errors.ErrNotFound {
		receiver.logger.Error(
			"failed to put currencies on <PutCurrencies> of <CurrencyService>",
			zap.Error(err),
		)

		return []string{}, err
	}

	if err != nil && err.Type() == errors.ErrNotFound {
		newCurrencyList, err := receiver.repository.Insert(ctx, &models.CurrencyList{
			Name:       models.DefaultCurrencyListName,
			Currencies: currencies,
		})
		if err != nil && err.Type() != errors.ErrNotFound {
			receiver.logger.Error(
				"failed to insert new currency list on <PutCurrencies> of <CurrencyService>",
				zap.Error(err),
			)

			return []string{}, err
		}

		return newCurrencyList.Currencies, nil
	}

	return currencyList.Currencies, nil
}
