package cart

import (
	"fmt"

	messages "git.tornberg.me/go-cart-actor/pkg/messages"
)

// mutation_change_quantity.go
//
// Registers the ChangeQuantity mutation.
//
// Behavior:
//   - Locates an item by its cart-local line item Id (not source item_id).
//   - If requested quantity <= 0 the line is removed.
//   - Otherwise the line's Quantity field is updated.
//   - Totals are recalculated (WithTotals).
//
// Error handling:
//   - Returns an error if the item Id is not found.
//   - Returns an error if payload is nil (defensive).
//
// Concurrency:
//   - Uses the grain's RW-safe mutation pattern: we mutate in place under
//     the grain's implicit expectation that higher layers control access.
//     (If strict locking is required around every mutation, wrap logic in
//     an explicit g.mu.Lock()/Unlock(), but current model mirrors prior code.)

func ChangeQuantity(g *CartGrain, m *messages.ChangeQuantity) error {
	if m == nil {
		return fmt.Errorf("ChangeQuantity: nil payload")
	}

	foundIndex := -1
	for i, it := range g.Items {
		if it.Id == uint32(m.Id) {
			foundIndex = i
			break
		}
	}
	if foundIndex == -1 {
		return fmt.Errorf("ChangeQuantity: item id %d not found", m.Id)
	}

	if m.Quantity <= 0 {
		// Remove the item
		g.Items = append(g.Items[:foundIndex], g.Items[foundIndex+1:]...)
		g.UpdateTotals()
		return nil
	}

	g.Items[foundIndex].Quantity = int(m.Quantity)
	g.UpdateTotals()
	return nil
}
