#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#ifndef NOMINMAX
#define NOMINMAX
#endif

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

#include "common/protocol.hpp"
#include "input/kmbox_net.hpp"
#include "brain/bot_brain.hpp"
#include "combat/skills_table.hpp"
#include "combat/skill_engine.hpp"
#include "combat/stutter_step_controller.hpp"
#include "combat/boss_phase_controller.hpp"
#include "combat/monster_pack_clusterer.hpp"
#include <random>

// ==========================================================
// ComboManager - Quản Lý Thi Triển Kỹ Năng & Kết Liễu Stagger POE2
// (Auto-Combo Rotation & Heavy Stagger Finisher)
// ==========================================================

struct ComboConfig {
    bool enabled = true;
    bool autoStaggerFinisher = true;    // Tự động xả đòn kết liễu khi quái bị Stagger (>= 80%)
    uint16_t staggerThreshold = 8000;   // 8000 = 80% Stagger Bar
    uint32_t comboIntervalMs = 200;     // Tần suất tung chiêu trong rotation (Monk nhịp đánh nhanh)
    bool autoClearing = true;           // Tự động dọn quái
    bool useMonkRotation = true;        // Kích hoạt rotation chuẩn Monk (Ice Strike + Tempest Bell + Double Dodge)
    float safeRange = 50.0f;            // Cự ly quái nguy hiểm kích hoạt EmergencyAttack (Doc 29)
    float monstersAttackRange = 150.0f; // Cự ly quái kích hoạt Combat thường (Doc 29)
    float engageRange = 380.0f;         // Cự ly quái kích hoạt tiếp cận giao tranh (khớp InMapCombat 380u)
    bool useGapCloserOnEngage = true;   // Dùng MMB Wolf Leap áp sát khi dist >= 100u
    uint32_t wasdEngageDwellMs = 300;   // Dwell time tiếp cận bằng WASD (>= 300ms theo INV-WASD-MIN-DWELL)
    uint32_t gapCloserCooldownMs = 2500;// Cooldown nhảy áp sát MMB (2.5s)

    // 1. Cấu hình Kỹ Năng Đánh Xa & Cận Chiến POE2:
    bool isRangedMode = true;            // Mặc định chế độ Đánh Xa (RMB Projectile / Spell)
    float rangedEngageDist = 450.0f;     // Cự ly giao chiến tầm xa (450 units)
    float kitingDangerDist = 120.0f;     // Cự ly quái áp sát nguy hiểm cần né lùi (120 units)
    uint32_t vaultCooldownMs = 1200;     // Cooldown giữa các lần né lùi [E] (1200ms)

    uint8_t primarySkillVk = VK_RBUTTON; // Chuột Phải (VK_RBUTTON): Kỹ năng tấn công chính đánh xa
    uint8_t vaultSkillVk = 0x45;         // Phím 'E' (0x45): Kỹ năng né / lướt thoát hiểm (Frozen Locus / Dash)
    uint8_t gapCloserSkillVk = VK_MBUTTON; // Chuột Giữa (VK_MBUTTON): DruidWolfLeapAttack nhảy áp sát & debuff
    uint8_t builderSkillVk = 0x51;       // Phím 'Q' (0x51): Chiêu Tích Combo (Tempest Flurry, Ice Strike)
    uint8_t spenderSkillVk = 0x52;       // Phím 'R' (0x52): Chiêu Xả Combo / Kích Nổ Chuông Bão (Tempest Bell)
    uint8_t bellSkillVk = 0x51;          // Tương thích ngược: Tempest Bell nếu cấu hình slot Q cũ
    uint8_t finisherSkillVk = 0x52;      // Phím 'R' (0x52): Đòn kết liễu cực đại khi Stagger
    uint8_t secondarySkillVk = VK_RBUTTON; // Chuột Phải: Kỹ năng phụ

    // 2. Cấu hình Đánh Boss Trừu Tượng (Builder -> Spender):
    // Tích đủ điểm combo qua Chiêu Tích Combo (Q) rồi kích nổ Spender / Chuông Bão (R)
    uint32_t bossStrikeGoal = 4;         // Đánh 4 lần chiêu tích combo trước khi xả đòn kết liễu / đặt chuông
    uint32_t bellDurationMs = 8000;      // Thời gian chuông tồn tại (8s)

