#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

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

#include "common/protocol.hpp"
#include "input/kmbox_net.hpp"
#include <random>

// ==========================================================
// ReflexManager - Bộ Điều Phối Phản Xạ Sinh Tồn & Chiến Đấu POE2
// (Giai đoạn 3 & 4 - Iframe Dodge, Smart Flask Sipping, Kiting XYZ)
// ==========================================================

struct ReflexConfig {
    // 1. Iframe Dodge Roll (Phím Space)
    bool dodgeEnabled = true;
    float burstDamageRatio = 0.22f;     // Tụt >= 22% maxHP trong tick window -> Lăn né
    uint32_t dodgeCooldownMs = 850;     // Cooldown giữa các lần lăn (tránh lãng phí animation)
    uint8_t dodgeVk = VK_SPACE;
    uint8_t dodgeHid = 0x2C;            // HID scan code cho Spacebar

    // 1b. Human Reaction Latency (Độ trễ phản xạ sinh học tự nhiên của người chơi đỉnh cao: 100ms - 150ms)
    bool humanReactionEnabled = true;
    float reactionMeanMs = 125.0f;
    float reactionStddevMs = 12.0f;
    float minReactionLatencyMs = 100.0f;
    float maxReactionLatencyMs = 150.0f;

    // 2. Smart Flask Sipping (2 bình Máu & Mana chuẩn POE2)
    bool flaskEnabled = true;
    float hpThreshold = 0.55f;          // Bơm Life Flask khi HP <= 55%
    float criticalHpThreshold = 0.48f;  // Nguy kịch (<= 48%): Bơm dồn bất chấp HoT chống sốc sát thương
    uint8_t lifeFlaskVk = 0x31;         // Phím '1'
    uint8_t lifeFlaskHid = 0x1E;
    uint32_t lifeCooldownMs = 650;      // Cooldown ngắn hơn để nhồi ngụm máu kịp thời

    bool manaEnabled = true;
    float manaThreshold = 0.25f;        // Bơm Mana Flask khi Mana <= 25%
    uint8_t manaFlaskVk = 0x32;         // Phím '2'
    uint8_t manaFlaskHid = 0x1F;
    uint32_t manaCooldownMs = 1200;

    // 3. Dynamic Kiting (Thả diều né quái theo XYZ)
    bool kitingEnabled = true;          // Mặc định bật Kiting để nhân vật không đứng im khi quái áp sát
    MovementMode moveMode = MovementMode::MOUSE; // Di chuyển lùi kiting bằng Chuột (Click to Move) hoặc WASD
    float safeDistance = 35.0f;         // Cự ly an toàn tối thiểu với quái
    uint32_t kitingIntervalMs = 150;

    // 4. Auto-Chicken Emergency Escape (Mở Town Portal & né khẩn cấp)
    bool emergencyLogoutEnabled = true;
    float emergencyHpThreshold = 0.35f; // HP <= 35% -> Kích hoạt thoát hiểm khẩn cấp qua Town Portal 'T'
    uint8_t portalVk = 0xBE;            // Phím '.' mở Town Portal (VK_OEM_PERIOD 0xBE, tránh xung đột phím 'T' của Warcry)
    uint8_t portalHid = 0x37;           // USB HID Keyboard . and > (0x37)

    // 5. Tự động hồi sinh tại Checkpoint khi nhân vật chết (Auto-Respawn at Checkpoint)
    bool autoRespawn = true;
    uint32_t respawnDelayMs = 2200;     // Chờ 2.2 giây sau khi chết để bảng 'YOU HAVE DIED' và nút hiện rõ

    // 6. CI (Chaos Inoculation) Evasion & Energy Shield Recharge
    bool ciEvasionEnabled = true;
    float ciDodgeEsThreshold = 0.75f;    // ES < 75% -> Lập tức né đòn (Space)
    float ciReengageEsThreshold = 0.90f; // ES >= 90% -> Mới cho phép quay lại đánh
    float ciManaFlaskThreshold = 0.50f;  // Bơm mana khi <= 50% cho build ngốn mana

    // 7. Boss Telegraph Evasion (CHU KỲ 5)
    bool telegraphEvasionEnabled = true; // Bật phản xạ né đòn telegraph của Boss
    float telegraphDangerRadius = 180.0f;// Bán kính nguy hiểm quanh Boss kích hoạt né telegraph
    uint16_t telegraphAnimMin = 100;     // Dải ID animation chiêu nộ/slam/telegraph
    uint16_t telegraphAnimMax = 150;
    uint32_t telegraphDodgeCooldownMs = 600; // Cooldown né telegraph
};

struct ReflexState {
    // Dodge state
    uint64_t lastDodgeMs = 0;
    uint32_t dodgeCount = 0;
    uint32_t previousHP = 0;
    uint32_t previousES = 0;
    uint64_t lastHpSampleMs = 0;
    bool isCiRecoveryMode = false;       // True khi ES < 75%, chờ tới >= 90% mới thoát

    // Human Reaction Latency State (Độ trễ phản xạ tự nhiên của game thủ đỉnh cao)
    bool pendingDodge = false;
    uint64_t dodgeScheduledMs = 0;
    std::string pendingDodgeReason;

    // Boss Telegraph Evasion State (CHU KỲ 5)
    uint64_t lastTelegraphDodgeMs = 0;
    uint32_t telegraphDodgeCount = 0;
    bool isEvadingTelegraph = false;
    float lastTelegraphTangentX = 0.0f;
    float lastTelegraphTangentY = 0.0f;

