import React from 'react';
import classNames from 'classnames/dedupe';
import {autobind, debounce} from 'core-decorators';

import log from 'js/utils/log';
import {formatTime} from 'js/utils/formatTime';

import {classname} from 'js/ENUM';
import ScrollBar from './ScrollBar';

class ScrollArea extends React.Component {

  static defaultProps = {
    speed: 1,
    vertical: true,
    horizontal: true,
    smoothScrolling: false,
    minScrollSize: 10,
    swapWheelAxes: false,
    contentWindow: (typeof window === "object") ? window : undefined,
    ownerDocument: (typeof document === "object") ? document : undefined
  }

  constructor(props){
    super(props);
    this.state = {
        scrollTop: 0,
        scrollHeight: 0,
        offsetHeight: 0,
        scrollLeft: 0,
        scrollWidth: 0,
        offsetWidth: 0
    };

    this.scrollArea = {
         scrollTop: () => {
             this.scrollTop();
         },
         scrollBottom: () => {
             this.scrollBottom();
         },
         scrollYTo: (position) => {
             this.scrollYTo(position);
         },
         scrollLeft: () => {
             this.scrollLeft();
         },
         scrollRight: () => {
             this.scrollRight();
         },
         scrollXTo: (position) => {
             this.scrollXTo(position);
         }
     };
  }

  componentDidMount(){
      if(this.props.contentWindow){
          this.props.contentWindow.addEventListener("resize", this.handleWindowResize);
      }
  }

  componentWillUnmount(){
      if(this.props.contentWindow){
          this.props.contentWindow.removeEventListener("resize", this.handleWindowResize);
      }
  }

  componentWillReceiveProps(nextProps) {
    let snapShotScroll = this.scrollInfo();
    this.setState({snapShotScroll});
  }

  componentDidUpdate() {
    let {snapShotScroll: {scrollTop, scrollHeight, offsetHeight}} = this.state;
    let scrollInfo = this.scrollInfo();


    if (scrollInfo.scrollHeight !== scrollHeight) {
      this.setState({snapShotScroll: scrollInfo});

      if (scrollTop === scrollHeight - offsetHeight) {
        this.scrollYTo(scrollInfo.scrollHeight - scrollInfo.offsetHeight);
        
      } else if (scrollInfo.scrollHeight - scrollHeight > 100) {
        this.scrollYTo(scrollInfo.scrollHeight - scrollHeight + scrollTop);
      }
    }
  }

  scrollTop() {
    console.log('scrollTop');
    this.wrapper.scrollTop = 0;
    this.setState(this.scrollInfo());
  }

  scrollBottom () {
    console.log('scrollTop');
    this.wrapper.scrollTop = this.wrapper.scrollHeight;
    this.setState(this.scrollInfo());
  }

  scrollYTo (position) {
    console.log('scrollTop');
    this.wrapper.scrollTop = position;
    this.setState(this.scrollInfo());
  }

  scrollLeft() {
     this.wrapper.scrollLeft = 0;
    this.setState(this.scrollInfo());
  }

  scrollRight() {
    this.wrapper.scrollLeft = this.wrapper.scrollWidth;
    this.setState(this.scrollInfo());
  }

   scrollXTo (position) {
    this.wrapper.scrollLeft = position;
    this.setState(this.scrollInfo());
  }


  scrollInfo() {
    return {
      scrollTop: this.wrapper.scrollTop,
      scrollHeight: this.wrapper.scrollHeight,
      offsetHeight: this.wrapper.offsetHeight,

      scrollLeft: this.wrapper.scrollLeft,
      scrollWidth: this.wrapper.scrollWidth,
      offsetWidth: this.wrapper.offsetWidth,

    }
  }

  @autobind
  handleWindowResize () {
    this.setState(this.scrollInfo());
  }

  @autobind
  handleScroll (e) {
    let scrollInfo = this.scrollInfo();
    this.setState(scrollInfo);

    if (this.props.onScroll) {
      this.props.onScroll(scrollInfo);
    }
  }

  canScrollY(state = this.state){
    let {scrollTop, scrollHeight, offsetHeight, scrollLeft, scrollWidth, offsetWidth, type} = state;

    let scrollableY = scrollHeight > offsetHeight;
    return scrollableY && this.props.vertical;
  }

  handleScrollbarMove () {

  }


  handleScrollbarYPositionChange() {

  }

  @autobind
  mapToScrollBarVertical (position) {
    this.wrapper.scrollTop = position;
  }

  @autobind
  mapToScrollBarHorizontal (position) {
    this.wrapper.scrollLeft = position;
  }

  render() {
    let {children, className, contentClassName, ownerDocument} = this.props;

    let scrollbarY = this.canScrollY()? (
      <ScrollBar
        {...this.state}
        ownerDocument={ownerDocument}
        scrollbarStyle={this.props.verticalScrollbarStyle}
        minScrollSize={this.props.minScrollSize}
        mapToScrollBarVertical={this.mapToScrollBarVertical}
        mapToScrollBarHorizontal={this.mapToScrollBarHorizontal}
        type="vertical"/>
    ): null;

    return (
      	<div className={`scroll-area`}> 
          {scrollbarY}
    			<div className={`scroll-area-wrap`} ref={x => this.wrapper = x} onScroll={this.handleScroll} style={this.props.style}>
            <div className={`scroll-area-body`}>  
              <div className={`scroll-area-content`} ref={x => this.content = x}>  
        		    {children}
              </div>
            </div>
        	</div> 
      	</div>
    );
  }
}



export default ScrollArea;