#pragma once
#include <Ogre.h>
#include <OgreApplicationContext.h>
#include <OgreInput.h>
#include <OgreOverlaySystem.h>
#include <OgreImGuiOverlay.h>
#include <flecs.h>
#include <memory>

// Forward declarations
class EditorUISystem;
class EditorCamera;

class EditorApp : public OgreBites::ApplicationContext,
                  public OgreBites::InputListener
{
public:
    EditorApp();
    virtual ~EditorApp();

    void setup() override;
    bool frameRenderingQueued(const Ogre::FrameEvent& evt) override;

    // Ogre 14.5 input handling
    bool mouseMoved(const OgreBites::MouseMotionEvent& evt) override;
    bool mousePressed(const OgreBites::MouseButtonEvent& evt) override;
    bool mouseReleased(const OgreBites::MouseButtonEvent& evt) override;
    bool keyPressed(const OgreBites::KeyboardEvent& evt) override;
    bool keyReleased(const OgreBites::KeyboardEvent& evt) override;

    // Setup methods
    void setupScene();
    void setupImGui();
    void setupFlecs();
    void createAxisHelper();

    // Helper methods
    void toggleGrid();
    void toggleAxes();
    void reloadResources();

    // Getters
    flecs::entity getSelectedEntity() const { return mSelectedEntity; }
    Ogre::SceneManager* getSceneManager() const { return mSceneMgr; }

    // Helper to check modifier keys using current state
    bool isCtrlPressed() const { return (mCurrentModifiers & OgreBites::KMOD_CTRL) != 0; }
    bool isShiftPressed() const { return (mCurrentModifiers & OgreBites::KMOD_SHIFT) != 0; }
    bool isAltPressed() const { return (mCurrentModifiers & OgreBites::KMOD_ALT) != 0; }

private:
    // Ogre objects
    Ogre::SceneManager* mSceneMgr;
    Ogre::OverlaySystem* mOverlaySystem;
    Ogre::ImGuiOverlay* mImGuiOverlay;

    // ECS
    flecs::world mWorld;
    flecs::entity mSelectedEntity;

    // Editor state
    Ogre::Vector3 m3DCursorPosition;
    bool mIsDraggingCursor;
    bool mGridVisible;
    bool mAxesVisible;

    // Modifier key tracking
    uint16_t mCurrentModifiers;

    // Editor systems
    std::unique_ptr<EditorUISystem> mUISystem;
    std::unique_ptr<EditorCamera> mEditorCamera;
};
