/* globals i18n */

import Component from "ember-component";
import injectService from 'ember-service/inject';
import moment from 'moment';
import computed from 'ember-computed';
import { htmlSafe } from 'ember-string';
import ENV from 'web-client/config/environment';
import { commatized } from 'web-client/helpers/commatized';

const HEALTH_CODE_MAP = {
  101: i18n('Excellent'),
  102: i18n('Warning'),
  103: i18n('Unstable')
};

const HEALTH_REASON_CODE_MAP = {
  1000: i18n('No recommended changes!'),
  1001: i18n('Incompatible audio codec detected'),
  1002: i18n('Incompatible video codec detected'),
  1003: i18n('Deprecated MP3 audio codec detected'),
  1004: i18n('Average stream bitrate too high'),
  1005: i18n('Substantial frame drops detected'),
  1006: i18n('Poor network connection detected'),
  1007: i18n('Keyframe interval too high')
};

const BITRATE = i18n('Bitrate');
const OFFLINE = i18n('Offline');

const BITRATE_COLORS = {
  value: '#7753BA',
  fill: 'rgba(100,65,164,0.1)',
  border: '#fff'
};

const BITRATE_CHART_OPTIONS = {
  animation: false,
  hover: {
    mode: 'x-axis'
  },
  tooltips: {
    enabled: true,
    mode: 'x-axis',
    backgroundColor: 'rgba(0,0,0,0.8)',
    titleFontFamily: `'Helvetica Neue', 'Helvetica', 'Arial', sans-serif`,
    titleFontSize: 12,
    titleFontColor: '#fff',
    titleSpacing: 2,
    titleMarginBottom: 6,
    bodyFontColor: '#fff',
    bodyFontStyle: 'normal',
    bodySpacing: 2,
    xPadding: 6,
    yPadding: 6,
    caretSize: 4,
    callbacks: {
      title(items) {
        return `${ i18n('Timestamp') }: ${ items[0].xLabel }`;
      },
      label(items, data) {
        return `${ data.datasets[items.datasetIndex].label }: ${ commatized(items.yLabel) }kb/s`;
      }
    }
  },
  legend: {
    display: false
  },
  responsive: true,
  maintainAspectRatio: false,
  scales: {
    xAxes: [
      {
        stacked: true,
        gridLines: {
          display: false,
          zeroLineWidth: 0,
          zeroLineColor: "rgba(0,0,0,0)",
          drawBorder: false
        },
        ticks: {
          display: false,
          fontColor: "#898395",
          padding: 0
        }
      }
    ],
    yAxes: [
      {
        stacked: true,
        gridLines: {
          display: false,
          zeroLineWidth: 0,
          zeroLineColor: "rgba(0,0,0,0)",
          drawBorder: false
        },
        ticks: {
          fontColor: "#898395",
          suggestedMax: 3500,
          maxTicksLimit: 3,
          callback(value) {
            return (value % 1 === 0) ? commatized(Number(value).toFixed(0)) : '';
          }
        }
      }
    ]
  }
};

export default Component.extend({
  classNames: ['js-dashboard-stream-health'],

  ingest: injectService(),

  /* passed in properties */
  channel: null,
  isCollapsed: false,
  isLive: false,
  isChannelOwner: false,
  qualityCode: null,
  reasonCodes: null,
  trackDashboardEvent() {},

  /* internal properties */
  bitrate: OFFLINE,
  bitrateChartOptions: BITRATE_CHART_OPTIONS,
  bitrateData: null,
  isShowingStreamTest: false,
  isShowingGraph: false,

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

    this.pollTask(next => {
      if (this.get('isChannelOwner')) {
        this._updateBitRate();
      }

      this.runTask(next, ENV.delay.dashboard.pollInterval);
    }, 'stream-health#update-quality');
  },

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

    if (!this.get('isCollapsed') && this.get('isLive') && this.get('isChannelOwner')) {
      this._updateBitRate();
    }
  },

  pillClass: computed('qualityCode', function() {
    switch (this.get('qualityCode')) {
      case 101: {
        return htmlSafe('pill--green');
      }
      case 102: {
        return htmlSafe('pill--orange');
      }
      default: {
        return htmlSafe('pill--red');
      }
    }
  }),

  qualityLabel: computed('qualityCode', function() {
    let code = this.get('qualityCode');

    return HEALTH_CODE_MAP[code];
  }),

  reasons: computed.map('reasonCodes', function(code) {
    return HEALTH_REASON_CODE_MAP[code];
  }),

  actions: {
    openModal() {
      let trackDashboardEvent = this.get('trackDashboardEvent');

      trackDashboardEvent('live_dashboard_stream_health', {
        action: 'click',
        target_name: 'stream_test'
      });

      this.set('isShowingStreamTest', true);
    },

    closeModal() {
      this.set('isShowingStreamTest', false);
    },

    onInspectorLinkClick() {
      window.open('https://inspector.twitch.tv');

      let trackDashboardEvent = this.get('trackDashboardEvent');

      trackDashboardEvent('live_dashboard_stream_health', {
        action: 'click',
        target_name: 'twitch_inspector'
      });
    }
  },

  _updateBitRate() {
    let ingest = this.get('ingest');

    ingest.getBitrate().then(response => {
      if (this.isDestroyed) { return; }

      if (!response || !response.Results || response.Results.length < 1) {
        this.set('bitrate', OFFLINE);
        this.set('bitrateData', null);
        this.set('isShowingGraph', false);
        return;
      }

      let results = response.Results;
      let bitrate = htmlSafe(`${ commatized(results[results.length - 1].Value.toFixed(0)) }kb/s`);
      let labels = [];
      let data = [];

      results.forEach(result => {
        labels.push(moment.unix(result.Timestamp).format('h:mm:ss'));
        data.push(result.Value.toFixed(0));
      });

      let bitrateData = {
        datasets: [{
          label: BITRATE,
            data: data,
          fill: true,
          lineTension: 0,
          borderColor: BITRATE_COLORS.value,
          backgroundColor: BITRATE_COLORS.fill,
          pointRadius: 0,
          pointBackgroundColor: BITRATE_COLORS.value,
          pointHoverRadius: 4,
          pointHoverBorderWidth: 2,
          pointHoverBorderColor: BITRATE_COLORS.border,
          pointHitRadius: 2
        }],
        labels: labels
      };

      this.set('bitrate', bitrate);
      this.set('bitrateData', bitrateData);
      this.set('isShowingGraph', true);
    }, () => {
      if (this.isDestroyed) { return; }

      this.set('isShowingGraph', false);
    });
  }
});
