import {create} from 'zustand'
import {devtools} from 'zustand/middleware'
import {Position} from "@xyflow/react";
import {BranchData} from "./StateBranchNode";
import {SelectActionNodeData} from "../SelectActionBranch";
import {ComponentRuntimeDataWithParentType} from "./components";
import {TreeContextData} from "./atoms";
import {produce} from "immer";
import {TestableEvent, Testables} from "./testables";
import {CreateTierBranchOptions, Tree} from "./Tree";
import {nodeTypes} from "../Tree";
import {EdgeData, RenderedNodeData} from "./FlowDataCreator";
import {Grove, GroveData} from "./Grove";
import {TreeNodeFactory} from "./TreeNodeFactory";
import {Offers} from "./Offers";
import {generateIdForType, getIdTypeForTestable, wrapTestablesInDefaultGroup} from "./NodeHelpers";
import {GroveActions} from "./GroveActions";
import {Testable} from "./Testable";
import {NestedTestableNodeData} from "./InMemoryTestableNode";
import {AppImporter} from "./export/AppImporter";
import {TestableCompositeGroupType} from "./testableGroupTypes";
import type {ConditionColorPalette} from "./Colors";

export type TestableCompositeData = {
    id: string,
    type: TestableCompositeGroupType | string,
    mode: 'filter' | 'test',
    conditionColorPalette?: ConditionColorPalette,
}

export type TestableCompositeDataWithChildren = TestableCompositeData & {
    children: (TestableCompositeDataWithChildren | TestableData)[]
}

export type ComponentDataType = 'filter' | 'condition' | 'offer'

export type TestableData<Options = { [p: string]: any }> = {
    id: string,
    testableType: Exclude<ComponentDataType, 'offer'>,
    type: string,
    options: Options
}
export type OfferData<Options = object> = {
    id: string,
    type: string,
    options: Options
}
export type NodeData = TestableCompositeData | TestableData;
export type Nodes = NodeData[]
export type RenderedNode = {
    id: TestableCompositeData['id'],
    type: keyof typeof nodeTypes,
    data: {
        renderedNodeType: 'welcome' | 'root' | 'node' | 'action' | 'branch-offers' | 'branch-first-passing-node' | 'step-anchor' | 'branch-add-node-button',
        testableID?: string,
        sourceNodeId?: string,
        targetNodeId?: string,
        [key: string]: any,
    },
    position: { x: number, y: number },
    className?: string
};
export type RenderedNodeDataInBranch = WithSourceNodeId & {
    isInsideBranch: boolean,
}

export type WithSourceNodeId = {
    sourceNodeId: string // // this is done here so that we don't use regexes on every render
}

export type WithTargetNodeId = {
    targetNodeId: string, // this is done here so that we don't use regexes on every render
}

export type WithXSpacing = {
    xSpacing: number,
}

export type WithParentNodeId = {
    parentNodeId: string, // this is done here so that we don't use regexes on every render
}

export type TestablePartial<OptionsType extends object = { [k: string]: any }> = {
    id: string, // unique id for this partial
    //baseID: string, // this isn't needed here because we have testableRelations and having two "points of entry" can lead to nasty bugs
    options: OptionsType
};

export type NodesStore = {
    grove: GroveData,
    preconditionsID: string | undefined, // the id of the root testable for preconditions, which is always a testable composite group (OR)
    predatesID: string | undefined, // the id of the root testable for pre-dates, which is always a testable composite group (OR)
    // NEW: simple setter for preconditionsID
    testables: Nodes,
    testablePartials: TestablePartial[],
    testableRelations: {
        id: TestableCompositeData['id'],
        children: TestableCompositeData['id'][]
    }[],
    renderedNodes: RenderedNodeData[],
    couponsPlusNodeTypes: {
        id: string,
        branchType: BranchData['type']
    }[],
    branchRelations: {
        branch: BranchData['id'],
        children: (TestableCompositeData['id'] | OfferData['id'])[],
        childrenType: keyof NodesStore
    }[],
    /**
     * These are OUR Coupons+ nodes, NOT the rendered nodes from React Flow.
     * These nodes represent a branch and each is composed of a testable and a branch
     */
    nodes: string[],
    offers: OfferData[],
    edges: EdgeData[],

    autoApply: boolean,
    toggleAutoApply: () => void,
    /*addTestables: (testables: ComponentRuntimeDataWithParentType[], contextData: PopupWindowStateContext<TreeContextData>) => void,*/
    write: (modifier: (store: NodesStore) => void) => void,
    updateGrove: (modifier: (grove: Grove) => void) => void,
    importFromSource: (source: string, reset?: boolean, then?: () => {}) => void,
    // grove nodes (treenode, testablecomposite, branchnode, etc)
    getGroveNode: (id: string) => ReturnType<Grove['get']>,
    // testables
    getTestable: (testableId: string) => Testable | undefined,
    //offers
    getOffer: (offerId: string) => OfferData | undefined,
    addBranchOffer: GroveActions['addBranchOffer'],
    addTreeNode: typeof GroveActions.prototype.addTreeNode,
    //testables
    addTestable: (testable: NestedTestableNodeData, then: (groupId?: string, group?: TestableCompositeData) => any) => any,
    addTestables: (args: Parameters<Testables['addTestables']>, then?: (result: ReturnType<Testables['addTestables']>, testables: Testables, writeableStore: NodesStore) => any) => void,
    updateTestablePartial: (args: Parameters<Testables['updatePartial']>, then?: (result: ReturnType<Testables['updatePartial']>, testables: Testables) => any) => void,
    updateTestable: (args: Parameters<Testables['updateTestable']>, then?: (result: ReturnType<Testables['updateTestable']>, testables: Testables) => any) => void,
    wrapAllContexts: (args: Parameters<Testables['wrapAllContexts']>, then?: (result: ReturnType<Testables['wrapAllContexts']>, testables: Testables) => any) => void,
    changeTestableGroupOptions: Testables['changeTestableGroupOptions'],
    getReadOnlyTestables: () => Testables,
    //offers
    updateOffer: (offer: OfferData) => void,
    removeOffer: (offerID: string, branchId: string) => void,
    //tiers
    cloneTier: typeof GroveActions.prototype.cloneTier,
    // to add a tier, use addTreeNode()
    removeTier: typeof GroveActions.prototype.removeTier,
    removeTieredBranch: typeof GroveActions.prototype.removeTieredBranch,


    // old
    updateTestables: (modifier: (testables: Testables) => void) => void,
    removeTestable: (testableId: string) => void,
    addOffers: (offers: OfferData[], branchId: string) => void,
    createTierBranch: (options: CreateTierBranchOptions) => void,
    removeRenderedNode: (renderedNodeId: RenderedNode['id']) => void;
    updateTree: (modifier: (tree: Tree, testables: Testables) => void) => void,
    setRenderedNodes: (renderedNodes: NodesStore['renderedNodes']) => void,
}

export type Anchor = {
    id: string,
    position: Position
}

// @ts-ignore
// @ts-ignore

