import React from 'react';
import moment from 'moment';
import { connect } from 'react-redux';
import 'moment-timezone';
import { securityService } from '../../../services';
import classnames from 'classnames';
import map from 'lodash/map';
import isEqual from 'lodash/isEqual';

// Only require on client-side. Most stuff is fine on serverside, this
// minfied code breaks under node.
let HighStock;
let ReactHighCharts;
if (!window.serverSide) {
  HighStock = require('react-highcharts/dist/bundle/ReactHighstock.src');
  ReactHighCharts = require('react-highcharts');
  const highOptions = {
    global: {
      getTimezoneOffset: (timestamp) => {
        const zone = 'America/New_York';
        const timezoneOffset = -moment.tz(timestamp, zone).utcOffset();
        return timezoneOffset;
      },
    },
  };
  ReactHighCharts.Highcharts.setOptions(highOptions);
  HighStock.Highcharts.setOptions(highOptions);
}

class SecurityChart extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      chartPeriod: '1d',
      chartType: 'line',
      chartData: [],
      isLoading: true,
    };
  }
  componentDidMount() {
    this.updateChart();
    // In order to make sure that "this" is set to the correct thing, we need to jump through some hoops.
    this.state.chartUpdateInterval = setInterval(this.updateChartLoop.bind(this), 20000);
  }
  shouldComponentUpdate(nextProps, nextState) {
    return !isEqual(this.state.chartData, nextState.chartData) ||
                    this.state.chartPeriod !== nextState.chartPeriod ||
                    this.state.chartType !== nextState.chartType ||
                    this.props.symbol !== nextProps.symbol ||
                    this.props.theme !== nextProps.theme;
  }
  componentWillUpdate(nextProps, nextState) {
    if (this.state.chartPeriod !== nextState.chartPeriod) {
      nextState.isLoading = true;
      this.updateChart(nextState.chartPeriod);
    } else if (this.props.symbol !== nextProps.symbol) {
      nextState.isLoading = true;
      this.updateChart(this.state.chartPeriod, nextProps.symbol);
    }
  }
  componentWillUnmount() {
    clearInterval(this.state.chartUpdateInterval);
  }

  updateChartLoop() {
    if (!this.state.isLoading) {
      this.updateChart();
    }
  }

  updateChart(period = this.state.chartPeriod, symbol = this.props.symbol) {
    securityService.getChart(symbol, period)
      .then((data) => {
        this.setState({chartData: data, isLoading: false});
        this.forceUpdate();
      });
  }
  changePeriod(period) {
    this.setState({chartPeriod: period});
  }
  changeType(type) {
    this.setState({chartType: type});
  }

  renderChartPeriods(chartPeriods) {
    const { symbol } = this.props;
    const { chartPeriod } = this.state;
    const buttons = chartPeriods.map((v, i) => {
      const isActive = chartPeriod === v ? 'is-active' : null;
      return <button className={isActive} key={i} onClick={() => this.changePeriod(v)}>{v}</button>;
    });

    return buttons;
  }

  renderChartTypes(chartTypes) {
    const { symbol } = this.props;
    const { chartType } = this.state;
    const buttons = chartTypes.map((v, i) => {
      const isActive = chartType === v ? 'is-active' : null;
      const icon = <i className={'bzpro-icon-' + v}></i>;
      return <button className={isActive} key={i} onClick={() => this.changeType(v)}>{icon}</button>;
    });

    return buttons;
  }

  render() {
    console.log('WE RENDERING THIS SECURITY CHART')

    const data = map(this.state.chartData, (d) => [d.time, d.close]);
    let color = null;
    let fillColor = null;
    const isIncreasing = data && data.length && data[0][1] < data[data.length - 1][1];

    if (data.length !== 0) {
      color = isIncreasing ? 'rgba(48, 191, 163, 1)' : 'rgba(229, 89, 78, 1)';
      fillColor = isIncreasing ? 'rgba(48, 191, 163, .2)' : 'rgba(229, 89, 78, .2)';
    }

    let mainColor = 'rgba(255, 255, 255, 1)';
    let accentColor = 'rgba(73, 83, 96, .3)';
    let accentColor2 = 'rgba(73, 83, 96, 1)';

    if (this.props.theme === 'light') {
      mainColor = 'rgba(44, 51, 63, 1)';
      accentColor = 'rgba(212, 219, 231, .3)';
      accentColor2 = 'rgba(212, 219, 231, 1)';
    }

    const config = {
      chart: {
        backgroundColor: 'transparent',
        height: 250,
        spacingLeft: 0,
        spacingRight: 0,
        spacingBottom: 0,
        zoomType: '',
      },
      tooltip: {
        valueDecimals: 2,
        backgroundColor: 'transparent',
        borderWidth: 0,
        shadow: false,
        useHTML: true,
        pointFormat: '{series.name} <b>{point.y}</b><br/>',
      },
      navigator: {
        enabled: false,
      },
      scrollbar: {
        enabled: false,
      },
      rangeSelector: {
        enabled: false,
      },
      yAxis: {
        opposite: false,
        showLastLabel: true,
        gridLineColor: accentColor2,
        labels: {
          y: 3,
          style: {
            fontFamily: 'proxima nova',
            color: mainColor,
            fontWeight: '200',
          },
        },
      },
      xAxis: {
        alternateGridColor: accentColor,
        showLastLabel: true,
        lineColor: accentColor2,
        tickLength: 0,
        labels: {
          style: {
            fontFamily: 'proxima nova',
            color: mainColor,
            fontWeight: '200',
          },
        },
      },
      series: [],
    };

    if (this.state.chartType === 'candlestick') {
      config.series.push({
        name: this.props.symbol,
        type: 'candlestick',
        data: map(this.state.chartData, (d) => [d.time, d.open, d.high, d.low, d.close]),
        color: 'rgba(229, 89, 78, 1)',
        lineColor: 'rgba(229, 89, 78, 1)',
        upColor: 'rgba(48, 191, 163, 1)',
        upLineColor: 'rgba(48, 191, 163, 1)',
        threshold: null, // default is 0
      });
    } else {
      config.series.push({
        name: this.props.symbol,
        type: 'area',
        linecap: 'square',
        states: {
          hover: {
            enabled: true,
            lineWidth: 2,
          },
        },
        color,
        fillColor,
        data,
        threshold: null, // default is 0
      });
    }
    return (
      <section className="SecurityChart">
        <div className="SecurityChart-filters">
          {this.renderChartPeriods(['1d', '5d', '1m', '3m', '6m', 'YTD', '1y', '2y', '5y', '10y', 'Max'])}
          {this.renderChartTypes(['line', 'candlestick'])}
        </div>
        <HighStock config={config} />
      </section>
    );
  }
}


function selectTheme(state) {
  return {
    theme: state.settings.get('theme'),
  };
}

SecurityChart.propTypes = {
  symbol: React.PropTypes.string.isRequired,
  theme: React.PropTypes.string.isRequired,
};

export default connect(selectTheme)(SecurityChart);
