package client

import (
	"context"
	"fmt"
	"log"
	"strconv"

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

type CurrencyClientDeps struct {
	Logger *zap.Logger
	URLs   *models.CurrencyMicroserviceURL
}

type CurrencyClient struct {
	logger *zap.Logger
	urls   *models.CurrencyMicroserviceURL
}

func NewCurrencyClient(deps CurrencyClientDeps) *CurrencyClient {
	if deps.Logger == nil {
		log.Panicln("logger is nil on <NewCurrencyClient>")
	}

	if deps.URLs == nil {
		log.Panicln("urls is nil on <NewCurrencyClient>")
	}

	return &CurrencyClient{
		logger: deps.Logger,
		urls:   deps.URLs,
	}
}

func (receiver *CurrencyClient) Translate(ctx context.Context, request *models.TranslateCurrency) (int64, errors.Error) {
	response, err := client.Get[models.CurrencyClientResponse[int64], models.CurrencyClientResponse[string]](ctx, &client.RequestSettings{
		URL:     receiver.urls.Translate,
		Headers: map[string]string{"Content-Type": "application/json"},
		QueryParams: map[string]string{
			"currencyFrom": request.From,
			"currencyTo":   request.To,
			"value":        strconv.FormatInt(request.Money, 10),
		},
	})
	if err != nil {
		receiver.logger.Error("failed to request on <Translate> of <CurrencyClient>",
			zap.Error(err),
			zap.String("from", request.From),
			zap.String("to", request.To),
			zap.Int64("money", request.Money),
		)

		return 0, errors.New(
			fmt.Errorf("failed to request on <Translate> of <CurrencyClient>: %w", err),
			errors.ErrInternalError,
		)
	}
	if response.Error != nil {
		receiver.logger.Error("failed translate currency on <Translate> of <CurrencyClient>",
			zap.String("error", response.Error.Message),
			zap.String("from", request.From),
			zap.String("to", request.To),
			zap.Int64("money", request.Money),
		)

		return 0, errors.New(
			fmt.Errorf("failed translate currency on <Translate> of <CurrencyClient>: %s", response.Error.Message),
			utils.DetermineClientErrorResponse(response.StatusCode),
		)
	}

	return response.Body.Message, nil
}
