#include "CreateShaderNodeCommand.h"
#include "../../utils/Logger.h"
#include <pxr/usd/usdShade/shader.h>
#include <pxr/base/tf/token.h>
#include <pxr/base/vt/value.h>

namespace UsdLayerManager {

CreateShaderNodeCommand::CreateShaderNodeCommand(pxr::UsdStageRefPtr stage,
                                                 const pxr::SdfPath&  path,
                                                 const std::string&   shaderId,
                                                 const pxr::GfVec2f&  uiPosition)
    : m_stage(stage)
    , m_path(path)
    , m_shaderId(shaderId)
    , m_uiPosition(uiPosition)
    , m_description("Create Shader " + shaderId + " " + path.GetString())
{
}

void CreateShaderNodeCommand::Execute() {
    if (!m_stage) return;
    try {
        pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(m_stage, m_path);
        if (!shader) {
            LOG_ERROR("CreateShaderNodeCommand: failed to define shader " + m_path.GetString());
            return;
        }
        shader.SetShaderId(pxr::TfToken(m_shaderId));
        shader.GetPrim().SetCustomDataByKey(pxr::TfToken("uiPosition"), pxr::VtValue(m_uiPosition));
    } catch (const std::exception& e) {
        LOG_ERROR(std::string("CreateShaderNodeCommand::Execute error: ") + e.what());
    }
}

void CreateShaderNodeCommand::Undo() {
    if (!m_stage) return;
    try {
        if (!m_stage->RemovePrim(m_path))
            LOG_ERROR("CreateShaderNodeCommand: failed to remove prim " + m_path.GetString());
    } catch (const std::exception& e) {
        LOG_ERROR(std::string("CreateShaderNodeCommand::Undo error: ") + e.what());
    }
}

} // namespace UsdLayerManager
