#include "LayerCommands.h"
#include "../../utils/Logger.h"

namespace UsdLayerManager {

// ─── LayerCreateCommand ───────────────────────────────────────────────────────

LayerCreateCommand::LayerCreateCommand(LayerManager* mgr, std::string path, int index)
    : m_mgr(mgr)
    , m_path(std::move(path))
    , m_index(index)
    , m_description("Create Layer " + m_path)
{
}

void LayerCreateCommand::Execute() {
    if (!m_mgr) return;
    auto before = m_mgr->GetSublayers().size();
    m_mgr->CreateSublayer(m_path, m_index);
    // Find the sublayer-local index so Undo() can call RemoveSublayer() correctly.
    // RemoveSublayer() uses indices into GetSubLayerPaths() (0..N-1), not the full
    // layer stack that includes session and root layers.
    auto sublayers = m_mgr->GetSublayers();
    if (sublayers.size() > before) {
        for (int i = 0; i < static_cast<int>(sublayers.size()); ++i) {
            if (sublayers[i].identifier == m_path) {
                m_insertedIndex = i;
                break;
            }
        }
    }
}

void LayerCreateCommand::Undo() {
    if (!m_mgr) return;
    if (m_insertedIndex >= 0) {
        m_mgr->RemoveSublayer(m_insertedIndex);
    }
}

// ─── LayerRemoveCommand ───────────────────────────────────────────────────────

LayerRemoveCommand::LayerRemoveCommand(LayerManager* mgr, int index)
    : m_mgr(mgr)
    , m_index(index)
    , m_description("Remove Layer")
{
    if (!mgr) return;
    auto sublayers = mgr->GetSublayers();
    if (index >= 0 && index < static_cast<int>(sublayers.size())) {
        m_savedPath   = sublayers[index].identifier;
        m_description = "Remove Layer " + sublayers[index].displayName;
    }
}

void LayerRemoveCommand::Execute() {
    if (!m_mgr) return;
    m_mgr->RemoveSublayer(m_index);
}

void LayerRemoveCommand::Undo() {
    if (!m_mgr || m_savedPath.empty()) return;
    // Re-insert at the original index.
    m_mgr->InsertSublayerPath(m_savedPath, m_index);
}

// ─── LayerReorderCommand ──────────────────────────────────────────────────────

LayerReorderCommand::LayerReorderCommand(LayerManager*            mgr,
                                         std::vector<std::string> before,
                                         std::vector<std::string> after)
    : m_mgr(mgr)
    , m_before(std::move(before))
    , m_after(std::move(after))
    , m_description("Reorder Layers")
{
}

void LayerReorderCommand::Execute() { ApplyOrder(m_after);  }
void LayerReorderCommand::Undo()    { ApplyOrder(m_before); }

void LayerReorderCommand::ApplyOrder(const std::vector<std::string>& order) {
    if (!m_mgr) return;

    // RemoveSublayer() operates on GetSubLayerPaths() — a sublayer-local list
    // with indices 0..N-1.  GetLayerStack() prepends session and root layers, so
    // its indices are always wrong here.  Use GetSublayers().size() for the count.
    int count = static_cast<int>(m_mgr->GetSublayers().size());
    for (int i = count - 1; i >= 0; --i)
        m_mgr->RemoveSublayer(i);

    for (const auto& path : order)
        m_mgr->InsertSublayerPath(path, -1);
}

} // namespace UsdLayerManager
