package items

import (
	"sync"
	"time"
)

// Item effect types
type ItemEffectType int

const (
	NoEffectType            ItemEffectType = 0
	EffectCureTypeTrauma    ItemEffectType = 1
	EffectCureTypeArcane    ItemEffectType = 2
	EffectCureTypeNoxious   ItemEffectType = 3
	EffectCureTypeElemental ItemEffectType = 4
	EffectCureTypeCurse     ItemEffectType = 5
	EffectCureTypeMagic     ItemEffectType = 6
	EffectCureTypeAll       ItemEffectType = 7
)

// Inventory slot types
type InventorySlotType int

const (
	HouseVault         InventorySlotType = -5
	SharedBank         InventorySlotType = -4
	Bank               InventorySlotType = -3
	Overflow           InventorySlotType = -2
	UnknownInvSlotType InventorySlotType = -1
	BaseInventory      InventorySlotType = 0
)

// Lock reasons for items
type LockReason uint32

const (
	LockReasonNone     LockReason = 0
	LockReasonHouse    LockReason = 1 << 0
	LockReasonCrafting LockReason = 1 << 1
	LockReasonShop     LockReason = 1 << 2
)

// Add item types for tracking how items were added
type AddItemType int

const (
	NotSet        AddItemType = 0
	BuyFromBroker AddItemType = 1
	GMCommand     AddItemType = 2
)

// ItemStatsValues represents the complete stat bonuses from an item
type ItemStatsValues struct {
	// Base stats
	Str int16 `json:"str"`
	Sta int16 `json:"sta"`
	Agi int16 `json:"agi"`
	Wis int16 `json:"wis"`
	Int int16 `json:"int"`
	
	// Resistances
	VsSlash    int16 `json:"vs_slash"`
	VsCrush    int16 `json:"vs_crush"`
	VsPierce   int16 `json:"vs_pierce"`
	VsPhysical int16 `json:"vs_physical"`
	VsHeat     int16 `json:"vs_heat"`
	VsCold     int16 `json:"vs_cold"`
	VsMagic    int16 `json:"vs_magic"`
	VsMental   int16 `json:"vs_mental"`
	VsDivine   int16 `json:"vs_divine"`
	VsDisease  int16 `json:"vs_disease"`
	VsPoison   int16 `json:"vs_poison"`
	
	// Pools
	Health        int16 `json:"health"`
	Power         int16 `json:"power"`
	Concentration int8  `json:"concentration"`
	
	// Abilities and damage
	AbilityModifier        int16 `json:"ability_modifier"`
	CriticalMitigation     int16 `json:"critical_mitigation"`
	ExtraShieldBlockChance int16 `json:"extra_shield_block_chance"`
	BeneficialCritChance   int16 `json:"beneficial_crit_chance"`
	CritBonus              int16 `json:"crit_bonus"`
	Potency                int16 `json:"potency"`
	HateGainMod            int16 `json:"hate_gain_mod"`
	AbilityReuseSpeed      int16 `json:"ability_reuse_speed"`
	AbilityCastingSpeed    int16 `json:"ability_casting_speed"`
	AbilityRecoverySpeed   int16 `json:"ability_recovery_speed"`
	SpellReuseSpeed        int16 `json:"spell_reuse_speed"`
	SpellMultiAttackChance int16 `json:"spell_multi_attack_chance"`
	DPS                    int16 `json:"dps"`
	AttackSpeed            int16 `json:"attack_speed"`
	MultiAttackChance      int16 `json:"multi_attack_chance"`
	Flurry                 int16 `json:"flurry"`
	AEAutoattackChance     int16 `json:"ae_autoattack_chance"`
	Strikethrough          int16 `json:"strikethrough"`
	Accuracy               int16 `json:"accuracy"`
	OffensiveSpeed         int16 `json:"offensive_speed"`
	
	// Uncontested stats
	UncontestedParry   float32 `json:"uncontested_parry"`
	UncontestedBlock   float32 `json:"uncontested_block"`
	UncontestedDodge   float32 `json:"uncontested_dodge"`
	UncontestedRiposte float32 `json:"uncontested_riposte"`
	
	// Other
	SizeMod float32 `json:"size_mod"`
}