    // 3. Cấu hình Thoát Hiểm Khẩn Cấp "Double Dodge" (E -> Space -> Hồi Máu):
    bool doubleDodgeEnabled = true;
    float emergencyHpThreshold = 0.45f;  // HP <= 45% kích hoạt Double Dodge
    float emergencyBurstRatio = 0.20f;   // Tụt >= 20% maxHP trong tích tắc kích hoạt Double Dodge
    uint32_t doubleDodgeCooldownMs = 1200; // Cooldown giữa các chuỗi Double Dodge
    uint8_t dodgeRollVk = VK_SPACE;      // Phím Spacebar (Iframe Dodge Roll)
    uint8_t lifeFlaskVk = 0x31;          // Phím '1' (Life Flask)

    // Tương thích ngược
    float closeRangeDistance = 180.0f;
    uint8_t closeSkillVk = 0x45;
    uint8_t rangedSkillVk = VK_LBUTTON;
    uint8_t primerSkillVk = VK_LBUTTON;
    uint8_t mainSkillVk = VK_LBUTTON;
    uint32_t minManaToCombo = 15;

    // 4. Cấu hình Chiến Thuật CI Charged Staff & Combo Rage (PoE 2 v0.5.5)
    bool isCiChargedStaffMode = false;   // Bật chế độ CI Trượng Tích Điện
    uint8_t staffBuffSkillVk = VK_RBUTTON;  // Chuột Phải (Charged Staff)
    uint8_t staffMeleeSkillVk = 'F';        // Phím 'F' (0x46) - Chiêu chính người chơi
    uint8_t finisherRSkillVk = 0x52;        // Phím 'R' (Finisher 4-Combo)
    uint32_t chargedStaffBuffDurationMs = 40000; // 40s buff duration
    uint32_t requiredChargesForBuff = 4;    // 4 đến 5 charges
    uint32_t requiredComboForR = 4;         // 4 combo points
    uint32_t minManaForHeavySkill = 35;     // Ngưỡng mana tối thiểu

    // 5. Cấu hình Chiến Thuật Unique Life Flask Khi Đánh Boss (Sustain Rage sau chiêu T)
    bool bossRageFlaskEnabled = false;      // Bật kích hoạt Life Flask 1 lần khi đánh Boss (kích hoạt qua --boss-rage-flask)
    uint32_t rageFlaskDelayAfterTMs = 4000; // Đợi 4s sau chiêu T rồi mới bấm Life Flask
    uint8_t rageBuffSkillVk = 0x54;         // Phím 'T' (0x54)

    // 6. Boss Stagger Burst DPS Window (CHU KỲ 5)
    bool bossStaggerBurstEnabled = true; // Bật chế độ dồn sát thương cực đại khi Boss bị Stagger
    uint16_t bossStaggerThreshold = 8000;// Ngưỡng stagger kích hoạt Burst Window (>= 80% Poise break)
    uint32_t burstWindowDurationMs = 3500;// Thời gian duy trì Burst DPS Window (3.5s)
};

struct ComboState {
    uint64_t lastSkillCastMs = 0;
    uint64_t lastFinisherCastMs = 0;
    uint64_t lastVaultMs = 0;           // Thời điểm né lùi bằng phím 'E' gần nhất
    uint32_t totalCombosExecuted = 0;
    uint32_t totalFinishersExecuted = 0;
    uint32_t totalBellsPlaced = 0;
    uint32_t totalDoubleDodges = 0;
    uint32_t currentRotationStep = 0;

    // Trạng thái Boss rotation & Combo
    uint32_t bossComboHits = 0;         // Số lần thi triển chiêu tích combo (Builder Q) vào Boss (0..4)
    uint32_t bossIceStrikeCount = 0;    // Tương thích ngược: Đếm số đòn đánh tích combo vào Boss (0..4)
    bool isBossEncounter = false;
    uint64_t lastBellPlacedMs = 0;
    float lastBellPosX = 0.0f;
    float lastBellPosY = 0.0f;

