package ground_spawn

// Database interface for ground spawn persistence
type Database interface {
	LoadGroundSpawnEntries(groundspawnID int32) ([]*GroundSpawnEntry, error)
	LoadGroundSpawnItems(groundspawnID int32) ([]*GroundSpawnEntryItem, error)
	SaveGroundSpawn(gs *GroundSpawn) error
	LoadAllGroundSpawns() ([]*GroundSpawn, error)
	DeleteGroundSpawn(id int32) error
}

// Logger interface for ground spawn logging
type Logger interface {
	LogInfo(message string, args ...interface{})
	LogError(message string, args ...interface{})
	LogDebug(message string, args ...interface{})
	LogWarning(message string, args ...interface{})
}

// Player interface for ground spawn interactions
type Player interface {
	GetID() int32
	GetName() string
	GetLevel() int16
	GetLocation() int32
	GetSkillByName(skillName string) *Skill
	CheckQuestsHarvestUpdate(item *Item, quantity int16)
	UpdatePlayerStatistic(statType int32, amount int32)
	SendMessage(message string)
}

// Client interface for client communication
type Client interface {
	GetPlayer() *Player
	GetVersion() int16
	GetLogger() Logger
	GetCurrentZoneID() int32
	Message(channel int32, message string, args ...interface{})
	SimpleMessage(channel int32, message string)
	SendPopupMessage(type_ int32, message string, sound string, duration float32, r, g, b int32)
	AddItem(item *Item, itemDeleted *bool) error
}

// Skill interface for skill management
type Skill interface {
	GetCurrentValue() int16
	GetMaxValue() int16
	GetName() string
	IncreaseSkill(amount int16) bool
}

// Item interface for harvest rewards
type Item interface {
	GetID() int32
	GetName() string
	GetCount() int16
	SetCount(count int16)
	CreateItemLink(version int16, color bool) string
}

// Zone interface for zone-specific operations
type Zone interface {
	GetID() int32
	GetGroundSpawnEntries(groundspawnID int32) []*GroundSpawnEntry
	GetGroundSpawnEntryItems(groundspawnID int32) []*GroundSpawnEntryItem
	ProcessSpell(spell *Spell, caster *Player, target *Player, harvest bool, fromItem bool)
	ProcessEntityCommand(command *EntityCommand, player *Player, target *Player)
}

// Spell interface for harvest spells
type Spell interface {
	GetID() int32
	GetName() string
	GetType() string
}

// EntityCommand interface for ground spawn commands
type EntityCommand interface {
	GetID() int32
	GetName() string
	GetCommand() string
}

// Rules interface for game rules and configuration
type Rules interface {
	GetZoneRule(zoneID int32, category string, ruleName string) *Rule
}

// Rule interface for individual rule values
type Rule interface {
	GetInt16() int16
	GetFloat() float32
	GetBool() bool
	GetString() string
}

// GroundSpawnProvider interface for systems that provide ground spawn functionality
type GroundSpawnProvider interface {
	GetGroundSpawn(id int32) *GroundSpawn
	CreateGroundSpawn(config GroundSpawnConfig) *GroundSpawn
	GetGroundSpawnsByZone(zoneID int32) []*GroundSpawn
	ProcessHarvest(gs *GroundSpawn, player *Player) (*HarvestResult, error)
}

// HarvestHandler interface for handling harvest events
type HarvestHandler interface {
	OnHarvestStart(gs *GroundSpawn, player *Player) error
	OnHarvestComplete(gs *GroundSpawn, player *Player, result *HarvestResult) error
	OnHarvestFailed(gs *GroundSpawn, player *Player, reason string) error
	OnGroundSpawnDepleted(gs *GroundSpawn) error
}

// ItemProvider interface for item creation and management
type ItemProvider interface {
	GetItem(itemID int32) *Item
	CreateItem(itemID int32, quantity int16) *Item
	GetItemName(itemID int32) string
}

// SkillProvider interface for skill management
type SkillProvider interface {
	GetPlayerSkill(player *Player, skillName string) *Skill
	GetSkillIDByName(skillName string) int32
	IncreasePlayerSkill(player *Player, skillName string, amount int16) bool
}

// SpawnProvider interface for spawn system integration
type SpawnProvider interface {
	CreateSpawn() interface{}
	GetSpawn(id int32) interface{}
	RegisterGroundSpawn(gs *GroundSpawn) error
	UnregisterGroundSpawn(id int32) error
}

