#pragma once
#include <atomic>
#include <functional>

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>
#include <d3d11.h>
#include <imgui.h>

// Standard ImGui + DX11 window, always-on-top, fullscreen popup.
// The game is visible through the mostly-dark background while ImGui
// draw-list calls render the ESP data on top.
class OverlayWindow {
public:
    using DrawFn        = std::function<void(float w, float h)>;
    using InputQueryFn  = std::function<bool()>;
    using FontReadyFn   = std::function<void(ImFont* lootClose, ImFont* lootFar)>;

    OverlayWindow()  = default;
    ~OverlayWindow() = default;

    OverlayWindow(const OverlayWindow&)            = delete;
    OverlayWindow& operator=(const OverlayWindow&) = delete;

    void SetDrawCallback(DrawFn fn)             { m_draw        = std::move(fn); }
    void SetInputQueryCallback(InputQueryFn fn) { m_queryInput  = std::move(fn); }
    // Called once after ImGui fonts are built, before the first frame.
    void SetFontReadyCallback(FontReadyFn fn)   { m_onFontReady = std::move(fn); }

    // Override the window size used at creation (0 = use GetSystemMetrics).
    void SetResolutionOverride(int w, int h)    { m_overrideW = w; m_overrideH = h; }

    // Resize the live window; triggers WM_SIZE which the render loop handles.
    void ResizeTo(int w, int h);

    // Blocks until stopFlag becomes true or the window is closed.
    void Run(std::atomic<bool>& stopFlag);

    // Called from WndProc for WM_SIZE
    UINT m_resizeW = 0;
    UINT m_resizeH = 0;

    // Resolution override — set before Run(); 0 = auto from screen metrics.
    int  m_overrideW = 0;
    int  m_overrideH = 0;

private:
    DrawFn        m_draw;
    InputQueryFn  m_queryInput;
    FontReadyFn   m_onFontReady;
    bool          m_prevWantInput = false;

    HWND                    m_hwnd = nullptr;
    ID3D11Device*           m_dev  = nullptr;
    ID3D11DeviceContext*    m_ctx  = nullptr;
    IDXGISwapChain*         m_sc   = nullptr;
    ID3D11RenderTargetView* m_rtv  = nullptr;

    int m_w = 0;
    int m_h = 0;

    bool CreateWin32Window();
    bool CreateDX11();
    void CreateRTV();
    void CleanupRTV();
    void Destroy();

    static LRESULT WINAPI WndProc(HWND h, UINT msg, WPARAM w, LPARAM l);
};
