package player

import (
	"sync"
	"sync/atomic"
	"time"

	"eq2emu/internal/common"
	"eq2emu/internal/entity"
	"eq2emu/internal/factions"
	"eq2emu/internal/languages"
	"eq2emu/internal/quests"
	"eq2emu/internal/skills"
	"eq2emu/internal/spells"
	"eq2emu/internal/titles"
)

// SpawnState represents the state of a spawn for a player
type SpawnState int32

const (
	SPAWN_STATE_NONE SpawnState = iota
	SPAWN_STATE_SENDING
	SPAWN_STATE_SENT_WAIT
	SPAWN_STATE_SENT
	SPAWN_STATE_REMOVING
	SPAWN_STATE_REMOVING_SLEEP
	SPAWN_STATE_REMOVED
)

// HistoryData represents character history data matching the character_history table
type HistoryData struct {
	Value     int32
	Value2    int32
	Location  [200]byte
	EventID   int32
	EventDate int32
	NeedsSave bool
}

// LUAHistory represents history set through the LUA system
type LUAHistory struct {
	Value      int32
	Value2     int32
	SaveNeeded bool
}

// SpellBookEntry represents a spell in the player's spell book
type SpellBookEntry struct {
	SpellID         int32
	Tier            int8
	Type            int32
	Slot            int32
	RecastAvailable int32
	Status          int8
	Recast          int16
	Timer           int32
	SaveNeeded      bool
	InUse           bool
	InRemiss        bool
	Player          *Player
	Visible         bool
}

// GMTagFilter represents a GM visual filter
type GMTagFilter struct {
	FilterType           int32
	FilterValue          int32
	FilterSearchCriteria [256]byte
	VisualTag            int16
}

// QuickBarItem represents an item on the player's quickbar
type QuickBarItem struct {
	Deleted  bool
	Hotbar   int32
	Slot     int32
	Type     int32
	Icon     int16
	IconType int16
	ID       int32
	Tier     int8
	UniqueID int64
	Text     common.EQ2String16Bit
}

// LoginAppearances represents equipment appearance data for login
type LoginAppearances struct {
	Deleted      bool
	EquipType    int16
	Red          int8
	Green        int8
	Blue         int8
	HRed         int8
	HGreen       int8
	HBlue        int8
	UpdateNeeded bool
}

// SpawnQueueState represents the spawn queue state with timer
type SpawnQueueState struct {
	SpawnStateTimer time.Time
	IndexID         int16
}

// PlayerLoginAppearance manages login appearance data
type PlayerLoginAppearance struct {
	appearanceList map[int8]*LoginAppearances
}

// InstanceData represents instance information for a player
type InstanceData struct {
	DBID                 int32
	InstanceID           int32
	ZoneID               int32
	ZoneInstanceType     int8
	ZoneName             string
	LastSuccessTimestamp int32
	LastFailureTimestamp int32
	SuccessLockoutTime   int32
	FailureLockoutTime   int32
}

// CharacterInstances manages all instances for a character
type CharacterInstances struct {
	instanceList []InstanceData
	mu           sync.Mutex
}

// PlayerInfo contains detailed player information for serialization
type PlayerInfo struct {
	player        *Player
	infoStruct    *entity.InfoStruct
	houseZoneID   int32
	bindZoneID    int32
	bindX         float32
	bindY         float32
	bindZ         float32
	bindHeading   float32
	boatXOffset   float32
	boatYOffset   float32
	boatZOffset   float32
	boatSpawn     int32
	changes       []byte
	origPacket    []byte
	petChanges    []byte
	petOrigPacket []byte
}

// PlayerControlFlags manages player control flags
type PlayerControlFlags struct {
	flagsChanged bool
	flagChanges  map[int8]map[int8]int8
	currentFlags map[int8]map[int8]bool
	controlMutex sync.Mutex
	changesMutex sync.Mutex
}

// PlayerGroup represents a player's group information
type PlayerGroup struct {
	// TODO: Implement group structure
}

// GroupMemberInfo represents information about a group member
type GroupMemberInfo struct {
	// TODO: Implement group member structure
}

// Statistic represents a player statistic
type Statistic struct {
	StatID int32
	Value  int64
	Date   int32
}

// Mail represents in-game mail
type Mail struct {
	MailID       int32
	PlayerTo     int32
	PlayerFrom   int32
	Subject      string
	MailBody     string
	AlreadyRead  int8
	MailType     int8
	Coin         int32
	Stack        int16
	Postage      int32
	AttachmentID int32
	CharItemID   int32
	TimeStamp    int32
	ExpireTime   int32
}

