package tradeskills

import (
	"sync"
	"time"
)

// TradeskillEvent represents a tradeskill event that can occur during crafting.
// Events require player counter-actions and affect crafting outcomes.
type TradeskillEvent struct {
	Name              string // Event name (max 250 characters)
	Icon              int16  // Icon ID for UI display
	Technique         uint32 // Associated technique/skill ID
	SuccessProgress   int16  // Progress gained on successful counter
	SuccessDurability int16  // Durability change on successful counter
	SuccessHP         int16  // HP change on successful counter
	SuccessPower      int16  // Power change on successful counter
	SuccessSpellID    uint32 // Spell cast on successful counter
	SuccessItemID     uint32 // Item given on successful counter
	FailProgress      int16  // Progress change on failed counter (can be negative)
	FailDurability    int16  // Durability change on failed counter (can be negative)
	FailHP            int16  // HP change on failed counter (can be negative)
	FailPower         int16  // Power change on failed counter (can be negative)
}

// Tradeskill represents an active crafting session for a player.
// Contains all state needed to track crafting progress and events.
type Tradeskill struct {
	PlayerID          uint32           // ID of the crafting player
	TableSpawnID      uint32           // ID of the crafting table spawn
	RecipeID          uint32           // ID of the recipe being crafted
	CurrentProgress   int32            // Current crafting progress (0-1000)
	CurrentDurability int32            // Current item durability (0-1000)
	NextUpdateTime    time.Time        // When the next crafting update should occur
	UsedComponents    []ComponentUsage // List of components being consumed
	CurrentEvent      *TradeskillEvent // Current active event (if any)
	EventChecked      bool             // Whether the current event has been checked/resolved
	EventCountered    bool             // Whether the current event was successfully countered
	StartTime         time.Time        // When crafting began
	LastUpdate        time.Time        // When crafting was last updated
}

// ComponentUsage tracks a component being used in crafting.
type ComponentUsage struct {
	ItemUniqueID uint32 // Unique ID of the item being used
	Quantity     int16  // Quantity being consumed
}

// TradeskillManager manages all active tradeskill sessions.
// Handles crafting updates, event processing, and session lifecycle.
type TradeskillManager struct {
	tradeskillList map[uint32]*Tradeskill // Map of player ID to their tradeskill session
	mutex          sync.RWMutex           // Protects concurrent access to tradeskillList

	// Configuration values (loaded from rules)
	critFailChance    float32 // Chance of critical failure
	critSuccessChance float32 // Chance of critical success
	failChance        float32 // Chance of regular failure
	successChance     float32 // Chance of regular success
	eventChance       float32 // Chance of triggering an event

	// Statistics
	stats TradeskillManagerStats
}

// TradeskillManagerStats tracks usage statistics for the tradeskill system.
type TradeskillManagerStats struct {
	ActiveSessions         int32     // Number of currently active crafting sessions
	TotalSessionsStarted   int32     // Total sessions started since startup
	TotalSessionsCompleted int32     // Total sessions completed since startup
	TotalSessionsCancelled int32     // Total sessions cancelled since startup
	TotalEventsTriggered   int32     // Total events triggered since startup
	TotalEventsCountered   int32     // Total events successfully countered since startup
	LastUpdate             time.Time // When stats were last updated
}

// MasterTradeskillEventsList manages all available tradeskill events.
// Events are organized by technique for efficient lookup during crafting.
type MasterTradeskillEventsList struct {
	eventList   map[uint32][]*TradeskillEvent // Map of technique ID to list of events
	mutex       sync.RWMutex                  // Protects concurrent access to eventList
	totalEvents int32                         // Total number of events loaded
}

