/** @jsx createElement */

import {
  Component,
  findDOMNode,
  createElement,
  setNativeProps,
  PropTypes,
} from 'rax';
import { isWeb } from 'nuke-env';
import View from 'nuke-view';
import addStyle from './add-style';

const defaultStyle = {
  flexShrink: 0,
  flexDirection: 'column-reverse',
  display: 'flex',
  overflow: 'hidden',
  height: 0,
};
const FULL_WIDTH = 750;
const defaultHeight = 150;
class RefreshControl extends Component {
  constructor(props) {
    super(props);
    this.getHeightPxValue();
    this.addAnimStyle();
  }
  findDom() {
    if (!this.dom) {
      this.dom = findDOMNode(this.refs.webRefresh);
    }
    return this.dom;
  }
  setStyle(styleData) {
    const elementStyle = this.findDom().style;
    for (const styleName in styleData) {
      elementStyle[styleName] = styleData[styleName];
    }
  }
  getHeightPxValue() {
    const { style = {} } = this.props;
    const height = parseInt(style.height || defaultHeight, 10);
    if (window.devicePixelRatio) {
      if (typeof height === 'number') {
        this.height = height * window.screen.width / FULL_WIDTH;
      }
      this.height = height * window.screen.width / FULL_WIDTH;
    }
  }
  addAnim() {
    setNativeProps(this.refs.webRefresh, { className: 'refreshAnim' });
  }
  removeAnim() {
    setNativeProps(this.refs.webRefresh, { className: 'empty' });
  }

  // 展开下拉动画
  setWebRefreshHeight = () => {
    this.setStyle({
      height: `${Math.floor(this.move / 3)}px`,
    });
  };

  // 收起下拉动画
  resetWebRefresh = () => {
    if (this.move / 3 >= this.height) {
      this.addAnim();
      const list = findDOMNode(this.props.listId);
      this.props.onRefresh && this.props.onRefresh();
    } else {
      this.removeAnim();
      this.setStyle({
        height: '0px',
      });
    }
  };
  /**
   * 仿 iOS 下拉刷新逻辑
   * 只有超过 refreshControl 的高度后才可以触发时间。
   * 并执行快速回弹到固定高度的，继而按照动画回弹。
   */
  addAnimStyle = () => {
    // 下拉刷新 css 动画效果
    const { animationTime: animTime } = this.props;
    const animStr = `0% {height: ${this.height}px} 40% {height: ${
      this.height
    }px} 100% {height: 0px}`;
    const strHTML =
      `.refreshAnim { animation:runWebRefresh ${
        animTime
      }s; -moz-animation:runWebRefresh ${
        animTime
      }s; -webkit-animation:runWebRefresh ${
        animTime
      }s; -o-animation:runWebRefresh ${
        animTime
      }s; } @keyframes runWebRefresh {${
        animStr
      }} @-moz-keyframes runWebRefresh {${
        animStr
      }} @-webkit-keyframes runWebRefresh {${
        animStr
      }} @-o-keyframes runWebRefresh {${
        animStr
      }}`;
    addStyle(strHTML);
  };

  setListEvent = () => {
    const listId = this.props.listId;
    // 绑定下拉刷新事件
    setTimeout(() => {
      const list = findDOMNode(listId);
      list.addEventListener(
        'touchstart',
        (e) => {
          this.startY = e.changedTouches[0].pageY;
        },
        false
      );
      list.addEventListener(
        'touchmove',
        (e) => {
          this.moveY = e.changedTouches[0].pageY;
          if (list.scrollTop == 0) {
            this.move = this.moveY - this.startY;
            this.setWebRefreshHeight();
            if (this.move > 0) {
              e.preventDefault();
            }
          }
        },
        false
      );
      list.addEventListener(
        'touchend',
        (e) => {
          this.endY = e.changedTouches[0].pageY;
          if (list.scrollTop == 0 && this.startY < this.endY) {
            this.resetWebRefresh();
          }
        },
        false
      );
    }, 300);
  };

  componentDidMount() {
    this.setListEvent();
  }

  componentWillReceiveProps(nextProps) {
    // if (nextProps.refreshing !== this.props.refreshing) {
    if (!nextProps.refreshing) {
      this.removeAnim();
      this.setStyle({ height: '0px', overflow: 'hidden' });
    }
    // }
  }

  render() {
    const { style } = this.props;
    const refreshStyle = Object.assign({}, defaultStyle, style, { height: 0 });
    if (isWeb) {
      return (
        <View ref="webRefresh" style={refreshStyle}>
          {this.props.children}
        </View>
      );
    }
    return null;
  }
}
RefreshControl.propTypes = {
  animationTime: PropTypes.float,
  isRefreshing: PropTypes.boolean,
  onRefresh: PropTypes.func,
};
RefreshControl.defaultProps = {
  animationTime: 1.5,

  style: {},
};

RefreshControl.displayName = 'RefreshControl';

export default RefreshControl;