// Collection represents a player collection
type Collection struct {
	// TODO: Implement collection structure
}

// PlayerItemList manages the player's items
type PlayerItemList struct {
	// TODO: Implement item list structure
}

// PlayerSkillList manages the player's skills
type PlayerSkillList struct {
	skills.PlayerSkillList
}

// PlayerTitlesList manages the player's titles
type PlayerTitlesList struct {
	titles.PlayerTitlesList
}

// PlayerLanguagesList manages the player's languages
type PlayerLanguagesList struct {
	languages.PlayerLanguagesList
}

// PlayerFaction manages the player's faction standings
type PlayerFaction struct {
	factions.PlayerFaction
}

// PlayerCollectionList manages the player's collections
type PlayerCollectionList struct {
	// TODO: Implement collection list structure
}

// PlayerRecipeList manages the player's recipes
type PlayerRecipeList struct {
	// TODO: Implement recipe list structure
}

// PlayerRecipeBookList manages the player's recipe books
type PlayerRecipeBookList struct {
	// TODO: Implement recipe book list structure
}

// PlayerAchievementList manages the player's achievements
type PlayerAchievementList struct {
	// TODO: Implement achievement list structure
}

// PlayerAchievementUpdateList manages achievement updates
type PlayerAchievementUpdateList struct {
	// TODO: Implement achievement update list structure
}

// Guild represents a player's guild
type Guild struct {
	// TODO: Implement guild structure
}

// Recipe represents a crafting recipe
type Recipe struct {
	// TODO: Implement recipe structure
}

// TraitData represents a character trait
type TraitData struct {
	// TODO: Implement trait structure
}

// PacketStruct represents a network packet structure
type PacketStruct struct {
	// TODO: Implement packet structure
}

// Client represents a connected client
type Client struct {
	// TODO: Implement client structure
}

// ZoneServer represents a zone server instance
type ZoneServer struct {
	// TODO: Implement zone server structure
}

// NPC represents a non-player character
type NPC struct {
	// TODO: Implement NPC structure
}

// Item represents an in-game item
type Item struct {
	// TODO: Implement item structure
}

// MaintainedEffects represents a maintained spell effect
type MaintainedEffects struct {
	spells.MaintainedEffects
}

// SpellEffects represents active spell effects
type SpellEffects struct {
	spells.SpellEffects
}

