/** @jsx createElement */

'use strict';

import { createElement, Component, findDOMNode, PropTypes } from 'rax';
import View from 'nuke-view';
import { Detection } from 'nuke-ep-utils';
import { connectStyle } from 'nuke-theme-provider';
import Emitter from '../util/emitter';
import Transform from './transform.js';
import stylesProvider from '../styles/index';
import Finger from './finger';
import Nav from './nav';
// 在weex及非android4.4以下的机器中才使用ep绑定
let expressionBinding = {};
try {
  expressionBinding = require('@weex-module/expressionBinding');
} catch (e) { }
const formatRem = num => (
  `${(
    (parseInt(num, 10) * document.documentElement.clientWidth) /
      750
  ).toString()}px`
);
class Tabbar extends Component {
  constructor(props) {
    super(props);
    this.childrenElements = []; // 存放tab主体element
    this.tabMap = {}; // 用于记录哪个tab是被激活过的状态
    this.tabPage = []; // 存放tab节点

    this.ob = null;
    this.scrolling = false;
    this.maxIndex = (props.children && props.children.length - 1) || 0; // tab的子节点只能是tab.item
    this.state = {
      curIndex:
        props.activeKey &&
          props.activeKey >= 0 &&
          props.activeKey <= this.maxIndex
          ? props.active
          : 0,
      transform: 0,
      prevIndex: null,
    };
    if (
      typeof props.activeKey === 'number' &&
      props.activeKey >= 0 &&
      props.activeKey <= this.maxIndex
    ) {
      this.tabMap[props.activeKey] = true;
    }
  }
  componentWillMount() { }
  componentDidMount() {
    const { curIndex } = this.state;
    this.ob = findDOMNode(`view${curIndex}`);
  }

  /**
   *  横向滑动停止
   */
  panEnd = (e) => {
    if (newIndex < 0) {
      newIndex = 0;
    } else if (newIndex > this.maxIndex) {
      newIndex = this.maxIndex;
    }
    if (Detection.iOS) {
      setTimeout(() => {
        this.slideTo(newIndex, 'pan');
      }, 50);
    } else {
      this.slideTo(newIndex, 'pan');
    }
  };

  onSwipe(evt) {
    const { direction } = evt;
    let { curIndex } = this.state;
    if (this.focused) {
      return false;
    }
    switch (direction) {
      case 'Left':
        curIndex < this.maxIndex && ++curIndex && this.bindStyle(curIndex);
        break;
      case 'Right':
        curIndex > 0 && curIndex-- && this.bindStyle(curIndex);
        break;
    }
    this.slideTo(curIndex);
  }

  endAnimation() {
    this.list.style.webkitTransition = '0';
    // this.ob && this.ob.style && (this.ob.style.webkitTransition = '0');
  }
  bindStyle(current) {
    // this.ob && this.restore();
    // this.ob = findDOMNode(`view${current}`);
    // if (this.ob && !this.ob.scaleX) {
    //   Transform(this.ob);
    // }
  }
  restore(rotate = true) {
    // this.ob.translateX = this.ob.translateY = 0;
    // !!rotate && (this.ob.rotateZ = 0);
    // this.ob.scaleX = this.ob.scaleY = 1;
    // this.ob.originX = this.ob.originY = 0;
  }

