package mongo

import (
	"fmt"
	"reflect"

	"github.com/shopspring/decimal"
	"go.mongodb.org/mongo-driver/v2/bson"
)

type MgoDecimal struct{}

var (
	_ bson.ValueEncoder = &MgoDecimal{}
	_ bson.ValueDecoder = &MgoDecimal{}
)

func (dc *MgoDecimal) EncodeValue(_ bson.EncodeContext, vw bson.ValueWriter, value reflect.Value) error {
	dec, ok := value.Interface().(decimal.Decimal)
	if !ok {
		return fmt.Errorf("value %v is not decimal.Decimal", value.Interface())
	}

	primDec, err := bson.ParseDecimal128(dec.String())
	if err != nil {
		return fmt.Errorf("decimal %v to Decimal128: %w", dec, err)
	}

	return vw.WriteDecimal128(primDec)
}

func (dc *MgoDecimal) DecodeValue(_ bson.DecodeContext, vr bson.ValueReader, value reflect.Value) error {
	primDec, err := vr.ReadDecimal128()
	if err != nil {
		return fmt.Errorf("read Decimal128: %w", err)
	}

	dec, err := decimal.NewFromString(primDec.String())
	if err != nil {
		return fmt.Errorf("Decimal128 %v to decimal: %w", primDec, err)
	}

	value.Set(reflect.ValueOf(dec))
	return nil
}