    // Trạng thái Boss Stagger Burst (CHU KỲ 5)
    bool isBossBurstWindow = false;      // True khi Boss đang bị choáng/vulnerable
    uint64_t burstWindowStartMs = 0;     // Mốc thời gian bắt đầu cửa sổ dồn sát thương
    uint32_t totalBossBurstWindows = 0;  // Số lần kích hoạt Burst DPS Window

    // Trạng thái Boss Rage Flask (Chiêu T -> 4s -> Life Flask 1)
    uint32_t activeBossId = 0;          // ID Boss đang giao tranh
    uint64_t lastTCastMs = 0;           // Thời điểm tung chiêu T
    bool bossLifeFlaskUsed = false;     // Đã bấm Life Flask 1 lần cho Boss này chưa

    // Trạng thái Double Dodge (E -> Space -> Flask -> Evaluate)
    int doubleDodgeStep = 0;            // 0: Idle, 1: vừa cast E, 2: vừa cast Space, 3: vừa bơm máu
    uint64_t lastDoubleDodgeMs = 0;
    uint64_t lastDoubleDodgeStepMs = 0;
    float threatDx = 0.0f;
    float threatDy = 0.0f;

    uint32_t previousHP = 0;
    uint64_t lastDamageTakenMs = 0;
    uint64_t inCombatUntilMs = 0;
    uint32_t consecutiveBlindCasts = 0;

    // Trạng thái CI Charged Staff & Rage/Combo
    uint32_t currentCharges = 0;           // Số lượng charges hiện tại (Power/Frenzy/Endurance)
    uint32_t currentComboPoints = 0;       // Điểm combo tích lũy (0..4)
    uint32_t currentRage = 0;              // Chỉ số Rage tích lũy
    uint64_t chargedStaffBuffExpiresMs = 0;// Thời điểm hết hạn của buff Charged Staff (40s)

    // Trạng thái Hồ sơ Giao chiến (CHU KỲ 6)
    CombatProfile activeCombatProfile = CombatProfile::MOB_CLEARING;
};

namespace navigation { class TerrainGrid; class MovementController; }
namespace combat { class KitingEngine; }
namespace input { class NonBlockingActuator; }
class ReflexManager;

class ComboManager : public IActionHandler {
public:
    explicit ComboManager(const ComboConfig& config = ComboConfig{});

    void SetConfig(const ComboConfig& config) { m_config = config; }
    const ComboConfig& Config() const { return m_config; }
    ComboConfig& Config() { return m_config; }
    const ComboConfig& GetConfig() const { return m_config; }
    ComboConfig& GetConfig() { return m_config; }
    ComboState& State() { return m_state; }

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

    void SetTerrainGrid(const navigation::TerrainGrid* grid) { m_terrainGrid = grid; }
    void SetKitingEngine(combat::KitingEngine* kiting) { m_kitingEngine = kiting; }
    void SetReflexManager(ReflexManager* reflex) { m_reflexManager = reflex; }
    void SetMovementController(navigation::MovementController* moveCtrl) { m_moveCtrl = moveCtrl; }
    void SetActuator(input::NonBlockingActuator* actuator) { m_actuator = actuator; }
    input::NonBlockingActuator* GetActuator() const { return m_actuator; }

    // Quản lý Hồ sơ Giao chiến (Combat Profile Switching - CHU KỲ 6)
    void SetCombatProfile(CombatProfile profile, uint32_t targetEntityId = 0);
    CombatProfile GetCombatProfile() const { return m_state.activeCombatProfile; }

    // Quản lý Charges & Combo Points
    void AddCharges(uint32_t count) { m_state.currentCharges = (std::min)(5u, m_state.currentCharges + count); }
    void SetCharges(uint32_t count) { m_state.currentCharges = (std::min)(5u, count); }
    uint32_t GetCharges() const { return m_state.currentCharges; }
    uint32_t GetComboPoints() const { return m_state.currentComboPoints; }
    void SetComboPoints(uint32_t points) { m_state.currentComboPoints = points; }
    uint32_t GetRage() const { return m_state.currentRage; }
    bool IsChargedStaffBuffActive(uint64_t nowMs) const { return nowMs < m_state.chargedStaffBuffExpiresMs; }
    uint64_t GetChargedStaffBuffExpiresMs() const { return m_state.chargedStaffBuffExpiresMs; }
    bool IsBossBurstWindow() const { return m_state.isBossBurstWindow; }
    uint32_t GetTotalBossBurstWindows() const { return m_state.totalBossBurstWindows; }