    // Smart Life Flask state
    uint64_t lastLifeMs = 0;
    uint32_t lifeUses = 0;
    uint32_t lifePressHP = 0;
    bool isLifeHoT = false;
    uint64_t lifeHoTStartMs = 0;

    // Smart Mana Flask state
    uint64_t lastManaMs = 0;
    uint32_t manaUses = 0;
    bool awaitManaEffect = false;
    uint64_t manaPressMs = 0;
    uint32_t preManaValue = 0;
    uint32_t manaNoEffectCount = 0;
    bool manaEmpty = false;

    // Kiting state
    uint64_t lastKiteMs = 0;
    uint8_t currentKiteKey = 0;

    // Emergency state
    bool emergencyTriggered = false;

    // Death & Auto-Respawn state
    uint64_t deathTimestampMs = 0;
    uint32_t totalRespawns = 0;
    uint64_t lastRespawnClickMs = 0;
};

class GameSession;
namespace input { class NonBlockingActuator; }

class ReflexManager {
public:
    explicit ReflexManager(const ReflexConfig& config = ReflexConfig{});

    // Cập nhật cấu hình
    void SetConfig(const ReflexConfig& config) { m_config = config; }
    const ReflexConfig& Config() const { return m_config; }
    const ReflexConfig& GetConfig() const { return m_config; }
    ReflexState& State() { return m_state; }

    void SetGameSession(GameSession* session) { m_gameSession = session; }
    GameSession* GetGameSession() const { return m_gameSession; }
    void SetActuator(input::NonBlockingActuator* actuator) { m_actuator = actuator; }
    input::NonBlockingActuator* GetActuator() const { return m_actuator; }

    // Gọi mỗi tick 120Hz trong vòng lặp GameSession / main.cpp
    // Trả về true nếu kích hoạt Emergency Logout (yêu cầu Core tạm ngắt)
    bool Update(const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);

    // Trạng thái tiêu thụ input độc quyền trong tick hiện tại (INV-BRAIN-02)
    bool ConsumedExclusiveInput() const { return m_consumedExclusiveInput; }
    void SetConsumedExclusiveInput(bool val) { m_consumedExclusiveInput = val; }

    // Kích hoạt thủ công 1 cú lướt né Iframe
    void TriggerDodgeRoll(KMBoxNet& kmbox, uint64_t nowMs, const std::string& reason);

    // Kích hoạt thủ công 1 ngụm bình máu (dùng trong combo Double-Dodge)
    void TriggerLifeFlask(KMBoxNet& kmbox, uint64_t nowMs, const std::string& reason = "Emergency Double-Dodge");

    // Kích hoạt thủ công 1 ngụm bình mana (tối ưu hóa mana cho combo)
    void TriggerManaFlask(KMBoxNet& kmbox, uint64_t nowMs, const std::string& reason = "Pre-Combo Mana Optimization");

    // Trạng thái rút lui chờ hồi Energy Shield (CI Build)
    bool IsCiRecoveryMode() const { return m_state.isCiRecoveryMode; }
    void SetCiRecoveryMode(bool mode) { m_state.isCiRecoveryMode = mode; }

    // Boss Telegraph Evasion (CHU KỲ 5)
    bool IsEvadingTelegraph() const { return m_state.isEvadingTelegraph; }
    uint32_t GetTelegraphDodgeCount() const { return m_state.telegraphDodgeCount; }
    void GetLastTelegraphTangent(float& outTanX, float& outTanY) const {
        outTanX = m_state.lastTelegraphTangentX;
        outTanY = m_state.lastTelegraphTangentY;
    }

    // Xử lý tự động hồi sinh tại Checkpoint
    bool HandleAutoRespawn(const PlayerTelemetryData& player, KMBoxNet& kmbox, uint64_t nowMs);

    // Sinh độ biến thiên Gauss cho Dwell Time và Reaction Latency
    uint32_t GenerateGaussianDwellTime(float meanMs = 48.0f, float stddevMs = 7.0f, float minMs = 35.0f, float maxMs = 65.0f);
    uint32_t GenerateReactionLatencyMs();

    void HandleLifeFlask(const PlayerTelemetryData& player, KMBoxNet& kmbox, uint64_t nowMs);
    void HandleManaFlask(const PlayerTelemetryData& player, KMBoxNet& kmbox, uint64_t nowMs);
    bool HandleIframeDodge(const PlayerTelemetryData& player, const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);
    void TriggerKiting(float dirX, float dirY, KMBoxNet& kmbox, uint64_t nowMs);
    void HandleKiting(const PlayerTelemetryData& player, const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);
    bool HandleEmergencyLogout(const PlayerTelemetryData& player, KMBoxNet& kmbox, uint64_t nowMs);

private:
    void SendKey(uint8_t vkCode, uint8_t hidCode, KMBoxNet& kmbox, uint32_t holdMs = 0, uint64_t nowMs = 0);

    ReflexConfig m_config;
    ReflexState m_state;
    std::mt19937 m_rng{ std::random_device{}() };
    HumanCurveGenerator m_curveGen;
    GameSession* m_gameSession = nullptr;
    input::NonBlockingActuator* m_actuator = nullptr;
    bool m_consumedExclusiveInput = false;
};