// ItemCore contains the core data for an item instance
type ItemCore struct {
	ItemID           int32 `json:"item_id"`
	SOEId            int32 `json:"soe_id"`
	BagID            int32 `json:"bag_id"`
	InvSlotID        int32 `json:"inv_slot_id"`
	SlotID           int16 `json:"slot_id"`
	EquipSlotID      int16 `json:"equip_slot_id"`   // used when a bag is equipped
	AppearanceType   int16 `json:"appearance_type"` // 0 for combat armor, 1 for appearance armor
	Index            int8  `json:"index"`
	Icon             int16 `json:"icon"`
	ClassicIcon      int16 `json:"classic_icon"`
	Count            int16 `json:"count"`
	Tier             int8  `json:"tier"`
	NumSlots         int8  `json:"num_slots"`
	UniqueID         int64 `json:"unique_id"`
	NumFreeSlots     int8  `json:"num_free_slots"`
	RecommendedLevel int16 `json:"recommended_level"`
	ItemLocked       bool  `json:"item_locked"`
	LockFlags        int32 `json:"lock_flags"`
	NewItem          bool  `json:"new_item"`
	NewIndex         int16 `json:"new_index"`
}

// ItemStat represents a single stat on an item
type ItemStat struct {
	StatName         string  `json:"stat_name"`
	StatType         int32   `json:"stat_type"`
	StatSubtype      int16   `json:"stat_subtype"`
	StatTypeCombined int16   `json:"stat_type_combined"`
	Value            float32 `json:"value"`
	Level            int8    `json:"level"`
}

// ItemSet represents an item set piece
type ItemSet struct {
	ItemID        int32  `json:"item_id"`
	ItemCRC       int32  `json:"item_crc"`
	ItemIcon      int16  `json:"item_icon"`
	ItemStackSize int16  `json:"item_stack_size"`
	ItemListColor int32  `json:"item_list_color"`
	Name          string `json:"name"`
	Language      int8   `json:"language"`
}

// Classifications represents item classifications
type Classifications struct {
	ClassificationID   int32  `json:"classification_id"`
	ClassificationName string `json:"classification_name"`
}

// ItemLevelOverride represents level overrides for specific classes
type ItemLevelOverride struct {
	AdventureClass  int8  `json:"adventure_class"`
	TradeskillClass int8  `json:"tradeskill_class"`
	Level           int16 `json:"level"`
}

// ItemClass represents class requirements for an item
type ItemClass struct {
	AdventureClass  int8  `json:"adventure_class"`
	TradeskillClass int8  `json:"tradeskill_class"`
	Level           int16 `json:"level"`
}

// ItemAppearance represents visual appearance data
type ItemAppearance struct {
	Type           int16 `json:"type"`
	Red            int8  `json:"red"`
	Green          int8  `json:"green"`
	Blue           int8  `json:"blue"`
	HighlightRed   int8  `json:"highlight_red"`
	HighlightGreen int8  `json:"highlight_green"`
	HighlightBlue  int8  `json:"highlight_blue"`
}

// QuestRewardData represents quest reward information
type QuestRewardData struct {
	QuestID      int32  `json:"quest_id"`
	IsTemporary  bool   `json:"is_temporary"`
	Description  string `json:"description"`
	IsCollection bool   `json:"is_collection"`
	HasDisplayed bool   `json:"has_displayed"`
	TmpCoin      int64  `json:"tmp_coin"`
	TmpStatus    int32  `json:"tmp_status"`
	DbSaved      bool   `json:"db_saved"`
	DbIndex      int32  `json:"db_index"`
}

