package widget

import (
	"eq2emu/internal/spawn"
)

// ClientInterface represents the minimal client interface needed by widgets
type ClientInterface interface {
	GetPlayer() *spawn.Spawn
	SetTemporaryTransportID(id int32)
	ProcessTeleport(widget *Widget, destinations []interface{}, transporterID int32)
	GetVersion() int32
	GetCurrentZone() ZoneInterface
}

// ZoneInterface represents the minimal zone interface needed by widgets
type ZoneInterface interface {
	HasWidgetTimer(widget *Widget) bool
	AddWidgetTimer(widget *Widget, duration float32)
	SendSpawnChanges(s *spawn.Spawn)
	PlaySoundFile(unknown int32, soundFile string, x, y, z float32)
	CallSpawnScript(s *spawn.Spawn, scriptType string, caller *spawn.Spawn, extra string, state bool) bool
	GetSpawnByDatabaseID(id int32) *spawn.Spawn
	GetTransporters(client ClientInterface, transporterID int32) []interface{}
	ProcessEntityCommand(command interface{}, player *spawn.Spawn, target *spawn.Spawn)
	GetInstanceID() int32
	GetInstanceType() int32
	SendHouseItems(client ClientInterface)
}

// WidgetSpawn provides integration between Widget and Spawn systems
type WidgetSpawn struct {
	*spawn.Spawn
	*Widget
}

// NewWidgetSpawn creates a new widget spawn wrapper
func NewWidgetSpawn() *WidgetSpawn {
	widget := NewWidget()
	return &WidgetSpawn{
		Spawn:  widget.Spawn,
		Widget: widget,
	}
}

// IsWidget returns true for widget spawns
func (ws *WidgetSpawn) IsWidget() bool {
	return true
}

// Copy creates a copy of the widget spawn
func (ws *WidgetSpawn) Copy() *WidgetSpawn {
	newWidget := ws.Widget.Copy()
	return &WidgetSpawn{
		Spawn:  newWidget.Spawn,
		Widget: newWidget,
	}
}

// WidgetManager interface for managing widgets in a zone
type WidgetManager interface {
	AddWidget(widget *Widget)
	RemoveWidget(widgetID int32)
	GetWidget(widgetID int32) *Widget
	GetWidgetByDatabaseID(databaseID int32) *Widget
	GetAllWidgets() []*Widget
	ProcessWidgetTimers()
}

// WidgetTimer represents a timer for widget actions
type WidgetTimer struct {
	Widget   *Widget
	Duration float32
	Callback func(*Widget)
}

// WidgetState represents the current state of a widget
type WidgetState struct {
	IsOpen         bool
	Position       spawn.Position
	Heading        float32
	ActivityStatus int32
}

// GetState returns the current state of the widget
func (w *Widget) GetState() WidgetState {
	w.mutex.RLock()
	defer w.mutex.RUnlock()

	return WidgetState{
		IsOpen:         w.isOpen,
		Position:       spawn.Position{X: w.GetX(), Y: w.GetY(), Z: w.GetZ()},
		Heading:        w.GetHeading(),
		ActivityStatus: w.GetActivityStatus(),
	}
}

// RestoreState restores the widget to a previous state
func (w *Widget) RestoreState(state WidgetState) {
	w.mutex.Lock()
	defer w.mutex.Unlock()

	w.isOpen = state.IsOpen
	w.SetX(state.Position.X)
	w.SetY(state.Position.Y)
	w.SetZ(state.Position.Z)
	w.SetHeading(state.Heading)
	w.SetActivityStatus(state.ActivityStatus)
}