    // Quét mục tiêu và tự động tung rotation hoặc đòn kết liễu Stagger
    bool Update(const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);

    // Kích hoạt thủ công đòn Finisher
    void TriggerFinisher(KMBoxNet& kmbox, uint64_t nowMs, const std::string& targetName, float dx = 0.0f, float dy = 0.0f);

    // Kích hoạt chuỗi thoát hiểm khẩn cấp Double Dodge
    bool TriggerDoubleDodge(KMBoxNet& kmbox, uint64_t nowMs, float threatDx, float threatDy, const std::string& reason);

    // Sinh độ biến thiên Gauss cho Dwell Time kỹ năng (35ms - 65ms)
    uint32_t GenerateGaussianDwellTime(float meanMs = 48.0f, float stddevMs = 7.0f, float minMs = 35.0f, float maxMs = 65.0f);

    // Bảng kỹ năng table-driven skills.toml (Doc 29 mục 13 - Phase P4)
    bool LoadSkills(const std::string& tomlPath) { return m_skillsTable.LoadSkills(tomlPath); }
    const SkillsTable& Skills() const { return m_skillsTable; }
    SkillsTable& Skills() { return m_skillsTable; }

    // Dedicated Flexible Skill Engine (Doc 36 - ARCH-SKILL-ENGINE-FLEXIBLE-2026-P6)
    bool LoadSkillProfile(const std::string& tomlPath);
    SkillEngine* GetSkillEngine() { return m_skillEngine.get(); }
    const SkillEngine* GetSkillEngine() const { return m_skillEngine.get(); }

    combat::StutterStepController& GetStutterStepper() { return m_stutterStepper; }
    const combat::StutterStepController& GetStutterStepper() const { return m_stutterStepper; }

    combat::BossPhaseController& GetBossPhaseController() { return m_bossPhaseCtrl; }
    const combat::BossPhaseController& GetBossPhaseController() const { return m_bossPhaseCtrl; }

    combat::MonsterPackClusterer& GetPackClusterer() { return m_packClusterer; }
    const combat::MonsterPackClusterer& GetPackClusterer() const { return m_packClusterer; }

    // Tiếp cận giao tranh (Combat Engage Movement) khi quái ở 150u < dist <= 380u
    bool ExecuteEngageMovement(const ActionProposal& chosen, const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs);
    void ReleaseEngageKeys(KMBoxNet& kmbox);

private:
    void SendKey(uint8_t vkCode, KMBoxNet& kmbox, uint32_t holdMs = 0, uint64_t nowMs = 0);
    void AimAndCast(uint8_t vkCode, float dx, float dy, KMBoxNet& kmbox, uint32_t holdMs = 0, uint64_t nowMs = 0);
    void AimAndMove(float dx, float dy, KMBoxNet& kmbox);

    std::vector<uint8_t> m_heldEngageKeys;
    uint64_t m_lastGapCloserMs = 0;

    ComboConfig m_config;
    ComboState m_state;
    SkillsTable m_skillsTable;
    const navigation::TerrainGrid* m_terrainGrid = nullptr;
    combat::KitingEngine* m_kitingEngine = nullptr;
    ReflexManager* m_reflexManager = nullptr;
    std::mt19937 m_rng{ std::random_device{}() };
    HumanCurveGenerator m_curveGen;
    std::unique_ptr<SkillEngine> m_skillEngine;
    navigation::MovementController* m_moveCtrl = nullptr;
    input::NonBlockingActuator* m_actuator = nullptr;
    combat::StutterStepController m_stutterStepper;
    combat::BossPhaseController m_bossPhaseCtrl;
    combat::MonsterPackClusterer m_packClusterer;
};