// Generic_Info contains general item information
type GenericInfo struct {
	ShowName                 int8   `json:"show_name"`
	CreatorFlag              int8   `json:"creator_flag"`
	ItemFlags                int16  `json:"item_flags"`
	ItemFlags2               int16  `json:"item_flags2"`
	Condition                int8   `json:"condition"`
	Weight                   int32  `json:"weight"` // num/10
	SkillReq1                int32  `json:"skill_req1"`
	SkillReq2                int32  `json:"skill_req2"`
	SkillMin                 int16  `json:"skill_min"`
	ItemType                 int8   `json:"item_type"`
	AppearanceID             int16  `json:"appearance_id"`
	AppearanceRed            int8   `json:"appearance_red"`
	AppearanceGreen          int8   `json:"appearance_green"`
	AppearanceBlue           int8   `json:"appearance_blue"`
	AppearanceHighlightRed   int8   `json:"appearance_highlight_red"`
	AppearanceHighlightGreen int8   `json:"appearance_highlight_green"`
	AppearanceHighlightBlue  int8   `json:"appearance_highlight_blue"`
	Collectable              int8   `json:"collectable"`
	OffersQuestID            int32  `json:"offers_quest_id"`
	PartOfQuestID            int32  `json:"part_of_quest_id"`
	MaxCharges               int16  `json:"max_charges"`
	DisplayCharges           int8   `json:"display_charges"`
	AdventureClasses         int64  `json:"adventure_classes"`
	TradeskillClasses        int64  `json:"tradeskill_classes"`
	AdventureDefaultLevel    int16  `json:"adventure_default_level"`
	TradeskillDefaultLevel   int16  `json:"tradeskill_default_level"`
	Usable                   int8   `json:"usable"`
	Harvest                  int8   `json:"harvest"`
	BodyDrop                 int8   `json:"body_drop"`
	PvPDescription           int8   `json:"pvp_description"`
	MercOnly                 int8   `json:"merc_only"`
	MountOnly                int8   `json:"mount_only"`
	SetID                    int32  `json:"set_id"`
	CollectableUnk           int8   `json:"collectable_unk"`
	OffersQuestName          string `json:"offers_quest_name"`
	RequiredByQuestName      string `json:"required_by_quest_name"`
	TransmutedMaterial       int8   `json:"transmuted_material"`
}

// ArmorInfo contains armor-specific information
type ArmorInfo struct {
	MitigationLow  int16 `json:"mitigation_low"`
	MitigationHigh int16 `json:"mitigation_high"`
}

// AdornmentInfo contains adornment-specific information
type AdornmentInfo struct {
	Duration  float32 `json:"duration"`
	ItemTypes int16   `json:"item_types"`
	SlotType  int16   `json:"slot_type"`
}

// WeaponInfo contains weapon-specific information
type WeaponInfo struct {
	WieldType   int16   `json:"wield_type"`
	DamageLow1  int16   `json:"damage_low1"`
	DamageHigh1 int16   `json:"damage_high1"`
	DamageLow2  int16   `json:"damage_low2"`
	DamageHigh2 int16   `json:"damage_high2"`
	DamageLow3  int16   `json:"damage_low3"`
	DamageHigh3 int16   `json:"damage_high3"`
	Delay       int16   `json:"delay"`
	Rating      float32 `json:"rating"`
}

// ShieldInfo contains shield-specific information
type ShieldInfo struct {
	ArmorInfo ArmorInfo `json:"armor_info"`
}

// RangedInfo contains ranged weapon information
type RangedInfo struct {
	WeaponInfo WeaponInfo `json:"weapon_info"`
	RangeLow   int16      `json:"range_low"`
	RangeHigh  int16      `json:"range_high"`
}

// BagInfo contains bag-specific information
type BagInfo struct {
	NumSlots        int8  `json:"num_slots"`
	WeightReduction int16 `json:"weight_reduction"`
}

// FoodInfo contains food/drink information
type FoodInfo struct {
	Type      int8    `json:"type"` // 0=water, 1=food
	Level     int8    `json:"level"`
	Duration  float32 `json:"duration"`
	Satiation int8    `json:"satiation"`
}