// GroundSpawnAware interface for entities that can interact with ground spawns
type GroundSpawnAware interface {
	CanHarvest(gs *GroundSpawn) bool
	GetHarvestSkill(skillName string) *Skill
	GetHarvestModifiers() *HarvestModifiers
	OnHarvestResult(result *HarvestResult)
}

// PlayerGroundSpawnAdapter provides ground spawn functionality for players
type PlayerGroundSpawnAdapter struct {
	player  *Player
	manager *Manager
	logger  Logger
}

// NewPlayerGroundSpawnAdapter creates a new player ground spawn adapter
func NewPlayerGroundSpawnAdapter(player *Player, manager *Manager, logger Logger) *PlayerGroundSpawnAdapter {
	return &PlayerGroundSpawnAdapter{
		player:  player,
		manager: manager,
		logger:  logger,
	}
}

// CanHarvest returns true if the player can harvest the ground spawn
func (pgsa *PlayerGroundSpawnAdapter) CanHarvest(gs *GroundSpawn) bool {
	if gs == nil || pgsa.player == nil {
		return false
	}

	// Check if ground spawn is available
	if !gs.IsAvailable() {
		return false
	}

	// Check if player has required skill
	skill := pgsa.player.GetSkillByName(gs.GetCollectionSkill())
	if skill == nil {
		return false
	}

	// TODO: Add additional checks (quest requirements, level, etc.)

	return true
}

// GetHarvestSkill returns the player's skill for a specific harvest type
func (pgsa *PlayerGroundSpawnAdapter) GetHarvestSkill(skillName string) *Skill {
	if pgsa.player == nil {
		return nil
	}

	return pgsa.player.GetSkillByName(skillName)
}

// GetHarvestModifiers returns harvest modifiers for the player
func (pgsa *PlayerGroundSpawnAdapter) GetHarvestModifiers() *HarvestModifiers {
	// TODO: Calculate modifiers based on player stats, equipment, buffs, etc.
	return &HarvestModifiers{
		SkillMultiplier:    1.0,
		RareChanceBonus:    0.0,
		QuantityMultiplier: 1.0,
		LuckModifier:       0,
	}
}

// OnHarvestResult handles harvest result notifications
func (pgsa *PlayerGroundSpawnAdapter) OnHarvestResult(result *HarvestResult) {
	if result == nil || pgsa.player == nil {
		return
	}

	if result.Success && len(result.ItemsAwarded) > 0 {
		if pgsa.logger != nil {
			pgsa.logger.LogDebug("Player %s successfully harvested %d items",
				pgsa.player.GetName(), len(result.ItemsAwarded))
		}
	}
}

// HarvestEventAdapter adapts harvest events for different systems
type HarvestEventAdapter struct {
	handler HarvestHandler
	logger  Logger
}

// NewHarvestEventAdapter creates a new harvest event adapter
func NewHarvestEventAdapter(handler HarvestHandler, logger Logger) *HarvestEventAdapter {
	return &HarvestEventAdapter{
		handler: handler,
		logger:  logger,
	}
}

// ProcessHarvestEvent processes a harvest event
func (hea *HarvestEventAdapter) ProcessHarvestEvent(eventType string, gs *GroundSpawn, player *Player, data interface{}) {
	if hea.handler == nil {
		return
	}

	switch eventType {
	case "harvest_start":
		if err := hea.handler.OnHarvestStart(gs, player); err != nil && hea.logger != nil {
			hea.logger.LogError("Harvest start handler failed: %v", err)
		}

	case "harvest_complete":
		if result, ok := data.(*HarvestResult); ok {
			if err := hea.handler.OnHarvestComplete(gs, player, result); err != nil && hea.logger != nil {
				hea.logger.LogError("Harvest complete handler failed: %v", err)
			}
		}

	case "harvest_failed":
		if reason, ok := data.(string); ok {
			if err := hea.handler.OnHarvestFailed(gs, player, reason); err != nil && hea.logger != nil {
				hea.logger.LogError("Harvest failed handler failed: %v", err)
			}
		}

	case "ground_spawn_depleted":
		if err := hea.handler.OnGroundSpawnDepleted(gs); err != nil && hea.logger != nil {
			hea.logger.LogError("Ground spawn depleted handler failed: %v", err)
		}
	}
}
