import React from 'react';
import PropTypes from 'prop-types';

export function keyboardSortableContext(Component) {
    return class KeyboardSortableContext extends React.Component<any, any> {
        static childContextTypes = {
            register: PropTypes.func.isRequired,
            unregister: PropTypes.func.isRequired,
            getPrevDropTarget: PropTypes.func.isRequired,
            getNextDropTarget: PropTypes.func.isRequired
        };
        constructor(props, context) {
            super(props, context);
            this.state = {
                items: {}
            };
        }
        getChildContext() {
            return {
                register: this.register,
                unregister: this.unregister,
                getPrevDropTarget: this.getPrevDropTarget,
                getNextDropTarget: this.getNextDropTarget
            };
        }
        unregister = index => {
            let {items} = this.state;
            if (items[index]) {
                delete items[index];
            }
        };
        register = (index, dndId) => {
            let {items} = this.state;
            items[index] = {
                dndId,
                index
            };
        };
        getPrevDropTarget = index => {
            const {items} = this.state;
            let firstIndex = Math.min.apply(null, Object.keys(items));
            if (index !== firstIndex) {
                for (let i = index - 1; i >= 0; i--) {
                    let target = items[i];
                    if (target) {
                        return target;
                    }
                }
            }
            return false;
        };
        getNextDropTarget = index => {
            const {items} = this.state;
            const lastIndex = Math.max.apply(null, Object.keys(items));
            if (index !== lastIndex) {
                for (let i = index + 1; i <= lastIndex; i++) {
                    let target = items[i];
                    if (target) {
                        return target;
                    }
                }
            }
            return false;
        };
        render() {
            return (
                <div role="select">
                    <Component {...this.props} />
                </div>
            );
        }
    };
}
