#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#ifndef NOMINMAX
#define NOMINMAX
#endif

#include <windows.h>
#include <cstdint>
#include <cmath>
#include <algorithm>

#include "common/protocol.hpp"
#include "common/math2d.hpp"
#include "input/kmbox_net.hpp"
#include "input/non_blocking_actuator.hpp"
#include "navigation/movement_controller.hpp"
#include "navigation/terrain_grid.hpp"

namespace combat {

/**
 * @brief Chu kỳ FSM của Stutter-Stepping (ExiledBot 2 Model).
 */
enum class StutterPhase : uint8_t {
    Idle = 0,             // Không có giao tranh, di chuyển bình thường
    AimAndWindup = 1,     // Auto-Facing: Xoay mặt và con trỏ chuột về quái
    Casting = 2,          // Đang kích hoạt giữ phím skill (dwell time)
    StepRecover = 3       // Vừa nhả skill, lập tức tái kích hoạt di chuyển (Stutter Step)
};

/**
 * @brief Kết quả đánh giá mục tiêu tối ưu (Auto-Targeting / Auto-Facing).
 * POD 64 bytes (1 cache line), 0 dynamic allocation.
 */
struct alignas(64) TargetEvaluation {
    uint32_t entityId = 0;
    float posX = 0.0f;
    float posY = 0.0f;
    float dx = 0.0f;
    float dy = 0.0f;
    float distance = 0.0f;
    float facingAngleRad = 0.0f;      // Góc quay mặt (radian)
    float screenAimX = 0.0f;          // Tọa độ chuột Isometric X trên màn hình
    float screenAimY = 0.0f;          // Tọa độ chuột Isometric Y trên màn hình
    float priorityScore = -99999.0f;  // Điểm ưu tiên quái
    bool valid = false;
    bool isBoss = false;
    bool isStaggered = false;
    bool hasLineOfSight = true;
};

/**
 * @brief Cấu hình Micro-Stutter-Step và Auto-Targeting.
 */
struct StutterStepConfig {
    uint32_t minDwellCastMs = 40;       // Thời gian giữ phím skill tối thiểu (40ms)
    uint32_t postCastStepDelayMs = 20;  // Độ trễ bước di chuyển sau khi nhả chiêu (20ms)
    float maxScanRadius = 450.0f;       // Bán kính tự động quét mục tiêu
    float safeKiteRadius = 130.0f;      // Ngưỡng khoảng cách kích hoạt kiting lùi khi bị áp sát
    bool prioritizeBoss = true;         // Ưu tiên Boss khi auto-targeting
    bool enableAutoFacing = true;       // Kích hoạt tự động xoay mặt về mục tiêu
    bool enableKitingStep = true;       // Cho phép bước lùi kiting khi quái quá gần
};

/**
 * @brief Thống kê hiệu năng DOD thực tế.
 */
struct StutterStepStats {
    uint64_t totalTargetsEvaluated = 0;
    uint64_t totalCastsExecuted = 0;
    uint64_t totalStutterSteps = 0;
    double lastDispatchLatencyUs = 0.0;
};

/**
 * @brief StutterStepController - Quản lý Micro-Stutter-Stepping và Auto-Targeting (Tier 1 Hot Path 120Hz).
 * 
 * Học hỏi từ ExiledBot 2:
 * 1. Auto-Facing: Tự động tính toán vector và xoay mặt nhân vật về quái gần nhất/Boss.
 * 2. Stutter-Stepping: Chạy -> Quay mặt bắn (Cast) -> Nhả phím -> Lập tức di chuyển tiếp (Step).
 * 3. Triệt tiêu hoàn toàn hiện tượng đứng khựng (Stop-and-Go stutter) trong giao tranh.
 * 4. Data-Oriented Design: O(1) memory, 0 dynamic allocation, latency < 0.05 µs.
 */
class StutterStepController {
public:
    explicit StutterStepController(const StutterStepConfig& config = StutterStepConfig{});

    void SetConfig(const StutterStepConfig& config) { m_config = config; }
    const StutterStepConfig& Config() const { return m_config; }
    const StutterStepStats& Stats() const { return m_stats; }

    /**
     * @brief Đánh giá và chọn mục tiêu tối ưu nhất từ Telemetry (Auto-Targeting).
     * O(N), 0 dynamic allocation, latency < 0.03 µs.
     */
    TargetEvaluation EvaluateBestTarget(const TelemetryPacket& packet,
                                        const navigation::TerrainGrid* grid = nullptr,
                                        uint32_t preferredTargetId = 0,
                                        CombatProfile profile = CombatProfile::MOB_CLEARING,
                                        int screenW = 1920, int screenH = 1080) const;

    /**
     * @brief Tự động quay mặt về mục tiêu (Auto-Facing).
     */
    bool AutoFaceTarget(const TargetEvaluation& target,
                        KMBoxNet& kmbox);

    /**
     * @brief Điều phối chu kỳ Micro-Stutter-Step trong nhịp tick 120Hz.
     * 
     * @param packet Gói telemetry thế giới game
     * @param target Mục tiêu đã chọn từ EvaluateBestTarget
     * @param moveCtrl Bộ điều khiển di chuyển duy nhất (MovementController)
     * @param actuator Bộ chấp hành phi khóa NonBlockingActuator (có thể nullptr)
     * @param kmbox Giao tiếp phần cứng KMBox
     * @param skillVk Phím ảo của chiêu muốn tung (VD: VK_RBUTTON, 'Q', 'E')
     * @param desiredMoveDx Hướng di chuyển mong muốn khi không kiting
     * @param desiredMoveDy Hướng di chuyển mong muốn khi không kiting
     * @param nowMs Mốc thời gian hiện tại (ms)
     * @return true nếu lệnh combat/stutter-step được xử lý
     */
    bool StepTick(const TelemetryPacket& packet,
                  const TargetEvaluation& target,
                  navigation::MovementController& moveCtrl,
                  input::NonBlockingActuator* actuator,
                  KMBoxNet& kmbox,
                  uint8_t skillVk,
                  float desiredMoveDx, float desiredMoveDy,
                  uint64_t nowMs);

    /**
     * @brief Reset trạng thái FSM về Idle.
     */
    void Reset();

    StutterPhase Phase() const { return m_phase; }
    uint64_t LastCastMs() const { return m_lastCastTimestampMs; }
    uint64_t LastStepMs() const { return m_lastStepTimestampMs; }
    const TargetEvaluation& LastTarget() const { return m_lastTarget; }

private:
    StutterStepConfig m_config;
    mutable StutterStepStats m_stats{};

    StutterPhase m_phase = StutterPhase::Idle;
    TargetEvaluation m_lastTarget{};
    uint8_t m_currentCastingVk = 0;
    uint64_t m_lastCastTimestampMs = 0;
    uint64_t m_castReleaseTimestampMs = 0;
    uint64_t m_lastStepTimestampMs = 0;
    float m_lastFacingAngleRad = 0.0f;
};

} // namespace combat