// BaubleInfo contains bauble-specific information
type BaubleInfo struct {
	Cast                  int16   `json:"cast"`
	Recovery              int16   `json:"recovery"`
	Duration              int32   `json:"duration"`
	Recast                float32 `json:"recast"`
	DisplaySlotOptional   int8    `json:"display_slot_optional"`
	DisplayCastTime       int8    `json:"display_cast_time"`
	DisplayBaubleType     int8    `json:"display_bauble_type"`
	EffectRadius          float32 `json:"effect_radius"`
	MaxAOETargets         int32   `json:"max_aoe_targets"`
	DisplayUntilCancelled int8    `json:"display_until_cancelled"`
}

// BookInfo contains book-specific information
type BookInfo struct {
	Language int8   `json:"language"`
	Author   string `json:"author"`
	Title    string `json:"title"`
}

// BookInfoPages represents a book page
type BookInfoPages struct {
	Page           int8   `json:"page"`
	PageText       string `json:"page_text"`
	PageTextVAlign int8   `json:"page_text_valign"`
	PageTextHAlign int8   `json:"page_text_halign"`
}

// SkillInfo contains skill book information
type SkillInfo struct {
	SpellID   int32 `json:"spell_id"`
	SpellTier int32 `json:"spell_tier"`
}

// HouseItemInfo contains house item information
type HouseItemInfo struct {
	StatusRentReduction int32   `json:"status_rent_reduction"`
	CoinRentReduction   float32 `json:"coin_rent_reduction"`
	HouseOnly           int8    `json:"house_only"`
	HouseLocation       int8    `json:"house_location"` // 0 = floor, 1 = ceiling, 2 = wall
}

// HouseContainerInfo contains house container information
type HouseContainerInfo struct {
	AllowedTypes     int64 `json:"allowed_types"`
	NumSlots         int8  `json:"num_slots"`
	BrokerCommission int8  `json:"broker_commission"`
	FenceCommission  int8  `json:"fence_commission"`
}

// RecipeBookInfo contains recipe book information
type RecipeBookInfo struct {
	Recipes  []uint32 `json:"recipes"`
	RecipeID int32    `json:"recipe_id"`
	Uses     int8     `json:"uses"`
}

// ItemSetInfo contains item set information
type ItemSetInfo struct {
	ItemID             int32 `json:"item_id"`
	ItemCRC            int32 `json:"item_crc"`
	ItemIcon           int16 `json:"item_icon"`
	ItemStackSize      int32 `json:"item_stack_size"`
	ItemListColor      int32 `json:"item_list_color"`
	SOEItemIDUnsigned  int32 `json:"soe_item_id_unsigned"`
	SOEItemCRCUnsigned int32 `json:"soe_item_crc_unsigned"`
}

// ThrownInfo contains thrown weapon information
type ThrownInfo struct {
	Range          int32   `json:"range"`
	DamageModifier int32   `json:"damage_modifier"`
	HitBonus       float32 `json:"hit_bonus"`
	DamageType     int32   `json:"damage_type"`
}

// ItemEffect represents an item effect
type ItemEffect struct {
	Effect        string `json:"effect"`
	Percentage    int8   `json:"percentage"`
	SubBulletFlag int8   `json:"sub_bullet_flag"`
}

// BookPage represents a book page
type BookPage struct {
	Page     int8   `json:"page"`
	PageText string `json:"page_text"`
	VAlign   int8   `json:"valign"`
	HAlign   int8   `json:"halign"`
}

// ItemStatString represents a string-based item stat
type ItemStatString struct {
	StatString string `json:"stat_string"`
}