// @ts-ignore
// @ts-ignore
export const useNodesStore = create<NodesStore>
    // @ts-ignore
    (devtools((set, get) => ({
        grove: [
            /*{
                id: 'tree-node-7955',
                testableId: 'group-5572', // a way to get its target branch
                branch: {
                    id: 'branch-9875',
                    type: 'select-action',//'offers',
                    children: []//['offer-kigiyfi']
                    // a way to get its tetsbale group
                }
            }
            {
                testableId: '5572', // a way to get its target branch
                branch: {
                    type: 'offers',
                    children: ['jhf']
                    // a way to get its tetsbale group
                }
            }*/
        ],
        preconditionsID: undefined,
        predatesID: undefined,
        testables: [
            /*{
                id: 'group-5572',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: '5573',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '5574',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },*/
            /**first tree, not and or OR*/
            /*{
                id: '5572',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: '5573',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '5574',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: '5575',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },*/
            /**first tree with a branch (DISCOUNT)*/
            /*{
                id: '1-tree-with-discount-branch',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: '1-tree-with-discount-branch--1-context',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '1-tree-with-discount-branch--1-context--1-filter',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: '1-tree-with-discount-branch--1-context--2-filter',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },*/
            /**first nested testable!*/
            /*{
                id: 'first-passing-nodes-example->children->3->branch',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                })
            },*/
            /**second tree with a branch (FIRST-PASSING-NODES)*/
            /*{
                id: 'first-passing-nodes-example',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->context->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->context->filter->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: 'first-passing-nodes-example->context->filter->2',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            // first-passing-nodes-example->children->1 to 4
            {
                id: 'first-passing-nodes-example->children->1',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->children->1->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->1->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: 'first-passing-nodes-example->children->1->contexts->1->children->2',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            // first-passing-nodes-example->children->2
            {
                id: 'first-passing-nodes-example->children->2',
                'type': 'OR',
                'mode': 'filter', //or filter
            },
            //first context: first-passing-nodes-example->children->2
            {
                id: 'first-passing-nodes-example->children->2->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->2->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            //second context: first-passing-nodes-example->children->2
            {
                id: 'first-passing-nodes-example->children->2->contexts->2',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->2->contexts->2->children->1',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({
                })
            },
            // 3
            {
                id: 'first-passing-nodes-example->children->3',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->children->3->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->3->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: 'first-passing-nodes-example->children->3->contexts->1->children->2',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            // 4
            {
                id: 'first-passing-nodes-example->children->4',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->children->4->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->4->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: 'first-passing-nodes-example->children->4->contexts->1->children->2',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            // first-passing-nodes-example->children->3->branch->children->1 to 2
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            // nested 2
            // first-passing-nodes-example->children->3->branch->children->1 to 2
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2->contexts->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2->contexts->1->children->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },*/
            /**
             * Third tree with a branch (tiered)
             */
            /*{
                id: 'tiered-example',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            {
                id: 'tiered-example->context->1',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: 'tiered-example->context->filter->1',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            // tier base filters
            {
                id: 'tiered-example->children->1',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                })
            },*/
            /**second tree, OR*/
            /*OR TREE*/
            /*{
                id: '6572',
                'type': 'OR',
                'mode': 'test', //because we have a condition
            },
            // FIRST CONTEXT
            {
                id: '6573',
                'type': 'context',
                'mode': 'test',
            },
            {
                id: '6574',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: '6575',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            //SECOND CONTEXT
            {
                id: '6580',
                'type': 'context',
                'mode': 'test',
            },
            {
                id: '6581',
                'testableType': 'condition',
                'type': 'UserRole',
                'options': ({
                })
            },*/
            /*AND TREE*/
            /**Third tree, AND*/
            /*{
                id: '7572',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            // FIRST CONTEXT
            {
                id: '7573',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '7574',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: '7575',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            //SECOND CONTEXT
            {
                id: '7580',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '7581',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({})
            },
            //THIRD CONTEXT
            {
                id: '7582',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '7583',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({})
            },*/
            /****************************++
             * NESTING
             *****************************/
            /**Fourth tree, [A + B] OR C*/
            /*FIRST  LEVEL*/
            /*{
                id: '1000',
                'type': 'OR',
                'mode': 'filter', //or filter
            },
            // FIRST GROUP (+)
            {
                id: '1010',
                'type': 'AND',
                'mode': 'filter',
            },
            // FIRST CONTEXT
            {
                id: '1011',
                'type': 'context',
                'mode': 'filter', //or filter
            },
            {
                id: '1012',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: '1013',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            //SECOND CONTEXT
            {
                id: '1014',
                'type': 'context',
                'mode': 'filter', //or filter
            },
            {
                id: '1015',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({})
            },
            //SECOND GROUP
            {
                id: '1020',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '1021',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({})
            },*/
            /**Fifth tree, A + [B OR C]*/
            /*FIRST  LEVEL*/
            /*{
                id: '2000',
                'type': 'AND',
                'mode': 'filter', //or filter
            },
            //FIRST GROUP
            {
                id: '2020',
                'type': 'context',
                'mode': 'filter',
            },
            {
                id: '2021',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({})
            },
            // SECOND GROUP (or)
            {
                id: '2010',
                'type': 'OR',
                'mode': 'filter',
            },
            // FIRST CONTEXT
            {
                id: '2011',
                'type': 'context',
                'mode': 'filter', //or filter
            },
            {
                id: '2012',
                'testableType': 'filter',
                'type': 'InCategories',
                'options': ({
                    'expectedValues': [10, 43],
                    'inclusionType': 'allowed'
                })
            },
            {
                id: '2013',
                'testableType': 'filter',
                'type': 'NumberOfItems',
                'options': ({})
            },
            //SECOND CONTEXT
            {
                id: '2014',
                'type': 'context',
                'mode': 'filter', //or filter
            },
            {
                id: '2015',
                'testableType': 'filter',
                'type': 'Products',
                'options': ({})
            },*/
        ],
        // these are used by tiered branches and have a base parent in testables
        testablePartials: [],
        testableRelations: [
            /*{
                id: 'group-5572',
                children: ['5573']
            },
            {
                id: '5573',
                children: ['5574']
            },
            {
                id: 'testable-ZVjbO7cXp',
                children: [
                    'testable-partial-VDiDYCuBm2'
                ]
            },
            {
                id: 'testable-BeAOgm9Cq',
                children: [
                    'testable-partial-t5C1AAugDY'
                ]
            },
            {
                id: 'group-tle73Bex15',
                children: [
                    'context-I66wtkagET'
                ]
            },
            {
                id: 'context-I66wtkagET',
                children: [
                    'testable-lpqPmTcpu'
                ]
            },
            {
                id: 'testable-1FIqXFhtW',
                children: [
                    'testable-partial-X75uf01A3W',
                    'testable-partial-jifQIfItc',
                    'testable-partial-e2RChAwCU'
                ]
            }*/
            //FIRST TREE
            /*{
                id: '5572',
                children: ['5573']
            },
            {
                id: '5573',
                children: ['5574', '5575']
            },
            //FIRST TREE WITH A BRANCH (DISCOUNT)
            {
                id: '1-tree-with-discount-branch',
                children: ['1-tree-with-discount-branch--1-context']
            },
            {
                id: '1-tree-with-discount-branch--1-context',
                children: ['1-tree-with-discount-branch--1-context--1-filter', '1-tree-with-discount-branch--1-context--2-filter']
            },
            //SECOND TREE WITH A BRANCH (FIRST PASSING NODE)
            {
                id: 'first-passing-nodes-example',
                children: ['first-passing-nodes-example->context->1']
            },
            {
                id: 'first-passing-nodes-example->context->1',
                children: ['first-passing-nodes-example->context->filter->1', 'first-passing-nodes-example->context->filter->2']
            },
            //NESTED TREE WITH A BRANCH FIRST PASSING NODE
            {
                id: 'first-passing-nodes-example->children->3->branch',
                children: ['first-passing-nodes-example->children->3->branch->contexts->1']
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->contexts->1',
                children: ['first-passing-nodes-example->children->3->branch->contexts->1->children->1',]
            },
            // first passing node first branch
            // first-passing-nodes-example->children->1
            {
                id: 'first-passing-nodes-example->children->1',
                children: ['first-passing-nodes-example->children->1->contexts->1']
            },
            {
                id: 'first-passing-nodes-example->children->1->contexts->1',
                children: ['first-passing-nodes-example->children->1->contexts->1->children->1', 'first-passing-nodes-example->children->1->contexts->1->children->2']
            },
            // first-passing-nodes-example->children->2
            {
                id: 'first-passing-nodes-example->children->2',
                children: ['first-passing-nodes-example->children->2->contexts->1', 'first-passing-nodes-example->children->2->contexts->2']
            },
            {
                id: 'first-passing-nodes-example->children->2->contexts->1',
                children: ['first-passing-nodes-example->children->2->contexts->1->children->1',]
            },
            {
                id: 'first-passing-nodes-example->children->2->contexts->2',
                children: ['first-passing-nodes-example->children->2->contexts->2->children->1',]
            },
            // first-passing-nodes-example->children->3
            {
                id: 'first-passing-nodes-example->children->3',
                children: ['first-passing-nodes-example->children->3->contexts->1']
            },
            {
                id: 'first-passing-nodes-example->children->3->contexts->1',
                children: ['first-passing-nodes-example->children->3->contexts->1->children->1', 'first-passing-nodes-example->children->3->contexts->1->children->2']
            },
            // first-passing-nodes-example->children->4
            {
                id: 'first-passing-nodes-example->children->4',
                children: ['first-passing-nodes-example->children->4->contexts->1']
            },
            {
                id: 'first-passing-nodes-example->children->4->contexts->1',
                children: ['first-passing-nodes-example->children->4->contexts->1->children->1', 'first-passing-nodes-example->children->4->contexts->1->children->2']
            },

            // first passing node nested 1
            // first-passing-nodes-example->children->3->branch->children->2->contexts->1->children->1
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1',
                children: ['first-passing-nodes-example->children->3->branch->children->1->contexts->1']
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1->contexts->1',
                children: ['first-passing-nodes-example->children->3->branch->children->1->contexts->1->children->1',]
            },
            // first-passing-nodes-example->children->3->branch->children->2->contexts->1->children->
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2',
                children: ['first-passing-nodes-example->children->3->branch->children->2->contexts->1']
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2->contexts->1',
                children: ['first-passing-nodes-example->children->3->branch->children->2->contexts->1->children->1',]
            },
            //tTHIRD TREE WITH A BRANCH (TIERED)
            {
                id: 'tiered-example',
                children: ['tiered-example->context->1']
            },
            {
                id: 'tiered-example->context->1',
                children: ['tiered-example->context->filter->1']
            },
            //SECOND TREE
            {
                id: '6572',
                children: ['6573', '6580']
            },
            //SECOND TREE, FIRST CONTEXT
            {
                id: '6573',
                children: ['6574', '6575']
            },
            //SECOND TREE, FIRST CONTEXT
            {
                id: '6580',
                children: ['6581']
            },
            //THIRD TREE
            {
                id: '7572',
                children: ['7573', '7580', '7582']
            },
            //THIRD TREE, FIRST CONTEXT
            {
                id: '7573',
                children: ['7574', '7575']
            },
            //THIRD TREE, FIRST CONTEXT
            {
                id: '7580',
                children: ['7581']
            },
            //THIRD TREE, third CONTEXT
            {
                id: '7582',
                children: ['7583']
            },*/
            /****************************************
             * nesting
             *****************************************/
            //FOURTH TREE
            /*{
                id: '1000',
                children: ['1010', '1020']
            },
            //FOURTH TREE, FIRST GROUP
            {
                id: '1010',
                children: ['1011', '1014']
            },
            //FOURTH TREE, FIRST GROUP, FIRST CONTEXT
            {
                id: '1011',
                children: ['1012', '1013']
            },
            //FOURTH TREE, FIRST GROUP, SECOND CONTEXT
            {
                id: '1014',
                children: ['1015',]
            },
            //FOURTH TREE, SECOND GROUP
            // FOURTH TREE, SECOND CONTEXT
            {
                id: '1020',
                children: ['1021']
            },
            //FIFTH TREE
            {
                id: '2000',
                children: ['2010', '2020']
            },
            //FIFTH TREE, FIRST GROUP
            {
                id: '2010',
                children: ['2011', '2014']
            },
            //FIFTH TREE, FIRST GROUP, FIRST CONTEXT
            {
                id: '2011',
                children: ['2012', '2013']
            },
            //FIFTH TREE, FIRST GROUP, SECOND CONTEXT
            {
                id: '2014',
                children: ['2015',]
            },
            //FIFTH TREE, SECOND GROUP
            // FIFTH TREE, SECOND CONTEXT
            {
                id: '2020',
                children: ['2021']
            },*/
        ],
        renderedNodes: [
            /*// @ts-ignore
            {
                id: 'group-5572',
                type: 'tree-node',
                position: {x: 0, y: 0},
            },
            // @ts-ignore
            {
                id: 'branch-9875',
                type: 'select-action-branch',
                position: {x: 0, y: 0},
            }*/


            /*{
                id: '5572',
                type: 'tree-node',
                position: {x: 0, y: 0},
            },
            {
                id: 'branch-9875',
                type: 'branch-offers',
                position: {x: 0, y: 0},
            },*/
            /*{
                id: 'group-tle73Bex15->testable',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root',
                    isDefaultAND: true,
                    testableID: 'group-tle73Bex15'
                },
                position: {
                    x: 20,
                    y: 40
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1',
                type: 'tiered-base-node',
                data: {
                    type: 'numeric',
                    renderedNodeType: 'branch-first-passing-node',
                    sourceNodeId: 'group-tle73Bex15->testable',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->1.step-anchor',
                    testableID: 'testable-1FIqXFhtW'
                },
                position: {
                    x: 163.0390625,
                    y: 186
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: true,
                    sourceNodeId: 'group-tle73Bex15->testable',
                    targetNodeId: 'branch-btf4ui9d2y->children->1',
                    type: 'tiered-base',
                    xSpacing: 32
                },
                position: {
                    x: 119.0390625,
                    y: 199
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->1',
                type: 'tiered-subchild-node',
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->1->branch',
                    parentNodeId: 'branch-btf4ui9d2y->children->1',
                    testablePartialId: 'testable-partial-X75uf01A3W'
                },
                position: {
                    x: 329.8125,
                    y: 186
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->1.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: true,
                    sourceNodeId: 'branch-btf4ui9d2y->children->1',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->1',
                    type: 'tier-row',
                    label: 'A',
                    direction: 'horizontal',
                    y: 'middle'
                },
                position: {
                    x: 293.8125,
                    y: 197
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->1->branch',
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: true,
                    sourceNodeId: 'branch-btf4ui9d2y->children->1->subchildren->1'
                },
                position: {
                    x: 411.5625,
                    y: 189.5
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->buttons.add',
                type: 'branch-add-node-button',
                data: {
                    renderedNodeType: 'branch-add-node-button',
                    parentNodeId: 'branch-btf4ui9d2y->children->1',
                    lastAnchor: 'branch-btf4ui9d2y->children->1->subchildren->3.step-anchor'
                },
                position: {
                    x: 293.8125,
                    y: 330
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2',
                type: 'tiered-subchild-node',
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->2->branch',
                    parentNodeId: 'branch-btf4ui9d2y->children->1',
                    testablePartialId: 'testable-partial-jifQIfItc'
                },
                position: {
                    x: 329.8125,
                    y: 234
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'branch-btf4ui9d2y->children->1->subchildren->1.step-anchor',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->2',
                    type: 'tier-row',
                    label: 'B',
                    direction: 'horizontal',
                    y: 'middle'
                },
                position: {
                    x: 293.8125,
                    y: 245
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2->branch',
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: true,
                    sourceNodeId: 'branch-btf4ui9d2y->children->1->subchildren->2'
                },
                position: {
                    x: 411.5625,
                    y: 237.5
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3',
                type: 'tiered-subchild-node',
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->3->branch',
                    parentNodeId: 'branch-btf4ui9d2y->children->1',
                    testablePartialId: 'testable-partial-e2RChAwCU'
                },
                position: {
                    x: 329.8125,
                    y: 282
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'branch-btf4ui9d2y->children->1->subchildren->2.step-anchor',
                    targetNodeId: 'branch-btf4ui9d2y->children->1->subchildren->3',
                    type: 'tier-row',
                    label: 'C',
                    direction: 'horizontal',
                    y: 'middle'
                },
                position: {
                    x: 293.8125,
                    y: 293
                }
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3->branch',
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: true,
                    sourceNodeId: 'branch-btf4ui9d2y->children->1->subchildren->3'
                },
                position: {
                    x: 411.5625,
                    y: 285.5
                }
            }*/



            /*{
                id: '5572->testable',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root',
                    // THIS IS GIVEN TO EMPTY TESTABLE GROUPS WITH: (1) NO PARENTS (2) only 1 CHILD
                    isDefaultAND: true,
                },
                position: {x: 30, y: 50},
                className: ''
            },
            {
                id: '5572->branch',
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: false,
                    sourceNodeId: '5572->testable'
                } as SelectActionNodeData,
                //position: {x: 32, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            // first tree with a branch discount
            {
                id: '1-tree-with-discount-branch->testable',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root',
                    // THIS IS GIVEN TO EMPTY TESTABLE GROUPS WITH: (1) NO PARENTS (2) only 1 CHILD
                    isDefaultAND: true,
                },
                position: {x: 230, y: 50},
                className: ''
            },
            {
                id: '1-tree-with-discount-branch->branch',
                type: 'branch-offers',
                data: {
                    renderedNodeType: 'branch-offers',
                    isInsideBranch: false,
                    sourceNodeId: '1-tree-with-discount-branch->testable'
                } as OffersBranchData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },* /
            /** ------------------------------
             * second tree with a branch first passing node
             ---------------------------------------------* /
            {
                id: 'first-passing-nodes-example->testable',
                type: 'tree-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'root',
                    targetNodeId: 'first-passing-nodes-example->children->1.step-anchor',
                    // THIS IS GIVEN TO EMPTY TESTABLE GROUPS WITH: (1) NO PARENTS (2) only 1 CHILD
                    isDefaultAND: true,
                } as WithTargetNodeId,
                position: {x: 230, y: 50},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->1.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: true,
                    sourceNodeId: 'first-passing-nodes-example->testable',
                    targetNodeId: 'first-passing-nodes-example->children->1'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->1',
                type: 'branch-first-passing-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'first-passing-nodes-example->children->1->branch',
                    // THIS IS GIVEN TO EMPTY TESTABLE GROUPS WITH: (1) NO PARENTS (2) only 1 CHILD
                    isDefaultAND: true,
                } as WithTargetNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->1->branch',
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: true,
                    sourceNodeId: 'first-passing-nodes-example->children->1'
                } as SelectActionNodeData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->2',
                type: 'branch-first-passing-node',
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'first-passing-nodes-example->children->2->branch'
                },
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->2.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'first-passing-nodes-example->children->1.step-anchor',
                    targetNodeId: 'first-passing-nodes-example->children->2'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->2->branch',
                type: 'branch-offers',
                data: {
                    renderedNodeType: 'branch-offers',
                    isInsideBranch: true,
                    sourceNodeId: 'first-passing-nodes-example->children->2'
                } as OffersBranchData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            //ok so, in this case, the child IS a branch, a first-passing-node branch
            // so this one node right here would be the testable for this branch
            {
                id: 'first-passing-nodes-example->children->3',
                type: 'branch-first-passing-node',
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'first-passing-nodes-example->children->3->branch->children->1',
                    sourceAnchor: {
                        id: 'bottom',
                        position: Position.Bottom
                    } as Anchor
                },
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->3.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'first-passing-nodes-example->children->2.step-anchor',
                    targetNodeId: 'first-passing-nodes-example->children->3',
                    nodeHasMultiNodeBranch: true
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            /**
             * NESTED FIRST PASSING NODE BRANCH!
             *
            * /
                {
                    id: 'first-passing-nodes-example->children->3->branch->children->1.step-anchor',
                    type: 'step-anchor',
                    data: {
                        renderedNodeType: 'step-anchor',
                        isFirst: true,
                        sourceNodeId: 'first-passing-nodes-example->children->3',
                        targetNodeId: 'first-passing-nodes-example->children->3->branch->children->1'
                    } as StepAnchorData,
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'first-passing-nodes-example->children->3->branch->children->1',
                    type: 'branch-first-passing-node',
                    data: {
                        renderedNodeType: 'branch-first-passing-node',
                        targetNodeId: 'first-passing-nodes-example->children->3->branch->children->1->branch'
                    },
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'first-passing-nodes-example->children->3->branch->children->1->branch',
                    type: 'select-action-branch',
                    data: {
                        renderedNodeType: 'action',
                        isInsideBranch: true,
                        sourceNodeId: 'first-passing-nodes-example->children->3->branch->children->1'
                    } as SelectActionNodeData,
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                // second nested tier
                {
                    id: 'first-passing-nodes-example->children->3->branch->children->2.step-anchor',
                    type: 'step-anchor',
                    data: {
                        renderedNodeType: 'step-anchor',
                        isFirst: false,
                        sourceNodeId: 'first-passing-nodes-example->children->3->branch->children->1.step-anchor',
                        targetNodeId: 'first-passing-nodes-example->children->3->branch->children->2'
                    } as StepAnchorData,
                    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'first-passing-nodes-example->children->3->branch->children->2',
                    type: 'branch-first-passing-node',
                    data: {
                        renderedNodeType: 'branch-first-passing-node',
                        targetNodeId: 'first-passing-nodes-example->children->3->branch->children->2->branch'
                    },
                    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'first-passing-nodes-example->children->3->branch->children->2->branch',
                    type: 'branch-offers',
                    data: {
                        renderedNodeType: 'action',
                        isInsideBranch: true,
                        sourceNodeId: 'first-passing-nodes-example->children->3->branch->children->2'
                    } as SelectActionNodeData,
                    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
            //nesting ends
            {
                id: 'first-passing-nodes-example->children->4.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'first-passing-nodes-example->children->3.step-anchor',
                    targetNodeId: 'first-passing-nodes-example->children->4'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->4',
                type: 'branch-first-passing-node',
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'first-passing-nodes-example->children->4->branch'
                },
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'first-passing-nodes-example->children->4->branch',
                type: 'branch-offers',
                data: {
                    renderedNodeType: 'branch-offers',
                    isInsideBranch: true,
                    sourceNodeId: 'first-passing-nodes-example->children->4'
                } as OffersBranchData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            //finally the add button
            {
                id: 'first-passing-nodes-example->children->buttons.add',
                type: 'branch-add-node-button',
                data: {
                    renderedNodeType: 'branch-add-node-button',
                    lastAnchor: 'first-passing-nodes-example->children->4.step-anchor'
                },
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },*/
            /** -----------------------
             *
             * Third tree with a branch (tiered)
             *
             ------------------------*/
            /*{
                id: 'tiered-example->testable',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root'
                },
                position: {x: 230, y: 50},
                className: ''
            },
            {
                id: 'tiered-example->children->1.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: true,
                    sourceNodeId: 'tiered-example->testable',
                    targetNodeId: 'tiered-example->children->1',
                    type: 'tiered-base',
                    xSpacing: 8 * 4
                } as StepAnchorData & WithXSpacing,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1',
                type: 'tiered-base-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    sourceNodeId: 'tiered-example->testable',
                    targetNodeId: 'tiered-example->children->1->subchildren->1.step-anchor',
                    testableId: 'tiered-example',
                } as WithTargetNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->1.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: true,
                    sourceNodeId: 'tiered-example->children->1',
                    targetNodeId: 'tiered-example->children->1->subchildren->1',
                    direction: 'horizontal',
                    type: 'tier-row',
                    y: 'middle',
                    label: 'a'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->1->branch',
                type: 'branch-offers',
                data: {
                    renderedNodeType: 'branch-offers',
                    isInsideBranch: true,
                    sourceNodeId: 'tiered-example->children->1->subchildren->1',
                    xSpacing: 18 * 4 // This is going to be calculated based on the width of the 'pass items' label IF the source node is a testable
                } as OffersBranchData & WithXSpacing,
                //                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->1',
                type: 'tiered-subchild-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'tiered-example->children->1->subchildren->1->branch',
                    parentNodeId: 'tiered-example->children->1'
                } as WithTargetNodeId & WithParentNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            // second tier
            {
                id: 'tiered-example->children->1->subchildren->2.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'tiered-example->children->1->subchildren->1.step-anchor',
                    targetNodeId: 'tiered-example->children->1->subchildren->2',
                    direction: 'horizontal',
                    y: 'middle'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->2->branch',
                type: 'branch-offers',
                data: {
                    renderedNodeType: 'branch-offers',
                    isInsideBranch: true,
                    sourceNodeId: 'tiered-example->children->1->subchildren->2'
                } as OffersBranchData,
                //                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->2',
                type: 'tiered-subchild-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'tiered-example->children->1->subchildren->2->branch',
                    parentNodeId: 'tiered-example->children->1'
                } as WithTargetNodeId & WithParentNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            // third tier

            {
                id: 'tiered-example->children->1->subchildren->3.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'tiered-example->children->1->subchildren->2.step-anchor',
                    targetNodeId: 'tiered-example->children->1->subchildren->3',
                    direction: 'horizontal',
                    y: 'middle'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->3',
                type: 'tiered-subchild-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'tiered-example->children->1->subchildren->3->children->1.step-anchor',
                    parentNodeId: 'tiered-example->children->1',
                    sourceAnchor: {
                        id: 'bottom',
                        position: Position.Bottom
                    } as Anchor
                } as WithTargetNodeId & WithParentNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            / **
             * NESTING STARTS HERE
             * /
                {
                    id: 'tiered-example->children->1->subchildren->3->children->1.step-anchor',
                    type: 'step-anchor',
                    data: {
                        renderedNodeType: 'step-anchor',
                        isFirst: true,
                        type: 'tiered-base',
                        sourceNodeId: 'tiered-example->children->1->subchildren->3',
                        targetNodeId: 'tiered-example->children->1->subchildren->3->children->1',
                        xSpacing: 8 * 4
                    } as StepAnchorData & WithXSpacing,
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'tiered-example->children->1->subchildren->3->children->1',
                    type: 'tiered-base-node',
                    // @ts-ignore
                    data: {
                        renderedNodeType: 'branch-first-passing-node',
                        targetNodeId: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1.step-anchor'
                    } as WithTargetNodeId,
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1.step-anchor',
                    type: 'step-anchor',
                    data: {
                        renderedNodeType: 'step-anchor',
                        isFirst: true,
                        sourceNodeId: 'tiered-example->children->1->subchildren->3->children->1',
                        targetNodeId: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                        direction: 'horizontal',
                        y: 'middle'
                    } as StepAnchorData,
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1->branch',
                    type: 'branch-offers',
                    data: {
                        renderedNodeType: 'branch-offers',
                        isInsideBranch: true,
                        sourceNodeId: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1'
                    } as OffersBranchData,
                    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
                {
                    id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                    type: 'tiered-subchild-node',
                    // @ts-ignore
                    data: {
                        renderedNodeType: 'branch-first-passing-node',
                        targetNodeId: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1->branch',
                        parentNodeId: 'tiered-example->children->1->subchildren->3->children->1'
                    } as WithTargetNodeId & WithParentNodeId,
    //                position: {x: 240, y: 290},
                    position: {x: 0, y: 0},
                    className: ''
                },
            // fourth tier
            {
                id: 'tiered-example->children->1->subchildren->4.step-anchor',
                type: 'step-anchor',
                data: {
                    renderedNodeType: 'step-anchor',
                    isFirst: false,
                    sourceNodeId: 'tiered-example->children->1->subchildren->3.step-anchor',
                    targetNodeId: 'tiered-example->children->1->subchildren->4',
                    direction: 'horizontal',
                    y: 'middle'
                } as StepAnchorData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->4->branch',
                type: 'branch-offers',
                data: {
                    renderedNodeType: 'branch-offers',
                    isInsideBranch: true,
                    sourceNodeId: 'tiered-example->children->1->subchildren->4'
                } as OffersBranchData,
                //                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->4',
                type: 'tiered-subchild-node',
                // @ts-ignore
                data: {
                    renderedNodeType: 'branch-first-passing-node',
                    targetNodeId: 'tiered-example->children->1->subchildren->4->branch',
                    parentNodeId: 'tiered-example->children->1'
                } as WithTargetNodeId & WithParentNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },
            {
                id: 'tiered-example->children->1->subchildren->buttons.add',
                type: 'branch-add-node-button',
                data: {
                    renderedNodeType: 'branch-add-node-button',
                    parentNodeId: 'tiered-example->children->1',
                    lastAnchor: 'tiered-example->children->1->subchildren->4.step-anchor'
                } & WithParentNodeId,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            }*/


            /*
                NOW WE JUST NEED THEY ACTUAL BRANCH!
            ,
            {
                id: 'first-passing-nodes-example->children->1->branch',
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: true,
                    sourceNodeId: 'first-passing-nodes-example->children->1'
                } as SelectActionNodeData,
//                position: {x: 240, y: 290},
                position: {x: 0, y: 0},
                className: ''
            },*/
            /*{
                id: '6572',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root'
                },
                position: {x: 460, y: 50},
                className: ''
            },
            {
                id: '7572',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root'
                },
                position: {x: 780, y: 50},
                className: ''
            },
            {
                id: '1000',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root'
                },
                position: {x: 880, y: 50},
                className: ''
            },
            {
                id: '2000',
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root'
                },
                position: {x: 1280, y: 50},
                className: ''
            },*/
        ],
        nodes: [
            /**
             * equals to:
             *   {
             *       testable: '5572->testable',
             *       branch:'5572->branch'
             *   }
             */
            /*'5572',
            '1-tree-with-discount-branch',
            'first-passing-nodes-example',
            'first-passing-nodes-example->children->1',
            'first-passing-nodes-example->children->2',
            'first-passing-nodes-example->children->3',
            'first-passing-nodes-example->children->3->branch->children->1',
            'first-passing-nodes-example->children->3->branch->children->2',
            'tiered-example',*/
        ],
        /**
         * These are NOT React Flow nodes, these are OUR Coupons+ nodes
         * these nodes have a
         *      -testable
         *          and
         *      -branch
         */
        couponsPlusNodeTypes: [
            /*{
                id: 'group-0CY0L995NF->testable',
                branchType: 'tiered'
            },
            {
                id: 'group-tle73Bex15',
                branchType: 'select-action'
            },
            {
                id: 'group-tle73Bex15->testable',
                branchType: 'tiered'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->1',
                branchType: 'select-action'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2',
                branchType: 'select-action'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3',
                branchType: 'select-action'
            }*/    /**
             * THE testable will be suffized with ->testable
             * THE branch will be suffized with ->branch
             *
             * eg: 5572->testable
             * and 5572->branch
             */
            /*{
                id: '5572',
                branchType: 'select-action',

            },
            {
                id: '1-tree-with-discount-branch',
                branchType: 'offers',
            },
            {
                id: 'first-passing-nodes-example',
                branchType: 'first-passing-node',
            },
            {
                id: 'first-passing-nodes-example->children->1',
                branchType: 'select-action',
            },
            {
                id: 'first-passing-nodes-example->children->2',
                branchType: 'offers',
            },
            {
                id: 'first-passing-nodes-example->children->3',
                branchType: 'first-passing-node',
            },
            {
                id: 'first-passing-nodes-example->children->4',
                branchType: 'offers',
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1',
                branchType: 'select-action',
            },
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2',
                branchType: 'offers',
            },*/
            /**
             * Tiered
             * tiered-example->children->1->subchildren->1->branch
             */
            /*{
                id: 'tiered-example',
                branchType: 'tiered',
            },
            {
                id: 'tiered-example->children->1->subchildren->1',
                branchType: 'offers',
            },
            {
                id: 'tiered-example->children->1->subchildren->2',
                branchType: 'offers',
            },
            {
                id: 'tiered-example->children->1->subchildren->3',
                branchType: 'tiered',
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                branchType: 'offers',
            },
            {
                id: 'tiered-example->children->1->subchildren->4',
                branchType: 'offers',
            },*/
        ],
        branchRelations: [
            /*{
                branch: 'branch-wOFK0xktHN->children->1->subchildren->1',
                children: [
                    'branch-wOFK0xktHN->children->1->subchildren->1->children->1'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'branch-wOFK0xktHN->children->1->subchildren->1->children->1->subchildren->1',
                children: [
                    'branch-wOFK0xktHN->children->1->subchildren->1->children->1->subchildren->1->branch'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'group-tle73Bex15->testable',
                children: [
                    'branch-btf4ui9d2y->children->1'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'branch-btf4ui9d2y->children->1',
                children: [
                    'branch-btf4ui9d2y->children->1->subchildren->1',
                    'branch-btf4ui9d2y->children->1->subchildren->2',
                    'branch-btf4ui9d2y->children->1->subchildren->3'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'branch-btf4ui9d2y->children->1->subchildren->1',
                children: [
                    'branch-btf4ui9d2y->children->1->subchildren->1->branch'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'branch-btf4ui9d2y->children->1->subchildren->2',
                children: [
                    'branch-btf4ui9d2y->children->1->subchildren->2->branch'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'branch-btf4ui9d2y->children->1->subchildren->3',
                children: [
                    'branch-btf4ui9d2y->children->1->subchildren->3->branch'
                ],
                childrenType: 'renderedNodes'
            }*/
            /*{
                branch: '5572',
                children: ['5572->branch'],
                childrenType: 'renderedNodes'
            },
            {
                branch: '1-tree-with-discount-branch->branch',
                children: ['1-tree-with-discount-branch->branch->offers->1'],
                childrenType: 'offers'
            },
            {
                branch: 'first-passing-nodes-example',
                children: [
                    'first-passing-nodes-example->children->1',
                    'first-passing-nodes-example->children->2',
                    'first-passing-nodes-example->children->3'
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'first-passing-nodes-example->children->3',
                children: [
                    'first-passing-nodes-example->children->3->branch->children->1',
                    'first-passing-nodes-example->children->3->branch->children->2'
                ],
                childrenType: 'renderedNodes'
            },

            {
                branch: 'tiered-example',
                children: [
                    'tiered-example->children->1->subchildren->1',
                    'tiered-example->children->1->subchildren->2',
                    'tiered-example->children->1->subchildren->3',
                    'tiered-example->children->1->subchildren->4',
                ],
                childrenType: 'renderedNodes'
            },
            {
                branch: 'tiered-example->children->1->subchildren->3',
                children: [
                    'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                ],
                childrenType: 'renderedNodes'
            },*/
        ],
        // so now let's js render the offers from the custom React flow Node!
        offers: [
            /*{
                id: 'offer-kigiyfi',
                type: 'Discount',
                options: {
                    discount: 10
                }
            }*/
        ],
        edges: [
            /*{
                id: 'group-5572',
                //sourceHandle: 'bottom',
                //targetHandle: 'top',
                source: 'group-5572',
                target: 'branch-9875',
                type: 'connecting-line',
            }, */

            /*{
                id: 'group-tle73Bex15->testable',
                source: 'group-tle73Bex15->testable',
                target: 'branch-btf4ui9d2y->children->1.step-anchor',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1',
                target: 'branch-btf4ui9d2y->children->1->subchildren->1.step-anchor',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1.step-anchor',
                target: 'branch-btf4ui9d2y->children->1',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1',
                target: 'branch-btf4ui9d2y->children->1->subchildren->1',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->1->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1->subchildren->1',
                target: 'branch-btf4ui9d2y->children->1->subchildren->1->branch',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->buttons.add',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'branch-btf4ui9d2y->children->1->subchildren->3.step-anchor',
                target: 'branch-btf4ui9d2y->children->1->subchildren->buttons.add',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1->subchildren->2.step-anchor',
                target: 'branch-btf4ui9d2y->children->1->subchildren->2',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'branch-btf4ui9d2y->children->1->subchildren->1.step-anchor',
                target: 'branch-btf4ui9d2y->children->1->subchildren->2.step-anchor',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->2->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1->subchildren->2',
                target: 'branch-btf4ui9d2y->children->1->subchildren->2->branch',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1->subchildren->3.step-anchor',
                target: 'branch-btf4ui9d2y->children->1->subchildren->3',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'branch-btf4ui9d2y->children->1->subchildren->2.step-anchor',
                target: 'branch-btf4ui9d2y->children->1->subchildren->3.step-anchor',
                type: 'connecting-line'
            },
            {
                id: 'branch-btf4ui9d2y->children->1->subchildren->3->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'branch-btf4ui9d2y->children->1->subchildren->3',
                target: 'branch-btf4ui9d2y->children->1->subchildren->3->branch',
                type: 'connecting-line'
            }*/
            /*{
                id: '5572',
                source: '5572->testable',
                target: '5572->branch',
                type: 'connecting-line',
            },
            {
                id: '1-tree-with-discount-branch',
                source: '1-tree-with-discount-branch->testable',
                target: '1-tree-with-discount-branch->branch',
                type: 'connecting-line',
            },
            {
                id: 'first-passing-nodes-example',
                source: 'first-passing-nodes-example->testable',
                target: 'first-passing-nodes-example->children->1.step-anchor',
                type: 'connecting-line',
            },
            // now connect the first anchor to the first node
            {
                id: 'first-passing-nodes-example->children->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->1.step-anchor',
                target: 'first-passing-nodes-example->children->1',
                type: 'connecting-line',
            },
            // now let's connect the first node to its branch
            {
                id: 'first-passing-nodes-example->children->1->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->1',
                target: 'first-passing-nodes-example->children->1->branch',
                type: 'connecting-line',
            },
            // connect the first anchor to the second anchor
            {
                id: 'first-passing-nodes-example->children->2.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'first-passing-nodes-example->children->1.step-anchor',
                target: 'first-passing-nodes-example->children->2.step-anchor',
                type: 'connecting-line',
            },
            //connect the second anchor to the second node
            {
                id: 'first-passing-nodes-example->children->2',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->2.step-anchor',
                target: 'first-passing-nodes-example->children->2',
                type: 'connecting-line',
            },
            // now let's connect the second node to its branch
            {
                id: 'first-passing-nodes-example->children->2->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->2',
                target: 'first-passing-nodes-example->children->2->branch',
                type: 'connecting-line',
            },
            // connect the second anchor to the third anchor
            {
                id: 'first-passing-nodes-example->children->3.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'first-passing-nodes-example->children->2.step-anchor',
                target: 'first-passing-nodes-example->children->3.step-anchor',
                type: 'connecting-line',
            },
            //connect the third anchor to the third node
            {
                id: 'first-passing-nodes-example->children->3',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->3.step-anchor',
                target: 'first-passing-nodes-example->children->3',
                type: 'connecting-line',
            },

            //first-passing-nodes-example->children->3->branch->children->1.step-anchor
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1',
                source: 'first-passing-nodes-example->children->3',
                target: 'first-passing-nodes-example->children->3->branch->children->1.step-anchor',
                type: 'connecting-line',
            },
            // now connect the anchor to the node
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->3->branch->children->1.step-anchor',
                target: 'first-passing-nodes-example->children->3->branch->children->1',
                type: 'connecting-line',
            },
            // now let's connect the node to its branch
            {
                id: 'first-passing-nodes-example->children->3->branch->children->1->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->3->branch->children->1',
                target: 'first-passing-nodes-example->children->3->branch->children->1->branch',
                type: 'connecting-line',
            },
            // second tier
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'first-passing-nodes-example->children->3->branch->children->1.step-anchor',
                target: 'first-passing-nodes-example->children->3->branch->children->2.step-anchor',
                type: 'connecting-line',
            },
            // now connect the anchor to the node
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->3->branch->children->2.step-anchor',
                target: 'first-passing-nodes-example->children->3->branch->children->2',
                type: 'connecting-line',
            },
            // now let's connect the node to its branch
            {
                id: 'first-passing-nodes-example->children->3->branch->children->2->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->3->branch->children->2',
                target: 'first-passing-nodes-example->children->3->branch->children->2->branch',
                type: 'connecting-line',
            },

            // nesting ends
            // connect the third anchor to the fourth anchor
            {
                id: 'first-passing-nodes-example->children->4.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'first-passing-nodes-example->children->3.step-anchor',
                target: 'first-passing-nodes-example->children->4.step-anchor',
                type: 'connecting-line',
            },
            //connect the fourth anchor to the fourth node
            {
                id: 'first-passing-nodes-example->children->4',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->4.step-anchor',
                target: 'first-passing-nodes-example->children->4',
                type: 'connecting-line',
            },
            // now let's connect the fourth node to its branch
            {
                id: 'first-passing-nodes-example->children->4->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'first-passing-nodes-example->children->4',
                target: 'first-passing-nodes-example->children->4->branch',
                type: 'connecting-line',
            },
            //let's connect the last anchor to the add node button
            {
                id: 'first-passing-nodes-example->children->4.buttons.add',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'first-passing-nodes-example->children->3.step-anchor',
                target: 'first-passing-nodes-example->children->buttons.add',
                type: 'connecting-line',
            },*/
            /**
             * Tiered
             */
            //tiered-example->children->1->subchildren->1.step-anchor
            /*{
                id: 'tiered-example',
                source: 'tiered-example->testable',
                target: 'tiered-example->children->1.step-anchor',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1.step-anchor',
                target: 'tiered-example->children->1',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1',
                target: 'tiered-example->children->1->subchildren->1.step-anchor',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->1.step-anchor',
                target: 'tiered-example->children->1->subchildren->1',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->1->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->1',
                target: 'tiered-example->children->1->subchildren->1->branch',
                type: 'connecting-line',
            }


            {
                id: 'tiered-example->children->1->subchildren->2.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'tiered-example->children->1->subchildren->1.step-anchor',
                target: 'tiered-example->children->1->subchildren->2.step-anchor',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->2',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->2.step-anchor',
                target: 'tiered-example->children->1->subchildren->2',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->2->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->2',
                target: 'tiered-example->children->1->subchildren->2->branch',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3.step-anchor',
                targetHandle: 'top',
                sourceHandle: 'bottom',
                source: 'tiered-example->children->1->subchildren->2.step-anchor',
                target: 'tiered-example->children->1->subchildren->3.step-anchor',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->3.step-anchor',
                target: 'tiered-example->children->1->subchildren->3',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'bottom',
                source: 'tiered-example->children->1->subchildren->3',
                target: 'tiered-example->children->1->subchildren->3->children->1.step-anchor',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->3->children->1.step-anchor',
                target: 'tiered-example->children->1->subchildren->3->children->1',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1.step-anchor',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->3->children->1',
                target: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1.step-anchor',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1.step-anchor',
                target: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                type: 'connecting-line',
            },
            {
                id: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1->branch',
                targetHandle: 'left',
                sourceHandle: 'right',
                source: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1',
                target: 'tiered-example->children->1->subchildren->3->children->1->subchildren->1->branch',
                type: 'connecting-line',
            },
            */
        ],
        autoApply: false,
        toggleAutoApply: () => {
            set(state => ({autoApply: !state.autoApply}))
        },
        setRenderedNodes: (renderedNodes) => { // this property is NOT unused!
            set({renderedNodes})
        },
        /**
         * New
         */
        write: (modifier) => {
            set(produce((state: NodesStore) => {
                modifier(state)
            }))
        },
        updateGrove: (modifier) => {
            set(produce((state: NodesStore) => {
                const grove = Grove.fromState(state)

                modifier(grove)
            }))
        },
        getGroveNode: id => {
            const grove = Grove.fromState(get())

            return grove.get(id)
        },
        importFromSource(source, reset,  then) {
            set(produce((state: NodesStore) => {
                if (reset) {
                    state.grove = []
                    state.renderedNodes = []
                    state.nodes = []
                    state.edges = []
                }

                const appImporter = new AppImporter(
                    state,
                    new GroveActions(state),
                    new Testables(state),
                    new TreeNodeFactory(new Testables(state), new Offers(state))
                )

                appImporter.importFromJSON(source)
                then?.()
            }))
        },
        /**
         * Tree Nodes
         */
        addTreeNode: (treeNode, options) => {
            set(produce((state: NodesStore) => {
                const groveActions = new GroveActions(state)

                groveActions.addTreeNode(treeNode, options)
            }))
        },
        /**
         * Offers
         */
        getOffer: (offerID: string): OfferData | undefined => {
            const offers = new Offers(get())

            return offers.get(offerID)
        },
        addBranchOffer: (offer, branchId) => {
            set(produce((state: NodesStore) => {
                const groveActions = new GroveActions(state)

                groveActions.addBranchOffer(offer, branchId)
            }))
        },
        updateOffer: (offer: OfferData) => {
            set(produce((state: NodesStore) => {
                const offers = new Offers(state)

                offers.update(offer)
            }))
        },
        removeOffer: (offerID: string, branchId: string) => {
            set(produce((state: NodesStore) => {
                const groveActions = new GroveActions(state)

                groveActions.removeBranchOffer(offerID, branchId)
            }))
        },
        /**
         * Tiers
         */
        cloneTier(targetTreeNodeId: string) {
            set(produce((state: NodesStore) => {
                const groveActions = new GroveActions(state)

                groveActions.cloneTier(targetTreeNodeId)
            }))
        },
        removeTier(treeNodeId) {
            set(produce((state: NodesStore) => {
                const groveActions = new GroveActions(state)

                groveActions.removeTier(treeNodeId)
            }))
        },
        removeTieredBranch(branchId) {
            set(produce((state: NodesStore) => {
                const groveActions = new GroveActions(state)

                groveActions.removeTieredBranch(branchId)
            }))
        },


        /**
         * Old
         */
        addOffers: (offers, branchId) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)
                const tree = new Tree(state, testables)

                tree.addOffers(offers, branchId)
            }))
        },
        createTierBranch: (options) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)
                const tree = new Tree(state, testables)

                tree.createTieredBranch(options)
            }))
        },
        /*cloneTier: (baseTestableId) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)
                const tree = new Tree(state, testables)

                tree.cloneTier(baseTestableId)
            }))

        },*/
        removeRenderedNode: (id: string) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)
                const tree = new Tree(state, testables)

                tree.removeRenderedNode(id)
            }))
        },
        updateTree: (modifier: (tree: Tree, testables: Testables) => void) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)
                const tree = new Tree(state, testables)

                modifier(tree, testables)
            }))
        },
        getTestable: (testableId) => {
            return new Testable(new Testables(get()), testableId)
        },
        addTestable: (testableData: NestedTestableNodeData, then) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)
                const createdId = testables.addTestables([testableData], undefined, false)[0] as string | undefined

                if (createdId) {
                    let rootNode = testables.getRootNode(createdId);

                    then(rootNode?.id, rootNode)
                }
            }))
        },
        addTestables: (args, then) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)

                let addedTestables = testables.addTestables(...args);

                then?.(addedTestables, testables, state)
            }))
        },
        updateTestablePartial: (args, then) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)

                let addedTestables = testables.updatePartial(...args);

                then?.(addedTestables, testables)
            }))
        },
        updateTestable: (args, then) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)

                let addedTestables = testables.updateTestable(...args);

                then?.(addedTestables, testables)
            }))
        },
        wrapAllContexts: (args, then) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)

                const result = testables.wrapAllContexts(...args)

                then?.(result, testables)
            }))
        },
        changeTestableGroupOptions: (...args) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)

                testables.changeTestableGroupOptions(...args)
            }))
        },
        getReadOnlyTestables: () => new Testables(get()),
        /**
         * Doesn't work! probably because of the proxy
         */
        updateTestables: (modifier: (testables: Testables) => void) => {
            set(produce((state: NodesStore) => {
                const testables = new Testables(state)

                modifier(testables)
            }))
        },
        removeTestable: (id: string) => {
            set(produce((store: NodesStore) => {
                // todo: write several tests for this function
                // case 1 : removes a testable from a context that has twon testables (1 testable will be removed)
                // case 2 : removes a testable from a context that has one testable and one group (the context will be removed and so the parent, an event will be triggered)
                // case 3 : removes a testable from a context that has one testable and a sibling (the parent group has 2 contexts) (the context will be removed but not the parent since it has another,)
                // case 4: removes a context with 2 testables and no siblings (the context will be removed and so will the parent group)
                // case 5: removes a context with 2 testables and a sibling (the context will be removed but not the parent since the parent has anther sibling,)

                const testables = new Testables(store);
                const isRoot = !testables.hasParent(id)
                const grove = Grove.fromState(store)

                testables.addSubscriber(TestableEvent.RemovedRoot, grove.afterRemovedRootTestableGroup.bind(grove))

                /**
                 * If the parent is empty, it will be removed, and so its parent if its empty too
                 * in which case, if this was a group with one context and one testable, the group will be removed
                 * so we need to remove the tree node
                 * for that, we will subscribe to this and remove the tree node when the root has been removed
                 */
                testables.remove(id)
            }))
        },
        /*addNode : () => set(state => ({
            nodes: [
                ...state.nodes,
                {
                  id: '1|'+Math.random(),
                  type: 'node',
                  data: { label: 'Any Products', description: 'My awesome desc!' },
                  position: { x: 0, y: (state.nodes.length || 1) * 50 },
                  className: 'border-2 rounded-lg'
                }
            ]
        })),*/
    })));