// CraftingOutcome represents the result of a crafting update.
type CraftingOutcome struct {
	Success          bool             // Whether the crafting step was successful
	CriticalSuccess  bool             // Whether it was a critical success
	CriticalFailure  bool             // Whether it was a critical failure
	ProgressChange   int32            // Change in progress
	DurabilityChange int32            // Change in durability
	EventTriggered   *TradeskillEvent // Event that was triggered (if any)
	Completed        bool             // Whether crafting is now complete
	Failed           bool             // Whether crafting has failed
	ComponentsUsed   []ComponentUsage // Components consumed this update
}

// CraftingRequest represents a request to begin crafting.
type CraftingRequest struct {
	PlayerID     uint32           // ID of the player crafting
	RecipeID     uint32           // ID of the recipe to craft
	TableSpawnID uint32           // ID of the crafting table
	Components   []ComponentUsage // Components to use for crafting
	Quantity     int32            // Quantity to craft (for mass production)
}

// EventCounterRequest represents a player's attempt to counter a tradeskill event.
type EventCounterRequest struct {
	PlayerID  uint32 // ID of the player attempting the counter
	SpellIcon int16  // Icon of the spell/ability used to counter
}

// TradeskillStats provides detailed statistics about tradeskill usage.
type TradeskillStats struct {
	TotalEvents        int32            // Total events in master list
	EventsByTechnique  map[uint32]int32 // Number of events per technique
	ActiveSessions     int32            // Currently active crafting sessions
	RecentCompletions  int32            // Completions in last hour
	AverageSessionTime time.Duration    // Average time per crafting session
}

// Copy creates a deep copy of a TradeskillEvent.
func (te *TradeskillEvent) Copy() *TradeskillEvent {
	if te == nil {
		return nil
	}

	return &TradeskillEvent{
		Name:              te.Name,
		Icon:              te.Icon,
		Technique:         te.Technique,
		SuccessProgress:   te.SuccessProgress,
		SuccessDurability: te.SuccessDurability,
		SuccessHP:         te.SuccessHP,
		SuccessPower:      te.SuccessPower,
		SuccessSpellID:    te.SuccessSpellID,
		SuccessItemID:     te.SuccessItemID,
		FailProgress:      te.FailProgress,
		FailDurability:    te.FailDurability,
		FailHP:            te.FailHP,
		FailPower:         te.FailPower,
	}
}

// IsValidTechnique checks if the given technique ID is valid.
func IsValidTechnique(technique uint32) bool {
	validTechniques := map[uint32]bool{
		TechniqueSkillFletching:     true,
		TechniqueSkillTailoring:     true,
		TechniqueSkillTransmuting:   true,
		TechniqueSkillAlchemy:       true,
		TechniqueSkillScribing:      true,
		TechniqueSkillJewelcrafting: true,
		TechniqueSkillProvisioning:  true,
		TechniqueSkillArtistry:      true,
		TechniqueSkillCarpentry:     true,
		TechniqueSkillMetalworking:  true,
		TechniqueSkillMetalshaping:  true,
		TechniqueSkillStoneworking:  true,
	}

	return validTechniques[technique]
}

// IsComplete checks if the tradeskill session has completed successfully.
func (ts *Tradeskill) IsComplete() bool {
	return ts.CurrentProgress >= MaxProgress
}

// IsFailed checks if the tradeskill session has failed (durability reached zero).
func (ts *Tradeskill) IsFailed() bool {
	return ts.CurrentDurability <= MinDurability
}

// NeedsUpdate checks if the tradeskill session needs to be updated.
func (ts *Tradeskill) NeedsUpdate() bool {
	return time.Now().After(ts.NextUpdateTime)
}

// Reset resets the tradeskill session to initial state.
func (ts *Tradeskill) Reset() {
	ts.CurrentProgress = MinProgress
	ts.CurrentDurability = MaxDurability
	ts.CurrentEvent = nil
	ts.EventChecked = false
	ts.EventCountered = false
	ts.UsedComponents = nil
	ts.StartTime = time.Now()
	ts.LastUpdate = time.Now()
	ts.NextUpdateTime = time.Now().Add(CraftingUpdateInterval)
}
