import * as React from 'react';
import {ColorScheme, ITreeNode, Tree, TreeUtil} from './../../index';

import {withInfo} from '@storybook/addon-info';
import {boolean, select, withKnobs} from '@storybook/addon-knobs';
import {storyLayout} from '../../index.stories';
import {useState} from 'react';

// eslint-disable-next-line no-restricted-syntax
export default {
    title: 'Tree',
    decorators: [withInfo, withKnobs, storyLayout]
};

const columns = [{
    displayName: '',
    name: 'displayName'
    // renderer: this.renderAttribute
}];

const initNodes: ITreeNode[] = [
    {
        key: 'ROOT',
        row: {displayName: 'ROOT'},
        expanded: true,
        children: [
            {
                key: '1',
                row: {displayName: '1'},
                expanded: true,
                children: null
            },
            {
                key: '2',
                row: {displayName: '2'},
                expanded: true,
                children: [{
                    key: '2.1',
                    row: {displayName: '2.1'},
                    expanded: true,
                    children: [{
                        key: '2.1.1',
                        row: {displayName: '2.1.1'},
                        expanded: true,
                        children: null
                    }, {
                        key: '2.1.2',
                        row: {displayName: '2.1.2'},
                        expanded: true,
                        children: [{
                            key: '2.1.2.1',
                            row: {displayName: '2.1.2.1'},
                            expanded: true,
                            children: null
                        }]
                    }]
                }]
            },
            {
                key: '3',
                row: {displayName: 'node 3 with long long long name'},
                expanded: true,
                children: null
            },
            {
                key: '4',
                row: {displayName: '4'},
                expanded: true,
                children: null
            }
        ]
    }
];

TreeUtil.initParents(initNodes[0], true);

export const simpleTree = () => {
    const [nodes, setNodes] = useState(initNodes);

    const findParent = (nodeKey: string, startNode: ITreeNode): ITreeNode | undefined => {
        if (!startNode.children) {
            return undefined;
        }

        if (startNode.children.findIndex((child) => child.key === nodeKey) > -1) {
            return startNode;
        }

        for (let i = 0; i < startNode.children.length; i++) {
            const parent = findParent(nodeKey, startNode.children[i]);

            if (parent) {
                return parent;
            }
        }

        return undefined;
    };

    const moveNode = (node: ITreeNode, newParent?: ITreeNode, newPrevious?: ITreeNode) => {
        // Find parent of moved node
        let oldParent: ITreeNode | undefined;

        for (let i = 0; i < initNodes.length; i++) {
            oldParent = findParent(node.key, initNodes[i]);

            if (oldParent !== undefined) {
                break;
            }
        }

        // Remove moved node from old parent
        if (oldParent && oldParent.children) {
            const movedNodeIdx = oldParent.children.findIndex((child) => child.key === node.key);

            if (movedNodeIdx !== -1) {
                oldParent.children.splice(movedNodeIdx, 1);
            }

            if (oldParent.children.length === 0) {
                oldParent.children = null;
            }
        } else {
            const movedNodeIdx = initNodes.findIndex((child) => child.key === node.key);

            if (movedNodeIdx !== -1) {
                initNodes.splice(movedNodeIdx, 1);
            }
        }

        // Add moved node as new child of newParent
        let newChildIndex: number = 0;

        if (newParent === undefined) {
            if (newPrevious !== undefined) {
                newChildIndex = initNodes.findIndex((child) => child.key === newPrevious.key) + 1;
            }
        } else {
            if (newParent.children) {
                if (newPrevious) {
                    newChildIndex = newParent.children.findIndex((child) => child.key === newPrevious.key) + 1;
                }
            } else {
                newParent.children = [];
            }
        }

        if (newParent) {
            newParent.children?.splice(newChildIndex, 0, node);
        } else {
            initNodes.splice(newChildIndex, 0, node);
        }

        // Set tree
        setNodes(initNodes);
    };

    const isDeletable = (node: ITreeNode) => {
        return node.children === null || node.children.length === 0;
    };

    return (
        <div style={{height: '400px', width: '200px'}}>
            <Tree
                nodes={nodes}
                columns={columns}
                onNodeSelect={() => null}
                selectedNodes={[]}
                isDeletable={isDeletable}
                isStriped={boolean('isStriped', false)}
                isDraggable={boolean('isDraggable', false)}
                onMoveNode={moveNode}
                colorScheme={select<ColorScheme>('colorScheme', Object.values(ColorScheme), ColorScheme.light)}
                actions={[
                    {
                        label: 'create',
                        action: (node) => {
                            node.children = node.children || [];

                            node.children.push({
                                key: `${node.key}.${node.children.length + 1}`,
                                row: {displayName: `${node.key}.${node.children.length + 1}`},
                                expanded: false,
                                children: null,
                                parent: node
                            });

                            setNodes((prevNodes) => {
                                return [...prevNodes];
                            });
                        }
                    }
                ]}
            />
        </div>
    );
};
