#pragma once

#include "../CommandHistory.h"
#include <pxr/usd/usd/stage.h>
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/sdf/valueTypeName.h>
#include <pxr/usd/sdf/layer.h>
#include <string>

namespace UsdLayerManager {

/// Connects a shader input to an upstream shader output, sparsely authoring
/// both attributes (with the given types) if they don't already exist.
/// Captures whatever the input was previously connected to (if anything) so
/// Undo can restore it exactly rather than merely disconnecting.
class ConnectShaderAttrsCommand : public ICommand {
public:
    /// editLayer: layer to author into (mirrors TransformCommand's pattern).
    /// Captured at construction time so Undo() targets the same layer as
    /// Execute() even if the stage's ambient edit target changes in between
    /// (e.g. a render-layer switch) — pass null/empty to fall back to
    /// whatever the ambient edit target is at call time (today's behavior).
    ConnectShaderAttrsCommand(pxr::UsdStageRefPtr stage,
                              const pxr::SdfPath&  destNode,
                              const std::string&   destInput,
                              const pxr::SdfValueTypeName& destType,
                              const pxr::SdfPath&  sourceNode,
                              const std::string&   sourceOutput,
                              const pxr::SdfValueTypeName& sourceType,
                              pxr::SdfLayerHandle  editLayer = pxr::SdfLayerHandle());

    void Execute() override;
    void Undo()    override;
    std::string GetDescription() const override { return m_description; }

private:
    pxr::UsdStageRefPtr   m_stage;
    pxr::SdfPath          m_destNode;
    std::string           m_destInput;
    pxr::SdfValueTypeName m_destType;
    pxr::SdfPath          m_sourceNode;
    std::string           m_sourceOutput;
    pxr::SdfValueTypeName m_sourceType;
    pxr::SdfLayerHandle   m_editLayer;
    std::string           m_description;

    bool        m_hadPriorConnection = false;
    pxr::SdfPath m_priorSourceNode;
    std::string  m_priorSourceOutput;
};

} // namespace UsdLayerManager
