#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

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

#include "common/protocol.hpp"
#include "input/kmbox_net.hpp"
#include "input/human_curve.hpp"
#include "brain/bot_brain.hpp"

// ==========================================================
// LootController - Bộ Tự Động Nhặt Đồ & Lọc Vật Phẩm (Auto-Loot)
// ==========================================================

struct LootConfig {
    bool enabled = true;
    MovementMode moveMode = MovementMode::WASD; // Di chuyển tiếp cận đồ bằng WASD (mặc định POE2) hoặc Chuột (Click to Move)
    float lootRadius = 120.0f;           // Bán kính quét tìm đồ quanh nhân vật (mở rộng lên 120u để Walk-To-Loot)
    float pickupRange = 22.0f;           // Cự ly nhặt tối đa của POE2 (~22 đơn vị thế giới)
    float safeRange = 50.0f;             // Cự ly an toàn với quái sống (INV-SAFE-01)
    uint32_t lootIntervalMs = 25;        // Thời gian nghỉ tối thiểu giữa các lần click nhặt (siêu tốc 25ms)
    uint32_t wasdDwellMs = 300;          // Dwell di chuyển WASD tiếp cận đồ (INV-WASD-MIN-DWELL >= 300ms)
    bool ultraFast = true;               // Chế độ Auto-Loot siêu tốc <5ms (bỏ qua blocking sleep)
    bool respectGameFilter = true;       // Tận dụng cờ hide_all_filtered_ground_items=true của POE2
    bool hideFilteredGroundItems = true; // Giá trị nạp từ poe2_production_Config.ini
    uint32_t fastLootDwellMs = 3;        // Dwell time nhấp chuột siêu tốc (2-4ms)
    int screenWidth = 2560;              // Độ phân giải màn hình nạp từ game config (mặc định 2560)
    int screenHeight = 1440;             // Độ phân giải màn hình nạp từ game config (mặc định 1440)
    bool pickGold = true;                // Ưu tiên nhặt Vàng
    bool pickCurrency = true;            // Nhặt Currency (Orbs, Scrolls, Omens)
    bool pickWaystones = true;           // Nhặt Waystones (Tier 1-16 Endgame Maps)
    bool pickUncutGems = true;           // Nhặt Uncut Gems (Skill/Support/Spirit)
    bool pickRunesAndCores = true;       // Nhặt Runes & Soul Cores
    bool pickCharms = true;              // Nhặt Charms
    uint16_t minEquipmentRarity = 1;     // Rarity tối thiểu: 0=White, 1=Magic, 2=Rare, 3=Unique
    bool autoEquipUpgrades = false;      // CẤM mặc/tháo/đổi đồ đang đeo — chỉ nhặt, không equip (INV-NO-AUTO-EQUIP-IN-COMBAT)
    bool isInventoryFull = false;        // Cờ báo hiệu túi đồ đã đầy (chỉ cho phép nhặt đồ 1 slot priority >= 80)
};

struct LootState {
    uint64_t lastLootMs = 0;
    uint64_t lastPickupDurationMs = 0;   // Đo đạc độ trễ nhặt đồ gần nhất (<5ms)
    uint32_t totalItemsLooted = 0;
    uint32_t totalGoldLooted = 0;
    uint32_t lastLootedEntityId = 0;
    std::unordered_set<uint32_t> ignoredOrLootedIds;
    std::vector<std::pair<uint32_t, uint64_t>> lootedHistory; // (entityId, timestampMs)
};

struct PickupFilter {
    bool isLoaded = false;
    int pickupAllAboveRarity = -1;
    std::vector<std::string> nameSubstrings;
    std::vector<std::string> exactTypes;
    std::vector<std::string> rejectNameSubstrings;
    std::string filterFilePath;
    uint64_t lastCheckMs = 0;
    uint64_t lastFileModTime = 0;
};

class LootController : public IActionHandler {
public:
    explicit LootController(const LootConfig& config = LootConfig{});

    void SetConfig(const LootConfig& config) { m_config = config; }
    const LootConfig& Config() const { return m_config; }
    LootState& State() { return m_state; }

    // Quản lý Pickup Filter (Doc 29 Phase P2)
    bool LoadFilter(const std::string& path);
    void SetFilterPath(const std::string& path) { m_filter.filterFilePath = path; }
    void CheckReloadFilter(uint64_t nowMs);
    const PickupFilter& Filter() const { return m_filter; }

    // IActionHandler interface (BotBrain Arbiter P0)
    const char* Name() const override { return "LootHandler"; }
    ActionProposal Propose(const TelemetryPacket& packet, uint64_t nowMs) override;
    bool Execute(const ActionProposal& chosen, const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs) override;

    // Xử lý quét và nhặt đồ trong tick hiện tại (bọc Propose + Execute)
    bool Update(const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);

    // Kiểm tra xem 1 thực thể rơi có thỏa mãn bộ lọc không
    bool ShouldLoot(const EntityTelemetryData& item) const;

    // Tính điểm ưu tiên nhặt: số càng cao ưu tiên càng lớn
    int GetPriority(const EntityTelemetryData& item) const;

    // Reset danh sách ID đã nhặt khi chuyển map
    void ResetAreaState();

    bool IsUltraFast() const { return m_config.ultraFast; }
    uint64_t LastPickupDurationMs() const { return m_state.lastPickupDurationMs; }
    void ReleaseLootWasd(KMBoxNet& kmbox);
    void SetInventoryFull(bool full) { m_config.isInventoryFull = full; }
    bool IsInventoryFull() const { return m_config.isInventoryFull; }

private:
    void ExecutePickup(const EntityTelemetryData& item, const PlayerTelemetryData& player, KMBoxNet& kmbox, uint64_t nowMs);
    void HoldLootWasd(const std::vector<uint8_t>& hids, KMBoxNet& kmbox);

    LootConfig m_config;
    LootState m_state;
    PickupFilter m_filter;
    HumanCurveGenerator m_curveGen;
    std::vector<uint8_t> m_heldLootHids;
};
