package game

import (
	"log/slog"
	"testing"
	"time"

	"github.com/denisovdennis/autohero/internal/model"
)

func TestHeroSocketDetachedKeepsMovement(t *testing.T) {
	e := NewEngine(100*time.Millisecond, make(chan model.CombatEvent, 8), slog.Default())
	e.SetRoadGraph(testGraph())

	h := &model.Hero{
		ID: 1, State: model.StateWalking, HP: 10, MaxHP: 10, Level: 1,
		PositionX: 1, PositionY: 1,
	}
	hm := NewHeroMovement(h, testGraph(), time.Now())
	e.mu.Lock()
	e.movements[1] = hm
	e.mu.Unlock()

	disconnectAt := time.Date(2026, 4, 1, 12, 0, 0, 0, time.UTC)
	e.HeroSocketDetached(1, true, disconnectAt)

	e.mu.RLock()
	_, ok := e.movements[1]
	e.mu.RUnlock()
	if !ok {
		t.Fatal("expected hero to remain resident in engine after last WS disconnect")
	}
	if h.WsDisconnectedAt == nil || !h.WsDisconnectedAt.Equal(disconnectAt) {
		t.Fatalf("expected WsDisconnectedAt on in-memory hero, got %v", h.WsDisconnectedAt)
	}
}

func TestMergeResidentHeroState(t *testing.T) {
	e := NewEngine(100*time.Millisecond, make(chan model.CombatEvent, 8), slog.Default())
	e.SetRoadGraph(testGraph())

	dst := &model.Hero{ID: 7, State: model.StateWalking, HP: 5, MaxHP: 10, Level: 2}
	if e.MergeResidentHeroState(dst) {
		t.Fatal("expected false when hero not resident")
	}

	h := &model.Hero{
		ID: 7, State: model.StateWalking, HP: 9, MaxHP: 10, Level: 3,
		PositionX: 2, PositionY: 3,
	}
	hm := NewHeroMovement(h, testGraph(), time.Now())
	e.mu.Lock()
	e.movements[7] = hm
	e.mu.Unlock()

	dst2 := &model.Hero{ID: 7, HP: 1, Level: 1}
	if !e.MergeResidentHeroState(dst2) {
		t.Fatal("expected true when resident")
	}
	if dst2.HP != 9 || dst2.Level != 3 {
		t.Fatalf("expected engine stats copied, got hp=%d level=%d", dst2.HP, dst2.Level)
	}
}