export const getNode = (store: NodesStore, id: TestableCompositeData['id'], where: keyof NodesStore = 'testables') => (store[where] as any[]).find(node => node.id === id)
export const findNode = (id: string, where: keyof NodesStore = 'testables') => store => getNode(store, id, where)
export const findTestable = <Options = {}>(id: string) => state => state.testables.find(testable => testable.id === id) as TestableData<Options> | TestableCompositeData

export const findDataForNodeWithoutChildren = id => store => (
    id ? store.testables.find(node => node.id === id) : undefined
)
const EMPTY_CHILDREN: readonly string[] = []
export const findDataForNode = id => store => ({
    data: store.testables.find(node => node.id === id),
    children: store.testableRelations.find(node => node.id === id)?.children || EMPTY_CHILDREN
})

type TestablesToAddReturnType = {
    parentGroup: TestableCompositeData,
    parentContext: TestableCompositeData,
    testablesToAdd: TestableData[]
}
export const convertTestableData = (testables: ComponentRuntimeDataWithParentType[]) => {
    return testables.map((testableData, index) => ({
        id: generateIdForType(getIdTypeForTestable(testableData.type)),
        ...testableData,
        'testableType': testableData.parentType.replace('s', '') as TestableData['testableType'], // singular filters -> filter
    }));
}

