import * as  React from "react";
import ChartComponent from "react-chartjs-2";
import {addCommas} from "../../Utils/Utils";
import { ThemeColors } from "../../Utils/ThemeColors";

export const chartTooltip = {
  backgroundColor: ThemeColors().foregroundColor,
  titleFontColor: ThemeColors().primaryColor,
  borderColor: ThemeColors().separatorColor,
  borderWidth: 0.5,
  bodyFontColor: ThemeColors().primaryColor,
  bodySpacing: 10, 
  xPadding: 15,
  yPadding: 15,
  cornerRadius: 0.15
};
const Chart = require('react-chartjs-2').Chart;


export const centerTextPlugin = {
  afterDatasetsUpdate: function(chart : any) {},
  beforeDraw: function(chart : any) {
    var width = chart.chartArea.right;
    var height = chart.chartArea.bottom;
    var ctx = chart.chart.ctx;
    ctx.restore();

    var activeLabel = chart.data.labels[0];
    var activeValue = chart.data.datasets[0].data[0];
    var dataset = chart.data.datasets[0];
    var meta = dataset._meta[Object.keys(dataset._meta)[0]];
    var total = meta.total;

    var activePercentage = parseFloat(((activeValue / total) * 100).toFixed(1));
    activePercentage = chart.legend.legendItems[0].hidden
      ? 0
      : activePercentage;

    if (chart.pointAvailable) {
      activeLabel = chart.data.labels[chart.pointIndex];
      activeValue =
        chart.data.datasets[chart.pointDataIndex].data[chart.pointIndex];

      dataset = chart.data.datasets[chart.pointDataIndex];
      meta = dataset._meta[Object.keys(dataset._meta)[0]];
      total = meta.total;
      activePercentage = parseFloat(((activeValue / total) * 100).toFixed(1));
      activePercentage = chart.legend.legendItems[chart.pointIndex].hidden
        ? 0
        : activePercentage;
    }

    ctx.font = "36px Nunito, sans-serif";
    ctx.fillStyle  = ThemeColors().primaryColor;
    ctx.textBaseline = "middle";

    var text = activePercentage + "%",
      textX = Math.round((width - ctx.measureText(text).width) / 2),
      textY = height / 2;
    ctx.fillText(text, textX, textY);

    ctx.font = "14px Nunito, sans-serif";
    ctx.textBaseline = "middle";

    var text2 = activeLabel,
      textX2 = Math.round((width - ctx.measureText(text2).width) / 2),
      textY2 = height / 2 - 30;
    ctx.fillText(text2, textX2, textY2);

    ctx.save();
  },
  beforeEvent: function(chart : any, event : any, options : any) {
    var firstPoint = chart.getElementAtEvent(event)[0];

    if (firstPoint) {
      chart.pointIndex = firstPoint._index;
      chart.pointDataIndex = firstPoint._datasetIndex;
      chart.pointAvailable = true;
    }
  }
};

export class PolarShadow extends React.Component<{}, any> {
  public chart_instance: any;

