package shared

import (
	"math"
	"math/big"
	"strings"

	"github.com/tech/sendico/pkg/merrors"
)

var (
	errHexEmpty      = merrors.InvalidArgument("hex value is empty")
	errHexInvalid    = merrors.InvalidArgument("invalid hex number")
	errHexOutOfRange = merrors.InvalidArgument("hex number out of range")
)

// DecodeHexBig parses a hex string that may include leading zero digits.
func DecodeHexBig(input string) (*big.Int, error) {
	trimmed := strings.TrimSpace(input)
	if trimmed == "" {
		return nil, errHexEmpty
	}
	noPrefix := strings.TrimPrefix(trimmed, "0x")
	if noPrefix == "" {
		return nil, errHexEmpty
	}
	value := strings.TrimLeft(noPrefix, "0")
	if value == "" {
		return big.NewInt(0), nil
	}
	val := new(big.Int)
	if _, ok := val.SetString(value, 16); !ok {
		return nil, errHexInvalid
	}
	return val, nil
}

// DecodeHexUint8 parses a hex string into uint8, allowing leading zeros.
func DecodeHexUint8(input string) (uint8, error) {
	val, err := DecodeHexBig(input)
	if err != nil {
		return 0, err
	}
	if val == nil {
		return 0, errHexInvalid
	}
	if val.BitLen() > 8 {
		return 0, errHexOutOfRange
	}
	decoded := val.Uint64()
	if decoded > math.MaxUint8 {
		return 0, errHexOutOfRange
	}
	return uint8(decoded), nil
}
