#pragma once

#include <cstdint>
#include <cstddef>
#include <array>
#include <algorithm>

// ==========================================================
// AutoPOE2 Common Kernel - Fixed Stack Arrays (Zero Heap Allocation)
// C++23 DOD Standard for 120Hz Hot Path (SPEC-P7-NONBLOCKING-ACTUATOR-ZEROHEAP-2026)
// ==========================================================

struct Vector2D {
    float x = 0.0f;
    float y = 0.0f;
};

namespace common {

/**
 * @brief WasdKeyArray - Cấu trúc mảng tĩnh lưu tối đa 4 phím VK của hướng di chuyển WASD.
 * Kích thước chính xác 5 bytes, nằm trọn trong stack/thanh ghi CPU, 0 dynamic allocation.
 */
struct WasdKeyArray {
    uint8_t keys[4] = {};
    uint8_t count = 0;

    constexpr WasdKeyArray() noexcept = default;

    void clear() noexcept {
        count = 0;
    }

    void push_back(uint8_t vk) noexcept {
        if (count < 4) {
            keys[count++] = vk;
        }
    }

    [[nodiscard]] bool empty() const noexcept {
        return count == 0;
    }

    [[nodiscard]] size_t size() const noexcept {
        return count;
    }

    [[nodiscard]] uint8_t operator[](size_t idx) const noexcept {
        return keys[idx];
    }

    [[nodiscard]] bool contains(uint8_t vk) const noexcept {
        for (uint8_t i = 0; i < count; ++i) {
            if (keys[i] == vk) return true;
        }
        return false;
    }

    [[nodiscard]] bool operator==(const WasdKeyArray& other) const noexcept {
        if (count != other.count) return false;
        for (uint8_t i = 0; i < count; ++i) {
            if (!other.contains(keys[i])) return false;
        }
        return true;
    }

    [[nodiscard]] const uint8_t* begin() const noexcept { return keys; }
    [[nodiscard]] const uint8_t* end() const noexcept { return keys + count; }
    [[nodiscard]] uint8_t* begin() noexcept { return keys; }
    [[nodiscard]] uint8_t* end() noexcept { return keys + count; }
};

/**
 * @brief TrajectoryBuffer - Bộ đệm tĩnh lưu các bước di chuyển chuột tương đối Bézier.
 * Dung lượng tối đa 32 bước (đủ cho trajectory chuột 15-25 bước), 0 dynamic allocation.
 */
struct TrajectoryBuffer {
    std::array<Vector2D, 32> steps{};
    uint8_t count = 0;

    constexpr TrajectoryBuffer() noexcept = default;

    void clear() noexcept {
        count = 0;
    }

    void push_back(Vector2D pt) noexcept {
        if (count < 32) {
            steps[count++] = pt;
        }
    }

    [[nodiscard]] bool empty() const noexcept {
        return count == 0;
    }

    [[nodiscard]] size_t size() const noexcept {
        return count;
    }

    [[nodiscard]] const Vector2D& operator[](size_t idx) const noexcept {
        return steps[idx];
    }

    [[nodiscard]] Vector2D& operator[](size_t idx) noexcept {
        return steps[idx];
    }

    [[nodiscard]] const Vector2D* begin() const noexcept { return steps.data(); }
    [[nodiscard]] const Vector2D* end() const noexcept { return steps.data() + count; }
    [[nodiscard]] Vector2D* begin() noexcept { return steps.data(); }
    [[nodiscard]] Vector2D* end() noexcept { return steps.data() + count; }
};

} // namespace common
