#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif

#include <cstdint>
#include <cstddef>
#include <array>
#include <random>
#include "common/fixed_keys.hpp"

namespace input {

/**
 * @brief Cấu hình quỹ đạo chuột sinh học bậc 5 (Quintic Bézier Configuration)
 */
struct QuinticBezierConfig {
    int defaultSteps = 22;              // Số bước di chuyển (15 - 30 bước cho cự ly thông thường)
    float curvatureVariance = 0.22f;    // Độ uốn lượn tiếp tuyến tối đa (% cự ly di chuyển)
    float maxLateralDeviation = 85.0f;  // Độ lệch ngang tối đa (pixels)
    float overshootProbability = 0.30f; // Tỷ lệ xuất hiện overshoot sinh học (30%)
    float overshootMinDist = 60.0f;     // Cự ly tối thiểu để kích hoạt overshoot (pixels)
    float minJerkExponent = 5.0f;       // Hàm nội suy Flash & Hogan bậc 5
    
    // Thông số nhiễu vi rung sinh học (Biomechanical Micro-Tremor)
    bool enablePerlinTremor = true;     // Bật nhiễu Perlin tần số thấp (8-12Hz)
    float tremorFrequency = 11.5f;      // Tần số rung cơ tự nhiên (Hz)
    float tremorAmplitude = 1.4f;       // Biên độ rung cơ bản (pixels)
    bool enableGaussianJitter = true;   // Bổ sung nhiễu Gauss vi mô (sub-pixel)
    float gaussianSigma = 0.35f;        // Độ lệch chuẩn Gauss (pixels)
};

/**
 * @brief Bộ điều khiển quỹ đạo chuột Quintic Bézier kết hợp nhiễu Perlin/Gaussian
 * Đạt chuẩn Triệt Tiêu Pattern Máy Móc & Vượt Qua AI Heuristic Anti-Cheat (2026).
 * 100% Zero Dynamic Allocation, Data-Oriented Design.
 */
class QuinticBezierController {
public:
    explicit QuinticBezierController(const QuinticBezierConfig& config = QuinticBezierConfig{});

    void SetConfig(const QuinticBezierConfig& config) { m_config = config; }
    const QuinticBezierConfig& Config() const { return m_config; }

    /**
     * @brief Sinh quỹ đạo di chuyển chuột sinh học (Zero Heap Allocation)
     * @param start Tọa độ điểm bắt đầu (pixels màn hình)
     * @param target Tọa độ điểm kết thúc (pixels màn hình)
     * @param outBuf Buffer tĩnh 32 phần tử chứa các bước vi phân (dx, dy)
     * @param steps Số bước (nếu <= 0, tự tính toán theo định luật Fitts)
     */
    void GenerateTrajectory(
        Vector2D start,
        Vector2D target,
        common::TrajectoryBuffer& outBuf,
        int steps = 0
    );

    /**
     * @brief Sinh thời gian dwell time (giữ nút chuột/phím) theo phân phối sinh học
     */
    int GenerateDwellTimeMs(float meanMs = 65.0f, float stdDevMs = 12.0f);

    /**
     * @brief Tính toán giá trị đường cong Bézier bậc 5 tại tham số t in [0, 1]
     */
    static Vector2D EvaluateQuinticBezier(
        float t,
        Vector2D p0, Vector2D p1, Vector2D p2,
        Vector2D p3, Vector2D p4, Vector2D p5
    );

    /**
     * @brief Hàm nội suy thời gian Flash & Hogan Minimum Jerk bậc 5
     * s(tau) = 10*tau^3 - 15*tau^4 + 6*tau^5, đạo hàm bậc 1 và bậc 2 triệt tiêu tại 0 và 1.
     */
    static float EvaluateMinimumJerk(float tau);

    /**
     * @brief Nhiễu Perlin gradient 1 chiều liên tục
     */
    static float PerlinNoise1D(float x);

private:
    QuinticBezierConfig m_config;
    std::mt19937 m_rng;
    std::normal_distribution<float> m_gaussianDist;
    std::uniform_real_distribution<float> m_uniformDist;

    // Bảng hoán vị cố định cho hàm Perlin 1D
    static const std::array<uint8_t, 512> s_perlinPermutation;
};

} // namespace input
