#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <cstdint>
#include <vector>
#include <string>

#include "common/protocol.hpp"
#include "input/kmbox_net.hpp"

namespace navigation {
    class MovementController;
}

// ==========================================================
// AutoPOE2 - BotBrain Priority Arbiter (Doc 29 - SPEC P0)
// Bộ điều phối hành động duy nhất mỗi tick 120Hz theo mức ưu tiên
// ==========================================================

enum class BotActionKind : uint16_t {
    None = 0,
    Chicken = 1,
    Flask = 2,
    Dodge = 3,
    Unstuck = 4,
    EmergencyAttack = 5,
    Combat = 6,
    AreaEvent = 7,
    Pickup = 8,
    OpenChest = 9,
    WaitLoot = 10,
    WaitBoss = 11,
    Explore = 12,
    Stash = 13,
    Vendor = 14,
    SwitchArea = 15,
    Idle = 16,
    NpcInteract = 17
};

inline const char* BotActionKindToString(BotActionKind kind) {
    switch (kind) {
        case BotActionKind::None: return "None";
        case BotActionKind::Chicken: return "Chicken";
        case BotActionKind::Flask: return "Flask";
        case BotActionKind::Dodge: return "Dodge";
        case BotActionKind::Unstuck: return "Unstuck";
        case BotActionKind::EmergencyAttack: return "EmergencyAttack";
        case BotActionKind::Combat: return "Combat";
        case BotActionKind::AreaEvent: return "AreaEvent";
        case BotActionKind::Pickup: return "Pickup";
        case BotActionKind::OpenChest: return "OpenChest";
        case BotActionKind::WaitLoot: return "WaitLoot";
        case BotActionKind::WaitBoss: return "WaitBoss";
        case BotActionKind::Explore: return "Explore";
        case BotActionKind::Stash: return "Stash";
        case BotActionKind::Vendor: return "Vendor";
        case BotActionKind::SwitchArea: return "SwitchArea";
        case BotActionKind::Idle: return "Idle";
        case BotActionKind::NpcInteract: return "NpcInteract";
        default: return "Unknown";
    }
}

namespace bot_priority {
    // -------------------------------------------------------------------------
    // Tier Sinh Tồn Tuyệt Đối (10000 - 8500):
    // Các mức ưu tiên lý thuyết cho phản xạ sinh tồn. Trong thực tế kiến trúc Tier 1,
    // ReflexManager xử lý độc lập trước vòng lặp BotBrain (ConsumedExclusiveInput() = true
    // sẽ bypass hoàn toàn BotBrain) để đảm bảo phản xạ sinh tồn 0ms không bị ảnh hưởng.
    // -------------------------------------------------------------------------
    constexpr uint32_t CHICKEN          = 10000;
    constexpr uint32_t FLASK            = 9000;
    constexpr uint32_t DODGE            = 8500;

    // -------------------------------------------------------------------------
    // Tier Tác Vụ Tự Hành (8000 - 1000):
    // Do BotBrain điều phối trọng tài mỗi tick 120Hz.
    // -------------------------------------------------------------------------
    constexpr uint32_t UNSTUCK          = 8000;
    constexpr uint32_t EMERGENCY_ATTACK = 7500;
    constexpr uint32_t COMBAT           = 7000;
    constexpr uint32_t AREA_EVENT       = 6500;
    constexpr uint32_t PICKUP           = 6000;
    constexpr uint32_t COMBAT_ENGAGE    = 5800;
    constexpr uint32_t OPEN_CHEST       = 5500;
    constexpr uint32_t WAITING_FOR_LOOT = 5000;
    constexpr uint32_t WAITING_FOR_BOSS = 4800;
    constexpr uint32_t EXPLORE          = 4000;
    constexpr uint32_t STASH            = 3500;
    constexpr uint32_t VENDOR           = 3400;
    constexpr uint32_t NPC_INTERACT     = 3300;
    constexpr uint32_t MAP_DEVICE       = 3200;
    constexpr uint32_t SWITCH_AREA      = 3000;
    constexpr uint32_t IDLE             = 1000;
}

struct ActionProposal {
    BotActionKind kind = BotActionKind::None;
    uint32_t priority = 0;             // 0 = không đề xuất hành động
    uint32_t entityId = 0;
    float targetX = 0.0f;
    float targetY = 0.0f;
    float targetZ = 0.0f;
    float distance = 0.0f;
    const char* priorityName = "NONE"; // chuỗi literal tĩnh không heap alloc
};

class IActionHandler {
public:
    virtual ~IActionHandler() = default;
    virtual const char* Name() const = 0;
    // Thu thập đề xuất hành động trong tick (chỉ đọc Telemetry, 0ms latency, không thao tác phím/chuột)
    virtual ActionProposal Propose(const TelemetryPacket& packet, uint64_t nowMs) = 0;
    // Thực thi hành động thắng cuộc được chọn (chỉ gọi đúng 1 handler thắng cuộc)
    virtual bool Execute(const ActionProposal& chosen, const TelemetryPacket& packet,
                         KMBoxNet& kmbox, uint64_t nowMs) = 0;
};

class BotBrain {
public:
    BotBrain() = default;

    // Đăng ký action handler (không sở hữu con trỏ)
    void AddHandler(IActionHandler* handler);
    void ClearHandlers();

    // Hành động được chọn gần nhất
    const ActionProposal& LastChosen() const { return m_lastChosen; }

    // Xử lý 1 tick điều phối (120Hz Hot Loop):
    // 1. Propose từ tất cả handler
    // 2. Chọn priority cao nhất (tie-break: khoảng cách gần hơn -> entityId nhỏ hơn)
    // 3. Thực thi Execute trên handler thắng cuộc
    // 4. Ghi log chuẩn INV-BRAIN-05
    // Trả về true nếu đã thực thi một hành động (khác Idle/None)
    bool Process(const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);

    // Cấu hình log verbose / suppress
    void SetLogEnabled(bool enabled) { m_logEnabled = enabled; }

    // Quản lý hạt nhân di chuyển phi khóa (tránh xung đột phím giữa các handler)
    void SetMovementController(navigation::MovementController* moveCtrl) { m_moveCtrl = moveCtrl; }
    navigation::MovementController* GetMovementController() const { return m_moveCtrl; }

private:
    std::vector<IActionHandler*> m_handlers;
    navigation::MovementController* m_moveCtrl = nullptr;
    ActionProposal m_lastChosen{};
    uint64_t m_lastLogMs = 0;
    BotActionKind m_lastLoggedKind = BotActionKind::None;
    uint32_t m_lastLoggedEntityId = 0;
    bool m_logEnabled = true;
};
