package vo

import "fmt"

// Quantity is a value object representing a positive integer quantity.
type Quantity struct {
	value int
}

// NewQuantity creates a validated Quantity. Value must be positive (> 0).
func NewQuantity(v int) (Quantity, error) {
	if v <= 0 {
		return Quantity{}, fmt.Errorf("quantity must be positive, got %d", v)
	}
	return Quantity{value: v}, nil
}

// MustNewQuantity creates a Quantity, panicking on invalid input. Use only in tests.
func MustNewQuantity(v int) Quantity {
	q, err := NewQuantity(v)
	if err != nil {
		panic(err)
	}
	return q
}

// QuantityFromInt creates a Quantity from an int, allowing zero (for remaining qty tracking).
func QuantityFromInt(v int) Quantity {
	if v < 0 {
		v = 0
	}
	return Quantity{value: v}
}

// ZeroQuantity returns a zero quantity.
func ZeroQuantity() Quantity {
	return Quantity{value: 0}
}

// Int returns the underlying integer value.
func (q Quantity) Int() int {
	return q.value
}

// IsZero returns true if quantity is zero.
func (q Quantity) IsZero() bool {
	return q.value == 0
}

// IsPositive returns true if quantity is > 0.
func (q Quantity) IsPositive() bool {
	return q.value > 0
}

// Add returns a new Quantity that is the sum of two quantities.
func (q Quantity) Add(other Quantity) Quantity {
	return Quantity{value: q.value + other.value}
}

// Subtract returns a new Quantity, clamped to zero if result would be negative.
func (q Quantity) Subtract(other Quantity) Quantity {
	result := q.value - other.value
	if result < 0 {
		result = 0
	}
	return Quantity{value: result}
}

// Min returns the smaller of two quantities.
func (q Quantity) Min(other Quantity) Quantity {
	if q.value < other.value {
		return q
	}
	return other
}

// String returns a human-readable representation.
func (q Quantity) String() string {
	return fmt.Sprintf("%d", q.value)
}
