#pragma once

#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <cstdint>
#include <string>
#include <vector>
#include <memory>

#include "common/protocol.hpp"
#include "visual/world_to_screen.hpp"
#include "memory/imemory_reader.hpp"

namespace visual {

struct FilterOptions {
    bool showBosses = true;
    bool showRareMonsters = true;
    bool showStrongboxes = true;
    bool showShrines = true;
    bool showBreachRitualDelirium = true;
    float maxDetectionDistance = 250.0f; // in-game world units (~2 screens)
};

class PoiRadar {
public:
    explicit PoiRadar(IMemoryReader& memory);
    ~PoiRadar() = default;

    void SetFilterOptions(const FilterOptions& options) { options_ = options; }
    const FilterOptions& GetFilterOptions() const { return options_; }

    void SetScreenDimensions(int width, int height) {
        screenWidth_ = width;
        screenHeight_ = height;
    }

    void SetCameraMatrix(const Matrix4x4& matrix) {
        viewProj_ = matrix;
    }

    void SetCameraMatrix(const float rawMatrix[16]) {
        viewProj_ = Matrix4x4(rawMatrix);
    }

    void SetPlayerPosition(const Vector3& playerPos, float cameraYaw = 0.0f) {
        playerPos_ = playerPos;
        cameraYaw_ = cameraYaw;
    }

    // Direct registration of an entity (used by engine scanner and unit tests)
    bool AddEntity(
        uint64_t id,
        PoiType type,
        const Vector3& worldPos,
        float healthPct = 1.0f,
        const std::string& name = ""
    );

    // Clears the active entity list before a new scan cycle
    void Clear();

    // Traverses raw entity buffer (mock or game) and collects POIs
    size_t ScanRawEntities(uintptr_t entityListAddr, size_t maxCount);

    // Exports active POI list into the IPC shared memory struct using seqlock synchronization
    void ExportToSharedState(PoiRadarSharedState& outState);

    // Reader helper: extracts POIs from shared state reliably with seqlock validation
    static bool ReadSharedStateSafely(const PoiRadarSharedState& inState, PoiRadarSharedState& outCopy);

    // Helper to get string description of POI type
    static const char* GetPoiTypeName(PoiType type);

    size_t EntityCount() const { return activeEntities_.size(); }
    const std::vector<PoiSharedEntity>& GetActiveEntities() const { return activeEntities_; }

private:
    IMemoryReader& memory_;
    FilterOptions options_;
    int screenWidth_ = 1920;
    int screenHeight_ = 1080;
    Matrix4x4 viewProj_{};
    Vector3 playerPos_{};
    float cameraYaw_ = 0.0f;

    std::vector<PoiSharedEntity> activeEntities_;
    uint32_t seqlock_ = 0;
};

} // namespace visual
