package ai

import (
	"a301_game_server/internal/combat"
	"a301_game_server/internal/entity"
	"a301_game_server/pkg/mathutil"
	pb "a301_game_server/proto/gen/pb"
)

// MobDef defines a mob template loaded from data.
type MobDef struct {
	ID         uint32
	Name       string
	Level      int32
	HP         int32
	MP         int32
	Str        int32
	Dex        int32
	Int        int32
	MoveSpeed  float32 // units per second
	AggroRange float32 // distance to start chasing
	AttackRange float32
	AttackSkill uint32 // skill ID used for auto-attack
	LeashRange float32 // max distance from spawn before returning
	ExpReward  int64
	LootTable  []LootEntry
}

// LootEntry defines a possible drop.
type LootEntry struct {
	ItemID   uint32
	Quantity int32
	Chance   float32 // 0.0 - 1.0
}

// Mob is a server-controlled enemy entity.
type Mob struct {
	id       uint64
	def      *MobDef
	position mathutil.Vec3
	rotation float32
	hp       int32
	maxHP    int32
	mp       int32
	maxMP    int32
	spawnPos mathutil.Vec3
	alive    bool

	// AI state
	state    AIState
	targetID uint64 // entity being chased/attacked
}

// NewMob creates a mob from a definition at the given position.
func NewMob(id uint64, def *MobDef, spawnPos mathutil.Vec3) *Mob {
	return &Mob{
		id:       id,
		def:      def,
		position: spawnPos,
		spawnPos: spawnPos,
		hp:       def.HP,
		maxHP:    def.HP,
		mp:       def.MP,
		maxMP:    def.MP,
		alive:    true,
		state:    StateIdle,
	}
}

// Entity interface
func (m *Mob) EntityID() uint64        { return m.id }
func (m *Mob) EntityType() entity.Type { return entity.TypeMob }

func (m *Mob) Position() mathutil.Vec3    { return m.position }
func (m *Mob) SetPosition(p mathutil.Vec3) { m.position = p }
func (m *Mob) Rotation() float32          { return m.rotation }
func (m *Mob) SetRotation(r float32)      { m.rotation = r }

// Combatant interface
func (m *Mob) HP() int32    { return m.hp }
func (m *Mob) MaxHP() int32 { return m.maxHP }
func (m *Mob) SetHP(hp int32) {
	if hp < 0 {
		hp = 0
	}
	if hp > m.maxHP {
		hp = m.maxHP
	}
	m.hp = hp
	m.alive = hp > 0
}
func (m *Mob) MP() int32 { return m.mp }
func (m *Mob) SetMP(mp int32) {
	if mp < 0 {
		mp = 0
	}
	m.mp = mp
}
func (m *Mob) IsAlive() bool { return m.alive }
func (m *Mob) Stats() combat.CombatStats {
	return combat.CombatStats{
		Str:   m.def.Str,
		Dex:   m.def.Dex,
		Int:   m.def.Int,
		Level: m.def.Level,
	}
}

func (m *Mob) Def() *MobDef        { return m.def }
func (m *Mob) SpawnPos() mathutil.Vec3 { return m.spawnPos }
func (m *Mob) State() AIState       { return m.state }
func (m *Mob) SetState(s AIState)   { m.state = s }
func (m *Mob) TargetID() uint64     { return m.targetID }
func (m *Mob) SetTargetID(id uint64) { m.targetID = id }

func (m *Mob) ToProto() *pb.EntityState {
	return &pb.EntityState{
		EntityId:   m.id,
		Name:       m.def.Name,
		Position:   &pb.Vector3{X: m.position.X, Y: m.position.Y, Z: m.position.Z},
		Rotation:   m.rotation,
		Hp:         m.hp,
		MaxHp:      m.maxHP,
		Level:      m.def.Level,
		EntityType: pb.EntityType_ENTITY_TYPE_MOB,
	}
}

// Reset restores the mob to full health at its spawn position.
func (m *Mob) Reset() {
	m.hp = m.maxHP
	m.mp = m.maxMP
	m.position = m.spawnPos
	m.alive = true
	m.state = StateIdle
	m.targetID = 0
}
