import React, { Component, Children, cloneElement } from 'react';
import imShallowEqual from '../../utils/HOC/imShallowEqual';
import classnames from 'classnames';
import './FlexBox.less';

const FlexBox = class extends Component {
    constructor(props) {
        super(props);
    }
    static defaultProps = {
        'data-_-_flexBox-_-': true
    }
    store = {
        props: this.props
    }
    componentWillReceiveProps(nextProps) {
        this.store.props = nextProps;
    }
    shouldComponentUpdate(nextProps, nextState) {
        return !(imShallowEqual(this.props, nextProps) && imShallowEqual(this.state, nextState));
    }
    render() {
        const { prefixCls = 'ant', direction = 'row', style = {}, gutter = 0, className, span, order, grow, shrink, offset, wrap, justify, alignContent, align, alignSelf, children, ...props } = this.store.props;
        const sizeCls = [];
        if (props.basis !== undefined) {
            style.flexGrow = 0;
            style.flexBasis = props.basis;
            delete props.basis;
        }
        if (props.block) {
            style.display = 'block';
            delete props.block;
        }
        if (props.fullW) {
            style.width = '100%';
            delete props.fullW;
        }
        if (props.fullH) {
            style.height = '100%';
            delete props.fullH;
        }
        ['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => {
            const prop = props[size];
            if (prop !== undefined) {
                let sizeProps = {};
                if (typeof prop === 'number') {
                    sizeProps.span = prop;
                } else if (typeof prop === 'object') {
                    sizeProps = prop || {};
                }

                sizeCls.push({
                    [`${prefixCls}-flexbox-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
                    [`${prefixCls}-flexbox-${size}-order-${sizeProps.order}`]: sizeProps.order !== undefined,
                    [`${prefixCls}-flexbox-${size}-grow-${sizeProps.grow}`]: sizeProps.grow !== undefined,
                    [`${prefixCls}-flexbox-${size}-shrink-${sizeProps.shrink}`]: sizeProps.shrink !== undefined,
                    [`${prefixCls}-flexbox-${size}-offset-${sizeProps.offset}`]: sizeProps.offset !== undefined,
                    [`${prefixCls}-flexbox-${size}-wrap-${sizeProps.wrap}`]: sizeProps.wrap,
                    [`${prefixCls}-flexbox-${size}-justify-${sizeProps.justify}`]: sizeProps.justify,
                    [`${prefixCls}-flexbox-${size}-alignContent-${sizeProps.alignContent}`]: sizeProps.alignContent,
                    [`${prefixCls}-flexbox-${size}-align-${sizeProps.align}`]: sizeProps.align,
                    [`${prefixCls}-flexbox-${size}-alignSelf-${sizeProps.alignSelf}`]: sizeProps.alignSelf,
                });
            }
            delete props[size];
        });
        const cls = classnames(className, sizeCls, {
            [`${prefixCls}-flexbox`]: true,
            [`${prefixCls}-flexbox-${span}`]: span !== undefined,
            [`${prefixCls}-flexbox-order-${order}`]: order !== undefined,
            [`${prefixCls}-flexbox-grow-${grow}`]: grow !== undefined,
            [`${prefixCls}-flexbox-shrink-${shrink}`]: shrink !== undefined,
            [`${prefixCls}-flexbox-offset-${offset}`]: offset !== undefined,
            [`${prefixCls}-flexbox-direction-${direction}`]: direction,
            [`${prefixCls}-flexbox-wrap-${wrap}`]: wrap,
            [`${prefixCls}-flexbox-justify-${justify}`]: justify,
            [`${prefixCls}-flexbox-alignContent-${alignContent}`]: alignContent,
            [`${prefixCls}-flexbox-align-${align}`]: align,
            [`${prefixCls}-flexbox-alignSelf-${alignSelf}`]: alignSelf,
        });
        const cols = Children.map(
            Children.map(children, col => {
                if (col && col.props && col.props['data-_-_flexBox-_-']) {
                    if (direction === 'column' || direction === 'column-reverse') {
                        const { offset, order, xs, sm, md, lg, xl } = col.props;
                        return [<FlexBox data-_-_flexColumnOffset_-_={true}
                            span={offset || 0}
                            order={order || 0}
                            xs={typeof xs === 'object' ? { span: xs.offset, order: xs.order } : xs}
                            sm={typeof sm === 'object' ? { span: sm.offset, order: sm.order } : sm}
                            md={typeof md === 'object' ? { span: md.offset, order: md.order } : md}
                            lg={typeof lg === 'object' ? { span: lg.offset, order: lg.order } : lg}
                            xl={typeof xl === 'object' ? { span: xl.offset, order: xl.order } : xl}
                        />, col];
                    } else {
                        return col;
                    }
                } else {
                    return col;
                }
            }),
            col => {
                if (gutter > 0 && col && col.props && col.props['data-_-_flexBox-_-']) {
                    if (col.props['data-_-_flexColumnOffset_-_'] === true) {
                        return col;
                    } else {
                        const { paddingLeft, paddingBottom, paddingRight, paddingTop } = col.props.style || {};
                        return cloneElement(col, {
                            style: Object.assign({},
                                direction === 'row' || direction === 'row-reverse' ?
                                    {
                                        paddingLeft: paddingLeft !== undefined ? paddingLeft : gutter / 2,
                                        paddingRight: paddingRight !== undefined ? paddingRight : gutter / 2,
                                    } : {
                                        paddingTop: paddingTop !== undefined ? paddingTop : gutter / 2,
                                        paddingBottom: paddingBottom !== undefined ? paddingBottom : gutter / 2,
                                    }
                                , col.props.style)
                        });
                    }
                } else {
                    return col;
                }
            });

        return <div {...props} className={cls} style={style}>{cols}</div>;
    }
}

export default FlexBox;