// Item represents a complete item with all its properties
type Item struct {
	// Basic item information
	LowerName    string `json:"lower_name"`
	Name         string `json:"name"`
	Description  string `json:"description"`
	StackCount   int16  `json:"stack_count"`
	SellPrice    int32  `json:"sell_price"`
	SellStatus   int32  `json:"sell_status"`
	MaxSellValue int32  `json:"max_sell_value"`
	BrokerPrice  int64  `json:"broker_price"`

	// Search and state flags
	IsSearchStoreItem   bool `json:"is_search_store_item"`
	IsSearchInInventory bool `json:"is_search_in_inventory"`
	SaveNeeded          bool `json:"save_needed"`
	NoBuyBack           bool `json:"no_buy_back"`
	NoSale              bool `json:"no_sale"`
	NeedsDeletion       bool `json:"needs_deletion"`
	Crafted             bool `json:"crafted"`
	Tinkered            bool `json:"tinkered"`

	// Item metadata
	WeaponType     int8           `json:"weapon_type"`
	Adornment      string         `json:"adornment"`
	Creator        string         `json:"creator"`
	SellerName     string         `json:"seller_name"`
	SellerCharID   int32          `json:"seller_char_id"`
	SellerHouseID  int64          `json:"seller_house_id"`
	Created        time.Time      `json:"created"`
	GroupedCharIDs map[int32]bool `json:"grouped_char_ids"`
	EffectType     ItemEffectType `json:"effect_type"`
	BookLanguage   int8           `json:"book_language"`

	// Adornment slots
	Adorn0 int32 `json:"adorn0"`
	Adorn1 int32 `json:"adorn1"`
	Adorn2 int32 `json:"adorn2"`

	// Spell information
	SpellID    int32  `json:"spell_id"`
	SpellTier  int8   `json:"spell_tier"`
	ItemScript string `json:"item_script"`

	// Collections and arrays
	Classifications    []*Classifications   `json:"classifications"`
	ItemStats          []*ItemStat          `json:"item_stats"`
	ItemSets           []*ItemSet           `json:"item_sets"`
	ItemStringStats    []*ItemStatString    `json:"item_string_stats"`
	ItemLevelOverrides []*ItemLevelOverride `json:"item_level_overrides"`
	ItemEffects        []*ItemEffect        `json:"item_effects"`
	BookPages          []*BookPage          `json:"book_pages"`
	SlotData           []int8               `json:"slot_data"`

	// Core item data
	Details     ItemCore    `json:"details"`
	GenericInfo GenericInfo `json:"generic_info"`

	// Type-specific information (pointers to allow nil for unused types)
	WeaponInfo         *WeaponInfo         `json:"weapon_info,omitempty"`
	RangedInfo         *RangedInfo         `json:"ranged_info,omitempty"`
	ArmorInfo          *ArmorInfo          `json:"armor_info,omitempty"`
	AdornmentInfo      *AdornmentInfo      `json:"adornment_info,omitempty"`
	BagInfo            *BagInfo            `json:"bag_info,omitempty"`
	FoodInfo           *FoodInfo           `json:"food_info,omitempty"`
	BaubleInfo         *BaubleInfo         `json:"bauble_info,omitempty"`
	BookInfo           *BookInfo           `json:"book_info,omitempty"`
	BookInfoPages      *BookInfoPages      `json:"book_info_pages,omitempty"`
	HouseItemInfo      *HouseItemInfo      `json:"house_item_info,omitempty"`
	HouseContainerInfo *HouseContainerInfo `json:"house_container_info,omitempty"`
	SkillInfo          *SkillInfo          `json:"skill_info,omitempty"`
	RecipeBookInfo     *RecipeBookInfo     `json:"recipe_book_info,omitempty"`
	ItemSetInfo        *ItemSetInfo        `json:"item_set_info,omitempty"`
	ThrownInfo         *ThrownInfo         `json:"thrown_info,omitempty"`

	// Thread safety
	mutex sync.RWMutex
}