function getTestablesToAdd(testables: ComponentRuntimeDataWithParentType[], {
    targetType,
    targetId,
    ...contextData
}: TreeContextData, state: NodesStore): TestablesToAddReturnType {
    if (!testables) {
        return {
            parentGroup: {} as TestableCompositeData,
            parentContext: {} as TestableCompositeData,
            testablesToAdd: []
        }
    }
    const testablesManager = new Testables(state)
    const tree = new Tree(state, testablesManager)

    const testablesToAdd: NodeData[] = []
    const addTestables = (parentContextId: string) => {
        const testableData: TestableData[] = convertTestableData(testables)

        testablesToAdd.push(...testableData)
    }

    let parentGroup: TestableCompositeData
    let parentContext: TestableCompositeData

    let parentContextId: string | undefined

    if (targetType === 'root') {
        // js use the target data to create a default tree node and add it to the grove
        const grove = Grove.fromState(state)

        const treeNodeFactory = new TreeNodeFactory(
            new Testables(state),
            new Offers(state)
        )

        treeNodeFactory.setGrove(grove)

        const treeNode = treeNodeFactory.createFromNestedData({
            testable: wrapTestablesInDefaultGroup(
                convertTestableData(testables)
            ),
            branch: {
                type: 'select-action',
                children: []
            }
        })!

        grove.addTreeNode(treeNode)
        /*const convertedTestablesToAdd = convertTestableData(testables);

        testablesManager.addTestables(convertedTestablesToAdd)
        // now we have to add the rendered nodes!
        tree.createRootTree(testablesManager.getRootNode(convertedTestablesToAdd[0].id).id)*/
    } else if (targetType === 'testableComposite') {
        // is this a context or a testableComposite (group)?
        if (testablesManager.isContext(targetId as string)) {
            // here we have to create a parent group if the context is not a default AND (is an AND and only has 1 context)
            const parentTestableGroup = testablesManager.getParent(targetId as string)!;
            let parentGroupToUse: TestableCompositeData

            if (testablesManager.isDefaultGroup(parentTestableGroup.id)) {
                testablesManager.addTestables(convertTestableData(testables), parentTestableGroup.id)
                parentGroupToUse = parentTestableGroup as TestableCompositeData
            } else {
                testablesManager.wrapAllContexts(parentTestableGroup.id)
                // after the warp, the parent of the target context will be a new group (that has been placed inside the parent group)
                const newParentGroup = testablesManager.getParent(targetId as string);

                testablesManager.addTestables(convertTestableData(testables), newParentGroup!.id)
                parentGroupToUse = newParentGroup as TestableCompositeData
            }

            testablesManager.changeTestableGroupOptions(parentGroupToUse!.id, {
                // @ts-ignore
                type: contextData.groupType,
            })


        } else {
            // this is a testable composite am i right?
            testablesManager.addTestables(convertTestableData(testables), targetId as string)
        }

    }
    // make sure to add the parent group and context if it they don't exist already
    /*if (parentContext) {
        state.testableRelations.push({
            id: parentContext.id,
            children: testablesToAdd.map(testable => testable.id)
        })
    }*/

    return {
        // @ts-ignore
        parentGroup,
        // @ts-ignore
        parentContext,
        testablesToAdd
    }
    // this ain't no root so let's get the parent group instead
//    return findTestable<TestableCompositeData>(targetId as string)(state) as TestableCompositeData
}

