#pragma once

#include <pxr/usd/usd/stage.h>
#include <pxr/usd/usd/attribute.h>
#include <pxr/usd/usd/editContext.h>
#include <pxr/usd/sdf/layer.h>
#include <string>
#include <vector>
#include <memory>
#include <variant>

PXR_NAMESPACE_USING_DIRECTIVE

namespace UsdLayerManager {

class CommandHistory;

using PropertyValue = std::variant<
    bool, int, float, double, std::string,
    pxr::GfVec3f, pxr::GfVec3d
>;

struct PropertyInfo {
    std::string name;
    std::string displayName;
    std::string typeName;
    pxr::UsdAttribute attribute;
    bool hasValue;
    PropertyValue value;
    std::string layerStack;
};

class PropertyManager {
public:
    PropertyManager();
    ~PropertyManager();
    
    void SetStage(UsdStageRefPtr stage);
    void SetCurrentLayer(const SdfLayerHandle& layer);
    void SetCommandHistory(CommandHistory* history) { m_commandHistory = history; }
    SdfLayerHandle GetCurrentLayer() const { return m_currentLayer; }
    
    // Prim properties
    std::vector<PropertyInfo> GetPrimProperties(const std::string& primPath);
    std::vector<PropertyInfo> GetPrimProperties(const UsdPrim& prim);
    
    // Property editing
    bool SetPropertyValue(const std::string& primPath, const std::string& propName, 
                          const PropertyValue& value);
    bool SetPropertyValueInLayer(const std::string& primPath, const std::string& propName,
                                 const PropertyValue& value, const SdfLayerHandle& layer);
    
    // Property info
    std::string GetPropertyLayerStack(const UsdAttribute& attr);
    
    // Prim hierarchy
    std::vector<std::string> GetPrimPaths();
    UsdPrim GetPrim(const std::string& path);
    
private:
    void CollectProperties(const UsdPrim& prim, std::vector<PropertyInfo>& props);
    PropertyValue ExtractValue(const UsdAttribute& attr);
    bool ApplyValue(const UsdAttribute& attr, const PropertyValue& value);
    
    UsdStageRefPtr m_stage;
    SdfLayerHandle m_currentLayer;
    CommandHistory* m_commandHistory = nullptr;
};

} // namespace UsdLayerManager