// MasterItemList manages all items in the game
type MasterItemList struct {
	items                  map[int32]*Item                   `json:"items"`
	mappedItemStatsStrings map[string]int32                  `json:"mapped_item_stats_strings"`
	mappedItemStatTypeIDs  map[int32]string                  `json:"mapped_item_stat_type_ids"`
	brokerItemMap          map[*VersionRange]map[int64]int64 `json:"-"` // Complex type, exclude from JSON
	mutex                  sync.RWMutex
}

// VersionRange represents a version range for broker item mapping
type VersionRange struct {
	MinVersion int32 `json:"min_version"`
	MaxVersion int32 `json:"max_version"`
}

// PlayerItemList manages a player's inventory
type PlayerItemList struct {
	maxSavedIndex int32                              `json:"max_saved_index"`
	indexedItems  map[int32]*Item                    `json:"indexed_items"`
	items         map[int32]map[int8]map[int16]*Item `json:"items"`
	overflowItems []*Item                            `json:"overflow_items"`
	packetCount   int16                              `json:"packet_count"`
	xorPacket     []byte                             `json:"-"` // Exclude from JSON
	origPacket    []byte                             `json:"-"` // Exclude from JSON
	mutex         sync.RWMutex
}

// EquipmentItemList manages equipped items for a character
type EquipmentItemList struct {
	items          [NumSlots]*Item `json:"items"`
	appearanceType int8            `json:"appearance_type"` // 0 for normal equip, 1 for appearance
	xorPacket      []byte          `json:"-"`               // Exclude from JSON
	origPacket     []byte          `json:"-"`               // Exclude from JSON
	mutex          sync.RWMutex
}

// ItemManagerStats represents statistics about item management
type ItemManagerStats struct {
	TotalItems            int32          `json:"total_items"`
	ItemsByType           map[int8]int32 `json:"items_by_type"`
	ItemsByTier           map[int8]int32 `json:"items_by_tier"`
	PlayersWithItems      int32          `json:"players_with_items"`
	TotalItemInstances    int64          `json:"total_item_instances"`
	AverageItemsPerPlayer float32        `json:"average_items_per_player"`
	LastUpdate            time.Time      `json:"last_update"`
}

// ItemSearchCriteria represents search criteria for items
type ItemSearchCriteria struct {
	Name               string            `json:"name"`
	ItemType           int64             `json:"item_type"`
	LocationType       int64             `json:"location_type"`
	BrokerType         int64             `json:"broker_type"`
	MinPrice           int64             `json:"min_price"`
	MaxPrice           int64             `json:"max_price"`
	MinSkill           int8              `json:"min_skill"`
	MaxSkill           int8              `json:"max_skill"`
	Seller             string            `json:"seller"`
	Adornment          string            `json:"adornment"`
	MinTier            int8              `json:"min_tier"`
	MaxTier            int8              `json:"max_tier"`
	MinLevel           int16             `json:"min_level"`
	MaxLevel           int16             `json:"max_level"`
	ItemClass          int8              `json:"item_class"`
	AdditionalCriteria map[string]string `json:"additional_criteria"`
}

// ItemValidationResult represents the result of item validation
type ItemValidationResult struct {
	Valid  bool     `json:"valid"`
	Errors []string `json:"errors,omitempty"`
}

// ItemError represents an item-specific error
type ItemError struct {
	message string
}

func (e *ItemError) Error() string {
	return e.message
}

// NewItemError creates a new item error
func NewItemError(message string) *ItemError {
	return &ItemError{message: message}
}

// IsItemError checks if an error is an ItemError
func IsItemError(err error) bool {
	_, ok := err.(*ItemError)
	return ok
}

// Common item errors
var (
	ErrItemNotFound      = NewItemError("item not found")
	ErrInvalidItem       = NewItemError("invalid item")
	ErrItemLocked        = NewItemError("item is locked")
	ErrInsufficientSpace = NewItemError("insufficient inventory space")
	ErrCannotEquip       = NewItemError("cannot equip item")
	ErrCannotTrade       = NewItemError("cannot trade item")
	ErrItemExpired       = NewItemError("item has expired")
)
