import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
var _jsxFileName = 'src/tabs/Tabs.jsx';
import React, { PureComponent, Children, isValidElement, cloneElement } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import throttle from '../util/throttle';
import Icon from '../icon';
import Button from '../button';

/**
 * Tabs
 * */

var Tabs = function (_PureComponent) {
    _inherits(Tabs, _PureComponent);

    function Tabs(props, context) {
        _classCallCheck(this, Tabs);

        var _this = _possibleConstructorReturn(this, (Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call(this, props, context));

        _this.valueToIndex = {};
        _this.scrollLeft = 0;

        _this.init = function () {
            var scrollable = _this.props.scrollable;

            _this.updateInkbar();
            scrollable && _this.scrollToDefaultTab();
            scrollable && _this.updateScrollButtonState();
            window.addEventListener('resize', throttle(function () {
                _this.updateInkbar();
                scrollable && _this.updateScrollButtonState();
            }, 500));
        };

        _this.scrollToDefaultTab = function () {
            var newStyle = _this.getDefaultTabPosition();
            if (newStyle.left != null && (newStyle.left - _this.scrollLeft > _this.scroller.clientWidth - newStyle.width + 10 || newStyle.left - _this.scrollLeft < -10) // 10表示隐藏宽度小于10时不滚动
            ) {
                    _this.scrollTo(newStyle.left);
                    // this.forceUpdate();
                }
        };

        _this.updateInkbar = function () {
            var newStyle = _this.getDefaultTabPosition();
            if ((newStyle.left !== _this.state.inkbarStyle.left || newStyle.width !== _this.state.inkbarStyle.width) && !Number.isNaN(newStyle.left) && !Number.isNaN(newStyle.width)) {
                _this.setState({ inkbarStyle: newStyle });
            }
        };

        _this.getTabsEl = function (el) {
            _this.tabs = el;
        };

        _this.getScrollerEl = function (el) {
            _this.scroller = el;
        };

        _this.updateScrollButtonState = function () {
            _this.setState({
                disableRightButton: !_this.tabs || !_this.scroller || _this.scrollLeft + _this.scroller.clientWidth >= _this.tabs.clientWidth,
                disableLeftButton: !_this.tabs || !_this.scroller || _this.scrollLeft <= 0
            });
        };

        _this.onLeftScrollClick = function () {
            if (_this.tabs && _this.scroller) {
                var newLeft = _this.scrollLeft - _this.scroller.clientWidth + _this.tabs.children[0].clientWidth;
                _this.scrollTo(newLeft <= 0 ? 0 : newLeft);
                _this.updateScrollButtonState();
            }
        };

        _this.onRightScrollClick = function () {
            if (_this.tabs && _this.scroller) {
                var newLeft = _this.scrollLeft + _this.scroller.clientWidth - _this.tabs.children[0].clientWidth;
                _this.scrollTo(newLeft >= _this.tabs.clientWidth ? _this.tabs.clientWidth : newLeft);
                _this.updateScrollButtonState();
            }
        };

        _this.onScroll = function (e) {
            // console.log(e.touches[0]);
        };

        _this.onSelect = function (e, tabValue) {
            var _this$props = _this.props,
                onChange = _this$props.onChange,
                onSelect = _this$props.onSelect,
                scrollable = _this$props.scrollable,
                value = _this$props.value;
            var selectedValue = _this.state.selectedValue;

            if (!_this.isControlled) {
                _this.setState({ selectedValue: tabValue }, function () {
                    if (scrollable) {
                        _this.scrollToDefaultTab();
                        _this.updateScrollButtonState();
                    }
                });
            }
            if (onChange && (_this.isControlled ? value : selectedValue) !== tabValue) {
                onChange(e, tabValue);
            }

            if (onSelect) {
                onSelect(e, tabValue);
            }
        };

        _this.isControlled = props.value != null;
        _this.state = Object.assign({
            inkbarStyle: {},
            disableLeftButton: false,
            disableRightButton: false
        }, _this.isControlled ? {} : { selectedValue: props.defaultValue });
        _this.tabItems = {};
        return _this;
    }

    _createClass(Tabs, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            this.init();
            setTimeout(this.init, 300);
        }
    }, {
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(newProps) {
            if (!this.isControlled && newProps.defaultValue !== this.props.defaultValue) {
                this.setState({
                    selectedValue: newProps.defaultValue
                });
            }
        }
    }, {
        key: 'componentDidUpdate',
        value: function componentDidUpdate() {
            this.updateInkbar();
        }
    }, {
        key: 'getTabs',
        value: function getTabs() {
            var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;

            var tabs = [];
            Children.forEach(props.children, function (tab) {
                if (isValidElement(tab)) {
                    tabs.push(tab);
                }
            });
            return tabs;
        }
    }, {
        key: 'getDefaultTabPosition',
        value: function getDefaultTabPosition() {
            var targetIndex = this.valueToIndex[this.isControlled ? this.props.value : this.state.selectedValue];
            var newStyle = {};
            if (this.tabs && targetIndex != null) {
                var target = this.tabs.children[targetIndex];
                if (target) {
                    newStyle.left = (target.getBoundingClientRect().left || 0) - (this.tabs.getBoundingClientRect().left || 0);
                    newStyle.width = target.getBoundingClientRect().width;
                }
            }
            return newStyle;
        }
    }, {
        key: 'scrollTo',
        value: function scrollTo(distance) {
            if (this.tabs) {
                this.scrollLeft = distance;
                this.tabs.style.transform = 'translateX(' + -this.scrollLeft + 'px)';
            }
        }
    }, {
        key: 'render',
        value: function render() {
            var _this2 = this;

            var _props = this.props,
                children = _props.children,
                prefixCls = _props.prefixCls,
                className = _props.className,
                showInkbar = _props.showInkbar,
                fullWidth = _props.fullWidth,
                scrollable = _props.scrollable,
                defaultValue = _props.defaultValue,
                propsValue = _props.value,
                other = _objectWithoutProperties(_props, ['children', 'prefixCls', 'className', 'showInkbar', 'fullWidth', 'scrollable', 'defaultValue', 'value']);

            var _state = this.state,
                selectedValue = _state.selectedValue,
                disableLeftButton = _state.disableLeftButton,
                disableRightButton = _state.disableRightButton;

            var value = this.isControlled ? propsValue : selectedValue;
            var classes = classNames(prefixCls, {});
            var tabs = this.getTabs().map(function (tab, key) {
                _this2.valueToIndex[tab.props.value != null ? tab.props.value : key] = key;
                return cloneElement(tab, {
                    fullWidth: fullWidth,
                    index: key,
                    key: tab.props.value || key,
                    selected: tab.props.value === value || tab.props.value == null && key === value,
                    onSelect: _this2.onSelect
                });
            });
            return React.createElement(
                'div',
                Object.assign({}, other, { className: classNames(prefixCls + '-container', className), __source: {
                        fileName: _jsxFileName,
                        lineNumber: 218
                    },
                    __self: this
                }),
                scrollable ? React.createElement(
                    Button,
                    {
                        className: prefixCls + '-scroll-btn',
                        onClick: this.onLeftScrollClick,
                        disabled: disableLeftButton, __source: {
                            fileName: _jsxFileName,
                            lineNumber: 220
                        },
                        __self: this
                    },
                    React.createElement(Icon, { type: 'left-arrow', className: prefixCls + '-scroll-btn-icon', __source: {
                            fileName: _jsxFileName,
                            lineNumber: 224
                        },
                        __self: this
                    })
                ) : null,
                React.createElement(
                    'div',
                    { className: prefixCls + '-scroller', ref: this.getScrollerEl, __source: {
                            fileName: _jsxFileName,
                            lineNumber: 227
                        },
                        __self: this
                    },
                    React.createElement(
                        'div',
                        {
                            className: classes,
                            role: 'tablist',
                            ref: this.getTabsEl,
                            style: {
                                transform: 'translateX(' + -this.scrollLeft + 'px)'
                            }, __source: {
                                fileName: _jsxFileName,
                                lineNumber: 228
                            },
                            __self: this
                        },
                        tabs,
                        showInkbar ? React.createElement('div', { className: prefixCls + '-inkbar', style: this.state.inkbarStyle, __source: {
                                fileName: _jsxFileName,
                                lineNumber: 236
                            },
                            __self: this
                        }) : null
                    )
                ),
                scrollable ? React.createElement(
                    Button,
                    {
                        className: prefixCls + '-scroll-btn',
                        onClick: this.onRightScrollClick,
                        disabled: disableRightButton, __source: {
                            fileName: _jsxFileName,
                            lineNumber: 240
                        },
                        __self: this
                    },
                    React.createElement(Icon, { type: 'right-arrow', className: prefixCls + '-scroll-btn-icon', __source: {
                            fileName: _jsxFileName,
                            lineNumber: 244
                        },
                        __self: this
                    })
                ) : null
            );
        }
    }]);

    return Tabs;
}(PureComponent);

Tabs.propTypes = {
    prefixCls: PropTypes.string,
    className: PropTypes.string,
    /** 是否显示墨水条 */
    showInkbar: PropTypes.bool,
    /** 是否占满全宽 */
    fullWidth: PropTypes.bool,
    /** 是否可以滚动 */
    scrollable: PropTypes.bool,
    /** 默认值 */
    defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
    /** tab切换回调 function(e, value) */
    onChange: PropTypes.func,
    /** tab点击回调 function(e, value) */
    onSelect: PropTypes.func
};
Tabs.defaultProps = {
    defaultValue: 0,
    prefixCls: 'ne-tabs',
    showInkbar: true,
    fullWidth: false,
    scrollable: false
};

export default Tabs;