import React, { Component } from 'react';
import hocImmutable, { imShallowEqual } from '../../utils/HOC/hocImmutable';
import { DropTarget } from 'react-dnd';

let idx = 0;
export default hocImmutable(class extends Component {
    constructor(props) {
        super(props);
    }
    state = {
        Comp: null,
        children: null,
        props: {}
    }
    store = {
        isOver: false
    }
    componentWillMount() {
        const { acceptTypes = '', spec = {}, collect, options, render, children, ...props } = this.props;
        const Comp = DropTarget(acceptTypes, spec, (connect, monitor) => {
            return Object.assign((collect && collect(connect, monitor)) || {}, {
                connectDropTarget: connect.dropTarget(),
                item: monitor.getItem(),
                canDrop: monitor.canDrop(),
                isOver: monitor.isOver({ shallow: true })
            })
        }, options)(({ connectDropTarget, item, canDrop, isOver, children, wrapProps, ...dragProps }) => {
            let dropTarget = null;
            if (typeof render === 'function') {
                dropTarget = <div {...wrapProps}>{
                    connectDropTarget(render({
                        ...dragProps,
                        item,
                        canDrop,
                        isOver,
                        isDragIn: isOver && !this.store.isOver,
                        isDragOut: !isOver && this.store.isOver
                    }) || null)
                }</div>
            } else {
                if (typeof children === 'object') {
                    dropTarget = <div {...wrapProps}>{
                        connectDropTarget(<div>{React.cloneElement(children, {
                            ...dragProps,
                            item,
                            canDrop,
                            isOver,
                            isDragIn: isOver && !this.store.isOver,
                            isDragOut: !isOver && this.store.isOver
                        })}</div>)
                    } </div>
                } else {
                    dropTarget = null;
                }
            }
            this.store.isOver = isOver;
            return dropTarget
        })
        this.setState({ Comp, children, props });
    }
    componentWillReceiveProps(nextProps) {
        const { acceptTypes = '', spec = {}, collect, options, render, children, ...props } = nextProps;
        this.setState({ children, props })
    }
    render() {
        const { Comp, children, props } = this.state;
        if (Comp === null) {
            return null;
        } else {
            return <Comp children={children} wrapProps={props} />
        }
    }
});