  componentWillMount() {
    Chart.defaults.polarArea = Chart.defaults.polarArea;
    Chart.controllers.polarArea = Chart.controllers.polarArea.extend({
      draw: function(ease : any) {
        Chart.controllers.radar.prototype.draw.call(this, ease);
        let ctx = this.chart.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.2)";
        ctx.shadowBlur = 7;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 7;
        ctx.responsive = true;
        Chart.controllers.radar.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }

  render() :JSX.Element{
    return (
      <ChartComponent
        ref={ (ref  : any)=> (this.chart_instance = ref && ref.chart_instance)}
        data={'' as any}
        type="polarArea"
        {...this.props}
      />
    );
  }
}

export class LineShadow extends React.Component<{}, any> {
  public chart_instance: any;

    componentWillMount() {
    Chart.defaults.line = Chart.defaults.line;
    Chart.controllers.line = Chart.controllers.line.extend({
      draw: function(ease : any) {
        Chart.controllers.line.prototype.draw.call(this, ease);
        var ctx = this.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.15)";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 10;
        ctx.responsive = true;
        ctx.stroke();
        Chart.controllers.line.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }
 render() {
    return (
      <ChartComponent
        ref={ (ref  : any) => (this.chart_instance = ref && ref.chart_instance)}
        data={'' as any}
        type="line"
        {...this.props}
      />
    );
  }
}

export class ScatterShadow extends React.Component<{}, any> {
  public chart_instance: any;

  componentWillMount() {
    Chart.defaults.scatter = Chart.defaults.scatter;
    Chart.controllers.scatter = Chart.controllers.scatter.extend({
      draw: function(ease : any) {
        Chart.controllers.scatter.prototype.draw.call(this, ease);
        let ctx = this.chart.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.2)";
        ctx.shadowBlur = 7;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 7;
        ctx.responsive = true;
        Chart.controllers.scatter.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }

  render() {
    return (
      <ChartComponent
        ref={(ref  : any) => (this.chart_instance = ref && ref.chart_instance)}
        data={'' as any}
        type="scatter"
        {...this.props}
      />
    );
  }
}

export class BarShadow extends React.Component<{}, any> {
  public chart_instance: any;

  componentWillMount() {
    Chart.defaults.bar = Chart.defaults.bar;
    Chart.controllers.barWithShadow = Chart.controllers.bar.extend({
      draw: function(ease : any) {
        Chart.controllers.bar.prototype.draw.call(this, ease);
        var ctx = this.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.2)";
        ctx.shadowBlur = 7;
        ctx.shadowOffsetX = 5;
        ctx.shadowOffsetY = 7;
        ctx.responsive = true;
        Chart.controllers.bar.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }

  render() {
    return (
      <ChartComponent
        ref={(ref  : any) => (this.chart_instance = ref && ref.chart_instance)}
        data={'' as any}
        type="bar"
        {...this.props}
      />
    );
  }
}

export class RadarShadow extends React.Component<{}, any> {
  public chart_instance: any;

  componentWillMount() {
    Chart.defaults.radar = Chart.defaults.radar;
    Chart.controllers.radarWithShadow = Chart.controllers.radar.extend({
      draw: function(ease : any) {
        Chart.controllers.radar.prototype.draw.call(this, ease);
        let ctx = this.chart.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.2)";
        ctx.shadowBlur = 7;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 7;
        ctx.responsive = true;
        Chart.controllers.radar.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }

  render() {
    return (
      <ChartComponent
        ref={(ref  : any) => (this.chart_instance = ref && ref.chart_instance)}
        data={'' as any}
        type="radar"
        {...this.props}
      />
    );
  }
}

export class PieShadow extends React.Component<{}, any> {
  public chart_instance: any;

  componentWillMount() {
    Chart.defaults.pie = Chart.defaults.pie;
    Chart.controllers.pie = Chart.controllers.pie.extend({
      draw: function(ease : any) {
        Chart.controllers.pie.prototype.draw.call(this, ease);
        let ctx = this.chart.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.15)";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 10;
        ctx.responsive = true;
        Chart.controllers.pie.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }

  render() {
    return (
      <ChartComponent
        ref={(ref  : any) => (this.chart_instance = ref && ref.chart_instance)}
        type="pie"
        data={'' as any}
        {...this.props}
      />
    );
  }
}

export class DoughnutShadow extends React.Component<{}, any> {
  public chart_instance: any;

  componentWillMount() {
    Chart.defaults.doughnut = Chart.defaults.doughnut;
    Chart.controllers.doughnut = Chart.controllers.doughnut.extend({
      draw: function(ease : any) {
        Chart.controllers.doughnut.prototype.draw.call(this, ease);
        let ctx = this.chart.chart.ctx;
        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.15)";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 10;
        ctx.responsive = true;
        Chart.controllers.doughnut.prototype.draw.apply(this, arguments);
        ctx.restore();
      }
    });
  }

  render() {
    return (
      <ChartComponent
        ref={(ref : any) => (this.chart_instance = ref && ref.chart_instance)}
        type="doughnut"
        data={'' as any}
        {...this.props}
      />
    );
  }
}

export class SmallLineChart extends React.Component<{}, any> {
  public chart_instance: any;

  constructor(props : any) {
    super(props);
    this.changeState = this.changeState.bind(this);
    this.state = {
      currentValue: "",
      currentLabel: ""
    };
  }

  componentWillMount() {
    Chart.defaults.line = Chart.defaults.line;
    Chart.controllers.line = Chart.controllers.line.extend({
      draw: function(ease : any) {
        Chart.controllers.line.prototype.draw.call(this, ease);

        if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
          var activePoint = this.chart.tooltip._active[0];
          var ctx = this.chart.ctx;
          var x = activePoint.tooltipPosition().x;
          var topY = this.chart.scales["y-axis-0"].top;
          var bottomY = this.chart.scales["y-axis-0"].bottom;

          ctx.save();
          ctx.beginPath();
          ctx.moveTo(x, topY);
          ctx.lineTo(x, bottomY);
          ctx.lineWidth = 1;
          ctx.strokeStyle = "rgba(0,0,0,0.1)";
          ctx.stroke();
          ctx.restore();
        }
      }
    });
  }

  changeState(yLabel : any, xLabel : any) {
    this.setState({ currentValue: yLabel, currentLabel: xLabel });
  }


  render() {
    let changeState = this.changeState;
    return (
      <div>
        <div>
          <p className="lead color-theme-1 mb-1 value">
            {this.state.currentValue}
          </p>
          <p className="mb-0 label text-small">{this.state.currentLabel}</p>
        </div>
        <div className="chart">
          <ChartComponent
          data={'' as any}
            ref={(ref  : any) => (this.chart_instance = ref && ref.chart_instance)}
            type="line"
            options={{
              layout: {
                padding: {
                  left: 5,
                  right: 5,
                  top: 10,
                  bottom: 10
                }
              },
              responsive: true,
              maintainAspectRatio: false,
              legend: {
                display: false
              },
              scales: {
                yAxes: [
                  {
                    ticks: {
                      beginAtZero: true
                    },
                    display: false
                  }
                ],
                xAxes: [
                  {
                    display: false
                  }
                ]
              },
              tooltips: {
                intersect: false,
                enabled: false,
                custom: function(tooltipModel) {
                  if (tooltipModel && tooltipModel.dataPoints) {
                    var yLabel = tooltipModel.dataPoints[0].yLabel;
                    var xLabel = tooltipModel.dataPoints[0].xLabel;
                    var label = tooltipModel.body[0].lines[0].split(":")[0];
                    changeState("$" + addCommas(yLabel), label + "-" + xLabel);
                  }
                }
              }
            }}
            plugins={[
              {
                afterInit: function(chart : any, options : any) {
                  var yLabel = chart.data.datasets[0].data[0];
                  var xLabel = chart.data.labels[0];
                  var label = chart.data.datasets[0].label;
                  changeState("$" + addCommas(yLabel), label + "-" + xLabel);
                }
              }
            ]}
            {...this.props}
          />
        </div>
      </div>
    );
  }
}