// Player represents a player character extending Entity
type Player struct {
	entity.Entity

	// Client connection
	client *Client

	// Character identifiers
	charID    int32
	spawnID   int32
	accountID int32

	// Tutorial progress
	tutorialStep int8

	// Player information
	info *PlayerInfo

	// Group information
	group *PlayerGroup

	// Movement and position
	movementPacket       []byte
	oldMovementPacket    []byte
	lastMovementActivity int16
	posPacketSpeed       float32
	testX                float32
	testY                float32
	testZ                float32
	testTime             int32

	// Combat
	rangeAttack  bool
	combatTarget *entity.Entity
	resurrecting bool

	// Packet management
	packetNum       int32
	spawnIndex      int16
	spellCount      int16
	spellOrigPacket []byte
	spellXorPacket  []byte
	raidOrigPacket  []byte
	raidXorPacket   []byte

	// Spawn management
	spawnVisPacketList      map[int32]string
	spawnInfoPacketList     map[int32]string
	spawnPosPacketList      map[int32]string
	spawnPacketSent         map[int32]int8
	spawnStateList          map[int32]*SpawnQueueState
	playerSpawnIDMap        map[int32]*entity.Spawn
	playerSpawnReverseIDMap map[*entity.Spawn]int32
	playerAggroRangeSpawns  map[int32]bool

	// Temporary spawn packets for XOR
	spawnTmpVisXorPacket  []byte
	spawnTmpPosXorPacket  []byte
	spawnTmpInfoXorPacket []byte
	visXorSize            int32
	posXorSize            int32
	infoXorSize           int32

	// Packet structures
	spawnPosStruct     *PacketStruct
	spawnInfoStruct    *PacketStruct
	spawnVisStruct     *PacketStruct
	spawnHeaderStruct  *PacketStruct
	spawnFooterStruct  *PacketStruct
	widgetFooterStruct *PacketStruct
	signFooterStruct   *PacketStruct

	// Character flags
	charsheetChanged atomic.Bool
	raidsheetChanged atomic.Bool
	hassentRaid      atomic.Bool
	quickbarUpdated  bool

	// Quest system
	playerQuests               map[int32]*quests.Quest
	completedQuests            map[int32]*quests.Quest
	pendingQuests              map[int32]*quests.Quest
	currentQuestFlagged        map[*entity.Spawn]bool
	playerSpawnQuestsRequired  map[int32][]int32
	playerSpawnHistoryRequired map[int32][]int32

	// Skills and spells
	spells          []*SpellBookEntry
	passiveSpells   []int32
	skillList       PlayerSkillList
	allSpellsLocked bool

	// Items and equipment
	itemList         PlayerItemList
	quickbarItems    []*QuickBarItem
	pendingLootItems map[int32]map[int32]bool

	// Social lists
	friendList map[string]int8
	ignoreList map[string]int8

	// Character history
	characterHistory map[int8]map[int8][]*HistoryData
	charLuaHistory   map[int32]*LUAHistory

	// POI discoveries
	playersPoiList map[int32][]int32

	// Collections and achievements
	collectionList               PlayerCollectionList
	pendingCollectionReward      *Collection
	pendingItemRewards           []Item
	pendingSelectableItemRewards map[int32][]Item
	achievementList              PlayerAchievementList
	achievementUpdateList        PlayerAchievementUpdateList

	// Titles and languages
	playerTitlesList    PlayerTitlesList
	playerLanguagesList PlayerLanguagesList
	currentLanguageID   int32

	// Recipes
	recipeList     PlayerRecipeList
	recipebookList PlayerRecipeBookList
	currentRecipe  int32

	// Factions
	factions PlayerFaction

	// Statistics
	statistics map[int32]*Statistic

	// Mail
	mailList map[int32]*Mail

	// Character instances
	characterInstances CharacterInstances

	// Character state
	awayMessage          string
	biography            string
	isTracking           bool
	pendingDeletion      bool
	returningFromLD      bool
	custNPC              bool
	custNPCTarget        *entity.Entity
	stopSaveSpellEffects bool
	gmVision             bool
	resetMentorship      bool
	activeReward         bool

	// Guild
	guild *Guild

	// Appearance
	savedApp      common.AppearanceData
	savedFeatures common.CharFeatures

	// Bots
	spawnedBots map[int32]int32 // bot index -> spawn id

	// Control flags
	controlFlags PlayerControlFlags

	// Target invisibility history
	targetInvisHistory map[int32]bool

	// Mount information
	tmpMountModel       int32
	tmpMountColor       common.EQ2Color
	tmpMountSaddleColor common.EQ2Color

	// Lift cooldown
	liftCooldown time.Time

	// GM visual filters
	gmVisualFilters []GMTagFilter

	// Food and drink
	activeFoodUniqueID  atomic.Int64
	activeDrinkUniqueID atomic.Int64

	// Housing
	houseVaultSlots int8

	// Traits
	sortedTraitList  map[int8]map[int8][]*TraitData
	classTraining    map[int8][]*TraitData
	raceTraits       map[int8][]*TraitData
	innateRaceTraits map[int8][]*TraitData
	focusEffects     map[int8][]*TraitData
	needTraitUpdate  atomic.Bool

	// Mutexes
	playerQuestsMutex               sync.RWMutex
	spellsBookMutex                 sync.RWMutex
	recipeBookMutex                 sync.RWMutex
	playerSpawnQuestsRequiredMutex  sync.RWMutex
	playerSpawnHistoryRequiredMutex sync.RWMutex
	luaHistoryMutex                 sync.RWMutex
	controlFlagsMutex               sync.RWMutex
	infoMutex                       sync.RWMutex
	posMutex                        sync.RWMutex
	visMutex                        sync.RWMutex
	indexMutex                      sync.RWMutex
	spawnMutex                      sync.RWMutex
	spawnAggroRangeMutex            sync.RWMutex
	traitMutex                      sync.RWMutex
	spellPacketUpdateMutex          sync.RWMutex
	raidUpdateMutex                 sync.RWMutex
	mailMutex                       sync.RWMutex
}

// SkillBonus represents a skill bonus from a spell
type SkillBonus struct {
	SpellID int32
	SkillID int32
	Value   float32
}

// AddItemType represents the type of item addition
type AddItemType int8
