import { makeArray } from "discourse-common/lib/helpers";
import { debounce, schedule } from "@ember/runloop";
import Component from "@ember/component";
import { number } from "discourse/lib/formatter";
import loadScript from "discourse/lib/load-script";

export default Component.extend({
  classNames: ["admin-report-chart", "admin-report-stacked-chart"],

  init() {
    this._super(...arguments);

    this.resizeHandler = () =>
      debounce(this, this._scheduleChartRendering, 500);
  },

  didInsertElement() {
    this._super(...arguments);

    $(window).on("resize.chart", this.resizeHandler);
  },

  willDestroyElement() {
    this._super(...arguments);

    $(window).off("resize.chart", this.resizeHandler);

    this._resetChart();
  },

  didReceiveAttrs() {
    this._super(...arguments);

    debounce(this, this._scheduleChartRendering, 100);
  },

  _scheduleChartRendering() {
    schedule("afterRender", () => {
      if (!this.element) {
        return;
      }

      this._renderChart(
        this.model,
        this.element.querySelector(".chart-canvas")
      );
    });
  },

  _renderChart(model, chartCanvas) {
    if (!chartCanvas) return;

    const context = chartCanvas.getContext("2d");

    const chartData = makeArray(model.get("chartData") || model.get("data"));

    const data = {
      labels: chartData[0].data.mapBy("x"),
      datasets: chartData.map(cd => {
        return {
          label: cd.label,
          stack: "pageviews-stack",
          data: cd.data.map(d => Math.round(parseFloat(d.y))),
          backgroundColor: cd.color
        };
      })
    };

    loadScript("/javascripts/Chart.min.js").then(() => {
      this._resetChart();

      this._chart = new window.Chart(context, this._buildChartConfig(data));
    });
  },

  _buildChartConfig(data) {
    return {
      type: "bar",
      data,
      options: {
        responsive: true,
        maintainAspectRatio: false,
        responsiveAnimationDuration: 0,
        hover: { mode: "index" },
        animation: {
          duration: 0
        },
        tooltips: {
          mode: "index",
          intersect: false,
          callbacks: {
            beforeFooter: tooltipItem => {
              let total = 0;
              tooltipItem.forEach(
                item => (total += parseInt(item.yLabel || 0, 10))
              );
              return `= ${total}`;
            },
            title: tooltipItem =>
              moment(tooltipItem[0].xLabel, "YYYY-MM-DD").format("LL")
          }
        },
        layout: {
          padding: {
            left: 0,
            top: 0,
            right: 0,
            bottom: 0
          }
        },
        scales: {
          yAxes: [
            {
              stacked: true,
              display: true,
              ticks: {
                userCallback: label => {
                  if (Math.floor(label) === label) return label;
                },
                callback: label => number(label),
                sampleSize: 5,
                maxRotation: 25,
                minRotation: 25
              }
            }
          ],
          xAxes: [
            {
              display: true,
              gridLines: { display: false },
              type: "time",
              offset: true,
              time: {
                parser: "YYYY-MM-DD",
                minUnit: "day"
              },
              ticks: {
                sampleSize: 5,
                maxRotation: 50,
                minRotation: 50
              }
            }
          ]
        }
      }
    };
  },

  _resetChart() {
    if (this._chart) {
      this._chart.destroy();
      this._chart = null;
    }
  }
});
