// Copyright 2015 - 2026, GIBIS-UNIFESP and the wiRedPanda contributors
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QObject>
#include <QTemporaryDir>

class TestSceneUndoredo : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();

    // Undo/Redo & Scene State Tests
    void testReceiveCommand();
    void testPasteUndoRedo();
    void testCutUndoRedo();
    void testMultiCommandSequence();

    // DeleteItemsCommand
    void testDeleteElementAndUndo();
    void testDeleteWithConnectionsRestored();

    // RotateCommand
    void testRotateSingleElement();
    void testRotateUndoRedo();
    void testRotateAccumulates();

    // MoveCommand
    void testMoveSingleElement();
    void testMoveMultipleElements();
    void testMidDragDeleteDoesNotCrash(); // regression: WIREDPANDA-H9 / WIREDPANDA-EV

    // FlipCommand
    void testFlipHorizontalUndoRedo();
    void testFlipVerticalUndoRedo();

    // MorphCommand
    void testMorphTypeChange();
    void testMorphPreservesLabel();
    void testMorphPreservesConnections();

    // ChangePortSizeCommand
    void testIncreaseInputSize();
    void testDecreaseInputSizeRemovesConnection();

    // ChangePortSizeCommand edge cases
    void testDecreaseInputSizeMultipleConnections();
    void testDecreaseInputSizeRestoresConnectionWithOriginalId();

    // ChangePortSizeCommand
    void testChangeOutputSizeUndoRedo();
    void testChangeOutputSizeMultipleElements();
    void testDecreaseOutputSizeRestoresConnectionWithOriginalId();

    // SplitCommand
    void testSplitConnectionCreatesNode();

    // UpdateCommand
    void testUpdateCommandUndoRedo();
    void testUpdateCommandWirelessModeUndoRedo();
    void testUpdateCommandRxModeIsRequired();
    void testWirelessModeUndoRestoresConnection();
    void testWirelessRxModeUndoRestoresConnection();
    void testWirelessUndoRestoresPortVisibility();

    // Edge cases
    void testNewOperationClearsRedoStack();
    void testUndoBeyondBeginning();
    void testRedoBeyondEnd();

    // Additional FlipCommand edge cases
    void testFlipRotationChanges();           // flip toggles mirror flag, rotation unchanged
    void testFlipNonRotatableElement();        // Led/InputSwitch: position flips, flip flags untouched
    void testFlipSingleElementPositionUnchanged(); // min==max → position unchanged, flip flag toggles

    // Additional RotateCommand edge cases
    void testRotateMultipleElementsPositionsChange(); // collective center pivot

    // Additional DeleteItemsCommand edge cases
    void testDeleteMultipleElements();         // delete 3 elements simultaneously

    // AddItemsCommand (direct, not via paste)
    void testAddItemsCommandDirect();          // items added in constructor; first redo() is no-op

    // Additional MorphCommand edge cases
    void testMorphMultipleElements();          // morph AND+OR→Xor simultaneously
    void testMorphDisplay14ToDisplay7RemovesDanglingConnection(); // regression: wire on dropped port must be deleted
    void testMorphToFewerPortsAllDroppedConnectionsRemoved();     // all connections on removed ports deleted
    void testMorphUndoRestoresConnectionWithOriginalId();         // restored connection keeps its scene ID

    // QUndoStack clean state (save-dirty tracking)
    void testUndoStackCleanState();

    // Multi-workspace isolation (cross-tab regression tests)
    void testCrossTabIdIsolation();

    // Autosave context directory isolation
    void testContextDirectoryPerTab();

    // Serialization::serialize portMap collision regression
    void testDeleteUndoConnectionsReattachedCorrectly();  // port endpoints point to correct elements
    void testDeleteUndoRedoConnectionCountStable();       // connection count stable across cycles
    void testDeleteChainMiddleUndoRestoresTopology();     // A→B→C: delete B, undo, verify chain
    void testDeleteUndoSimulationCorrectness();           // AND gate truth table survives delete+undo

private:
    QTemporaryDir m_tempDir;
};