  onPressMove(evt) {
    const { curIndex } = this.state;

    this.endAnimation();

    if (!this.focused) {
      if (
        (curIndex === 0 && evt.deltaX > 0) ||
        (curIndex === this.maxIndex && evt.deltaX < 0)
      ) {
        this.translateX += evt.deltaX / 3;
        this.list.style.transform =
          `translateX(${formatRem(this.translateX)})`;
      } else {
        this.translateX += evt.deltaX;
      }
    }

    evt.preventDefault();
  }
  /**
   * tab切换前的回调函数
   * @param index 即将滚动去的位置
   * @param type  触发滚动的事件类型
   */
  slideTo = (index, type) => {
    const time = 300;
    if (this.isMoving === true) return;
    this.isMoving = true;
    const { onChange, beforeSlide, forbidNavScroll } = this.props;
    const prevIndex = this.state.curIndex;
    const moveEndCallback = () => {
      if (typeof onChange === 'function') {
        onChange(index, prevIndex, type);
      }
      this.setState({
        curIndex: index,
        prevIndex,
      });
      this.isMoving = false;
    };
    const navRef = this.refs.nav && this.refs.nav.wrappedInstance;
    if (typeof beforeSlide === 'function') {
      if (!beforeSlide(index, type)) return;
    }
    // 选中状态滚动,当只有两个item，无需scroll的时候需要禁止滚动
    if (!forbidNavScroll) {
      navRef.scrollTo(index);
    }
    navRef.focusMove(index);
    navRef.setState({
      curIndex: index,
    });
    // if (Detection.epEnable) {
    //   // 高版本系统的手机才使用transform动画
    //   const animation = require('@weex-module/animation');
    //   const sliderElement = this.refs.listSlider;
    //   const dist = 750 * index;
    //   animation.transition(
    //     findDOMNode(sliderElement),
    //     {
    //       styles: {
    //         transform: `translateX(-${dist}px)`,
    //       },
    //       delay: 0,
    //       duration: time,
    //       timingFunction: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', // ['cubic-bezier(0.25, 0.46, 0.45, 0.94)', 'cubic-bezier(0,0,0.25,1)']
    //     },
    //     () => {}
    //   );
    // }
    this.list.style.webkitTransition = '300ms ease';
    this.translateX = -index * (750 + this.props.gap);
    this.list.style.transform = `translateX(${formatRem(-index * 750)})`;
    moveEndCallback();
  };
  render() {
    const { curIndex, prevIndex } = this.state;
    const {
      themeStyle,
      children,
      style,
      navTop,
      dataSource,
      renderNavItem,
      navStyle,
      renderLoading,
      navFocusStyle,
      forceRender, // ignore SCU just forceRender
      navContentStyle,
    } = this.props;
    const { slider } = themeStyle;
    if (!children.length) {
      return null;
    }
    if (navTop) {
      slider.top = navStyle && navStyle.height;
      navStyle.top = 0;
      delete navStyle.bottom;
    } else {
      slider.bottom = navStyle && navStyle.height;
      navStyle.bottom = 0;
      delete navStyle.top;
    }
    // 根据子节点计算tab偏移

    const sliderStyle = [slider];

    sliderStyle.push({
      width: 750 * children.length,
    });
    this.translateX = -750 * this.state.curIndex;
    sliderStyle.push({
      transform: `translateX(${formatRem(-750 * this.state.curIndex)})`,
    });

    if (this.tabMap[curIndex]) {
      this.tabMap[curIndex]++;
    } else {
      this.tabMap[curIndex] = 1;
    }

    let formatChildren = [];

    formatChildren = children.map((child, index) => {
      const length = children.length;
      const next = circleIndex(this.state.curIndex + 1, length);
      const prev = circleIndex(this.state.curIndex - 1, length);
      const shouldRender = this.tabMap[index] === 1;
      const eachTabStyle = [themeStyle.eachTab, { left: 750 * index }];
      if (this.tabMap[index] && curIndex === index) {
        this.tabPage[curIndex] = (
          <View style={eachTabStyle} key={index} shouldRender={shouldRender}>
            {child}
          </View>
        );
      }
      if (this.tabMap[index]) {
        return this.tabPage[index];
      }
      if (
        typeof renderLoading === 'function' &&
        (index === next || index === prev)
      ) {
        return (
          <View style={eachTabStyle} key={index}>
            {renderLoading(index)}
          </View>
        );
      }
      return null;
    });
    // } else {
    //   formatChildren = children.map((child, index) => {
    //     child.props.id = `view${index}`;
    //     if (index === curIndex) {
    //       return child;
    //     }
    //     return null;
    //   });
    // }
    // const childrenElements = [
    //   <Finger
    //     onPressMove={this.onPressMove.bind(this)}
    //     onSwipe={this.onSwipe.bind(this)}
    //   >
    //     <View
    //       style={sliderStyle}
    //       id="listWrapper"
    //       ref={node => {
    //         this.list = findDOMNode(node);
    //       }}
    //       onHorizontalPan={
    //         Detection.epEnable && this.props.epEnable
    //           ? this.onHorizontalPan
    //           : null
    //       }
    //     >
    //       {formatChildren}
    //     </View>
    //   </Finger>,
    // ];
    const childrenElements = [

      <View
        style={sliderStyle}
        id="listWrapper"
        ref={(node) => {
          this.list = findDOMNode(node);
        }}
        onHorizontalPan={
          Detection.epEnable && this.props.epEnable
            ? this.onHorizontalPan
            : null
        }
      >
        {formatChildren}
      </View>,
    ];
    const headerStyle = navTop
      ? {
        ...navStyle,
        top: 0,
        positon: 'relative',
      }
      : navStyle;
    const NavWithProps = (
      <View style={[themeStyle.header, headerStyle]}>
        <Nav
          ref="nav"
          dataSource={dataSource}
          renderNavItem={renderNavItem}
          slideTo={(...args) => this.slideTo(...args)}
          style={navStyle}
          contentStyle={navContentStyle}
          navFocusStyle={navFocusStyle}
          forceRender={forceRender}
        />
      </View>
    );
    navTop
      ? childrenElements.unshift(NavWithProps)
      : childrenElements.push(NavWithProps);
    return (
      <View style={[themeStyle.wrapContainer, style]}>{childrenElements}</View>
    );
  }
}
function circleIndex(i, len) {
  return (len + (i % len)) % len;
}
// Tabbar.propTypes = {
// };

Tabbar.defaultProps = {
  epEnable: false,
  navTop: true,
};
Tabbar.displayName = 'Ep-Tabbar';

export default connectStyle(stylesProvider)(Tabbar);