function setTestableRelations(testablesData: TestablesToAddReturnType, {
    targetType,
    targetId
}: TreeContextData, state: NodesStore) {
    const {parentGroup, parentContext, testablesToAdd} = testablesData
    const parentGroupWithChildren = state.testableRelations.find(({id}) => id === parentGroup.id)!
    // add the parent group only if it doesn't exist already
    if (!parentGroupWithChildren) {
        state.testableRelations.push({
            id: parentGroup.id,
            children: [parentContext.id]
        })
    } else {
        // it exists so let's add the parent context to it?
        parentGroupWithChildren.children.push(parentContext.id)
    }

    // parent context
    state.testableRelations.push({
        id: parentContext.id,
        children: testablesToAdd.map(testable => testable.id)
    })

    return;
    //let parentContext: NodeData
    // parent group
    const _parentGroup = testablesToAdd[0]

    if (_parentGroup.type && _parentGroup.type !== 'context') {
        // we have a parent group and a context
        parentContext = testablesToAdd[1]

        state.testableRelations.push({
            id: _parentGroup.id,
            children: [
                parentContext.id
            ]
        })

    } else {
        // only modify the parent group, add the new context to it
        // so find the parent group from the EXISTING RELLATIONS using targetid!
        // bc the targetid IS the context id
        const parentGroup = state.testableRelations.find(({children}) => children.includes(targetId as string))!

        parentContext = testablesToAdd[0];

        parentGroup.children.push(parentContext.id)
    }

    const testables: NodeData[] = testablesToAdd.filter((testable, index) => {
        if (testable.type === 'context') {
            // 0 and 1 are the parent group and the context respectively
            if ([0, 1].includes(index)) {
                return false
            }
        } else {
            // 0 is the context
            if (index === 0) {
                return false
            }
        }

        return true;
    })

    // parent context
    state.testableRelations.push({
        id: parentContext.id,
        children: testables.map(testable => testable.id)
    })
}

