'use strict';
/**
 * d2recharts module
 * @module d2recharts
 * @see module:index
 * @see https://github.com/hustcc/echarts-for-react/blob/master/src/echarts-for-react.js
 */
const React = require('react');
const echarts = require('echarts');
const elementResizeEvent = require('element-resize-event');
const _ = require('lodash');
import update from 'immutability-helper';
const propTypes = require('./prop-types');

class Recharts extends React.Component {
  componentDidMount() {
    // first add
    const me = this;
    const echartObj = me.renderEchartDom();
    const props = me.props;
    const onEvents = props.onEvents || [];

    _.forIn(onEvents, (eventFunc, eventName) => {
      // ignore the event config which not satisfy
      if (_.isString(eventName) && _.isFunction(eventFunc)) {
        // binding event
        echartObj.on(eventName, (param) => {
          eventFunc(param, me, echartObj);
        });
      }
    });

    // on chart ready
    if (_.isFunction(props.onChartReady)) {
      props.onChartReady(me, echartObj);
    }

    // on resize
    elementResizeEvent(me.wrapper, () => {
      echartObj.resize();
    });
  }

  componentDidUpdate(prevProps, prevState) {
    // update
    if (JSON.stringify(prevProps.option) !== JSON.stringify(this.props.option)) {
      this.renderEchartDom();
    }
  }

  componentWillUnmount() {
    // remove
    echarts.dispose(this.wrapper);
  }

  getEchartsInstance() {
    // return the echart object
    const me = this;
    const props = me.props;
    const option = props.option;
    const theme = props.theme || option.theme;
    return echarts.getInstanceByDom(me.wrapper) || echarts.init(me.wrapper, theme);
  }

  renderEchartDom() {
    const me = this;
    // render the dom
    // init the echart object
    let props = this.props;
    if (this.props.option.dataZoom) {
      const h = Number.parseInt(this.props.height, 10);
      props = update(this.props, {
        option: {
          dataZoom: {
            $set: _.map(this.props.option.dataZoom, (opt) => {
              let newOpt = opt;
              if (opt.type !== 'inside') {
                newOpt = update(newOpt, {
                  top: {
                    $set: h - 20,
                  },
                  bottom: {
                    $set: 0,
                  },
                });
                if (this.props.option.series.length === 1) {
                  // 双轴图datazoom偏移，单轴图时露出右侧端点
                  newOpt = update(newOpt, {
                    right: {
                      $set: {
                        right: 5,
                      }
                    }
                  });
                }
              }
              return newOpt;
            }),
          }
        }
      });
    }
    const echartObj = me.getEchartsInstance();
    if (props.option.xAxis && props.option.xAxis.data && !props.option.dataZoom) {
      // different chart has different config, Scatter, Radar, Funnel, Pie, Bar
      props = update(props, {
        option: {
          xAxis: {
            axisLabel: {
              $merge: {
                interval: Math.round(props.option.xAxis.data.length / Math.floor(echartObj.getWidth() / 100)),
              }
            }
          }
        }
      });
    }

    // set the echart option
    echartObj.setOption(props.option, props.notMerge, props.lazyUpdate);
    // set loading mask
    if (props.showLoading) {
      echartObj.showLoading();
    } else {
      echartObj.hideLoading();
    }
    // on chart ready
    if (props.option && _.isFunction(props.option.onChartRendered)) {
      props.option.onChartRendered(me, echartObj);
    }
    return echartObj;
  }

  render() {
    const me = this;
    const props = _.clone(me.props);
    const style = _.assign({
      width: props.option.width || props.width,
      height: props.option.height || props.height,
    }, props.style);
    delete props.option.width;
    delete props.option.height;
    // for render
    return (
      <div ref={(wrapper) => me.wrapper = wrapper} className={props.className} style={style}/>
    );
  }
}

Recharts.propTypes = propTypes.recharts;
Recharts.defaultProps = {
  lazyUpdate: true,
  notMerge: true,
  width: 'auto',
  height: '300px',
};

module.exports = Recharts;
