#pragma once
/// \file types.hpp — Mô hình dữ liệu cốt lõi của toàn hệ thống.
/// Đối ứng với thiết kế trong docs/01-architecture.md và docs/03-memory-module.md.
/// Các struct snapshot là BẤT BIẾN (immutable) — DecisionEngine không bao giờ
/// chạm trực tiếp vào process game, chỉ đọc snapshot.

#include <array>
#include <chrono>
#include <cstdint>
#include <variant>
#include <vector>

namespace ares {

// ---------------------------------------------------------------------------
// Primitives
// ---------------------------------------------------------------------------

struct Vec3 {
    float x{0.0f};
    float y{0.0f};
    float z{0.0f};
};

// ---------------------------------------------------------------------------
// GameState — do MemoryReader / VisionModule tạo ra mỗi tick
// ---------------------------------------------------------------------------

struct PlayerState {
    std::uint32_t hp{0};
    std::uint32_t max_hp{1};
    std::uint32_t mp{0};
    std::uint32_t max_mp{1};
    std::uint8_t  class_id{0};     // 0=Engineer 1=Warlord 2=Hunter 3=Warlock
    std::uint8_t  suit_id{0};      // suit đang dùng (Suit Change)
    Vec3          pos{};
    std::array<float, 8> skill_cooldowns{};  // giây còn lại của 8 skill slot
};

enum class EntityKind : std::uint8_t {
    Unknown = 0,
    Mob,
    Elite,
    Boss,
    PlayerOther,
    Npc,
};

struct Entity {
    std::uint32_t id{0};
    EntityKind    kind{EntityKind::Unknown};
    float         hp_pct{1.0f};    // 0.0 .. 1.0
    Vec3          pos{};
    std::uint32_t state_id{0};     // animation/boss skill cue — đầu vào chính cho dodge
};

enum class EncounterKind : std::uint8_t {
    Unknown = 0,
    Field,
    Dungeon,
    Raid,
    Arena,
    UiMenu,
};

struct UiState {
    bool dialog_open{false};
    bool loading{false};
    bool dead{false};
};

struct GameState {
    std::chrono::steady_clock::time_point timestamp{};
    PlayerState      player{};
    std::vector<Entity> entities{};
    EncounterKind    context{EncounterKind::Unknown};
    UiState          ui{};
};

// ---------------------------------------------------------------------------
// ActionCommand — output của DecisionEngine
// ---------------------------------------------------------------------------

enum class ActionType : std::uint8_t {
    Idle = 0,
    MoveTo,
    CastSkill,
    Dodge,
    SwitchSuit,
    Interact,
};

/// Priority quyết định interrupt trong InputController (xem docs/04-input-module.md §5)
enum class Priority : std::uint8_t {
    Emergency = 0,   // Dodge/potion — pre-empt mọi thứ, flush queue
    Combat,          // CastSkill — xếp hàng giữ thứ tự combo
    Navigation,      // MoveTo — chỉ giữ command mới nhất cùng loại
};

struct TargetPoint {
    Vec3 point{};
};

struct SkillSlot {
    std::uint8_t slot{0};
};

struct ActionCommand {
    ActionType type{ActionType::Idle};
    Priority   priority{Priority::Navigation};
    std::variant<std::monostate, TargetPoint, SkillSlot> payload{};
};

// ---------------------------------------------------------------------------
// InputEvent — do Humanizer tạo ra, gửi qua Virtual KMBox
// ---------------------------------------------------------------------------

enum class InputKind : std::uint8_t {
    KeyPress = 0,
    KeyRelease,
    MouseMoveRel,
    MouseButton,
};

struct InputEvent {
    InputKind kind{InputKind::KeyPress};
    std::chrono::steady_clock::time_point execute_at{};  // đã cộng reaction delay
    std::array<char, 64> payload{};  // packet ASCII sẵn sàng cho transport KMBox
};

} // namespace ares