function setRenderedNodes(testablesToAdd: NodeData[], {targetType, targetId}: TreeContextData, state: NodesStore) {
    if (targetType === 'root') {
        const parentGroup = testablesToAdd[0]
        state.renderedNodes.push(
            {
                id: `${parentGroup.id}->testable`,
                type: 'tree-node',
                data: {
                    renderedNodeType: 'root',
                    testableId: parentGroup.id,
                    isDefaultAND: true,// THIS IS GIVEN TO EMPTY TESTABLE GROUPS WITH: (1) NO PARENTS (2) only 1 CHILD
                },
                position: {x: 0, y: 0},
            },
        )

        state.renderedNodes.push({
                id: `${parentGroup.id}->branch`,
                type: 'select-action-branch',
                data: {
                    renderedNodeType: 'action',
                    isInsideBranch: false,
                    sourceNodeId: `${parentGroup.id}->testable`
                } as SelectActionNodeData,
                position: {x: 0, y: 0},
                className: ''
            }
        )
    } else if (targetType === 'testableComposite') {
        // i don't think we need to add rendered nodes, actually
    }
}

function setCouponsPlusNodeTypesToAdd(testablesToAdd: NodeData[], {
    targetType,
    targetId
}: TreeContextData, state: NodesStore) {
    if (targetType === 'root') {
        const parentGroup = testablesToAdd[0]

        state.couponsPlusNodeTypes.push({
            id: `${parentGroup.id}`,
            branchType: 'select-action',
        })
    }
}

function setBranchRelations(testablesToAdd: NodeData[], {targetType, targetId}: TreeContextData, state: NodesStore) {
    if (targetType === 'root') {
        const parentGroup = testablesToAdd[0]

        state.branchRelations.push(
            {
                branch: `${parentGroup.id}`,
                children: [
                    `${parentGroup.id}->branch`
                ],
                childrenType: 'renderedNodes'
            }
        )
    }
}

function setEdges(testablesToAdd: NodeData[], {targetType, targetId}: TreeContextData, state: NodesStore) {
    if (targetType === 'root') {
        const parentGroup = testablesToAdd[0]

        state.edges.push({
            id: `${parentGroup.id}`,
            source: `${parentGroup.id}->testable`,
            target: `${parentGroup.id}->branch`,
            type: 'connecting-line',
        })
    }
}
