package items

import (
	"fmt"

	nigiri "git.sharkk.net/Sharkk/Nigiri"
)

// Item represents an item in the game
type Item struct {
	ID      int    `json:"id"`
	Type    int    `json:"type" db:"index"`
	Name    string `json:"name" db:"required"`
	Value   int    `json:"value"`
	Att     int    `json:"att"`
	Special string `json:"special"`
}

// ItemType constants for item types
const (
	TypeWeapon = 1
	TypeArmor  = 2
	TypeShield = 3
)

// Global store
var store *nigiri.BaseStore[Item]

// Init sets up the Nigiri store and indices
func Init(collection *nigiri.Collection) {
	store = nigiri.NewBaseStore[Item]()

	// Register custom indices
	store.RegisterIndex("byType", nigiri.BuildIntGroupIndex(func(i *Item) int {
		return i.Type
	}))

	store.RegisterIndex("allByID", nigiri.BuildSortedListIndex(func(a, b *Item) bool {
		return a.ID < b.ID
	}))

	store.RebuildIndices()
}

// GetStore returns the items store
func GetStore() *nigiri.BaseStore[Item] {
	if store == nil {
		panic("items store not initialized - call Initialize first")
	}
	return store
}

// Creates a new Item with sensible defaults
func New() *Item {
	return &Item{
		Type:    TypeWeapon, // Default to weapon
		Name:    "",
		Value:   0,
		Att:     0,
		Special: "",
	}
}

// Validate checks if item has valid values
func (i *Item) Validate() error {
	if i.Name == "" {
		return fmt.Errorf("item name cannot be empty")
	}
	if i.Type < TypeWeapon || i.Type > TypeShield {
		return fmt.Errorf("invalid item type: %d", i.Type)
	}
	if i.Value < 0 {
		return fmt.Errorf("item Value cannot be negative")
	}
	if i.Att < 0 {
		return fmt.Errorf("item Att cannot be negative")
	}
	return nil
}

// CRUD operations
func (i *Item) Save() error {
	if i.ID == 0 {
		id, err := store.Create(i)
		if err != nil {
			return err
		}
		i.ID = id
		return nil
	}
	return store.Update(i.ID, i)
}

func (i *Item) Delete() error {
	store.Remove(i.ID)
	return nil
}

// Insert with ID assignment
func (i *Item) Insert() error {
	id, err := store.Create(i)
	if err != nil {
		return err
	}
	i.ID = id
	return nil
}

// Query functions
func Find(id int) (*Item, error) {
	item, exists := store.Find(id)
	if !exists {
		return nil, fmt.Errorf("item with ID %d not found", id)
	}
	return item, nil
}

func All() ([]*Item, error) {
	return store.AllSorted("allByID"), nil
}

func ByType(itemType int) ([]*Item, error) {
	return store.GroupByIndex("byType", itemType), nil
}

// Helper methods
func (i *Item) IsWeapon() bool {
	return i.Type == TypeWeapon
}

func (i *Item) IsArmor() bool {
	return i.Type == TypeArmor
}

func (i *Item) IsShield() bool {
	return i.Type == TypeShield
}

func (i *Item) TypeName() string {
	switch i.Type {
	case TypeWeapon:
		return "Weapon"
	case TypeArmor:
		return "Armor"
	case TypeShield:
		return "Shield"
	default:
		return "Unknown"
	}
}

func (i *Item) HasSpecial() bool {
	return i.Special != ""
}

func (i *Item) IsEquippable() bool {
	return i.Type == TypeWeapon || i.Type == TypeArmor || i.Type == TypeShield
}

// Legacy compatibility functions (will be removed later)
func LoadData(dataPath string) error {
	// No longer needed - Nigiri handles this
	return nil
}

func SaveData(dataPath string) error {
	// No longer needed - Nigiri handles this
	return nil
}
