package oracle

import (
	"math/big"
	"strings"

	"github.com/tech/sendico/fx/storage/model"
	"github.com/tech/sendico/pkg/decimal"
	"github.com/tech/sendico/pkg/merrors"
	fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
)

// Convenience aliases to pkg/decimal for backward compatibility
var (
	ratFromString = decimal.RatFromString
	mulRat        = decimal.MulRat
	divRat        = decimal.DivRat
	formatRat     = decimal.FormatRat
)

// roundRatToScale wraps pkg/decimal.RoundRatToScale with model RoundingMode conversion
func roundRatToScale(value *big.Rat, scale uint32, mode model.RoundingMode) (*big.Rat, error) {
	return decimal.RoundRatToScale(value, scale, convertRoundingMode(mode))
}

// convertRoundingMode converts fx/storage model.RoundingMode to pkg/decimal.RoundingMode
func convertRoundingMode(mode model.RoundingMode) decimal.RoundingMode {
	switch mode {
	case model.RoundingModeHalfEven:
		return decimal.RoundingModeHalfEven
	case model.RoundingModeHalfUp:
		return decimal.RoundingModeHalfUp
	case model.RoundingModeDown:
		return decimal.RoundingModeDown
	case model.RoundingModeUnspecified:
		return decimal.RoundingModeUnspecified
	default:
		return decimal.RoundingModeHalfEven
	}
}

func priceFromRate(rate *model.RateSnapshot, side fxv1.Side) (*big.Rat, error) {
	var priceStr string
	switch side {
	case fxv1.Side_BUY_BASE_SELL_QUOTE:
		priceStr = rate.Ask
	case fxv1.Side_SELL_BASE_BUY_QUOTE:
		priceStr = rate.Bid
	default:
		priceStr = ""
	}

	if strings.TrimSpace(priceStr) == "" {
		priceStr = rate.Mid
	}

	if strings.TrimSpace(priceStr) == "" {
		return nil, merrors.InvalidArgument("oracle: rate snapshot missing price")
	}

	return ratFromString(priceStr)
}
