import {
  AdvancedProperty,
  AnalyticalScope,
  Behavior,
  DateTimeUtil,
  TimeScaleUnit,
  Visible
} from "@webbpm/base-package";
import {Chart} from "chart.js";
import {Moment} from "moment-timezone";
import {ChartPlugin} from "./ChartPlugin";
import {ChartUtils} from "../ChartUtils";
import {ErvuChartV2} from "../ErvuChartV2";

@AnalyticalScope(ErvuChartV2)
export class DarkBackgroundColorChartPlugin extends Behavior implements ChartPlugin {
  @Visible('false')
  id: string = 'dark-background-color';

  public dateFormat: string;
  public timeUnit: TimeScaleUnit;
  public lightness: number; // 0 - 100 для затемнения, для осветления > 100
  public dash: number;
  public space: number;
  @AdvancedProperty()
  public date: Date;

  /**
   * Затемнение цвета столбцов и добавление пунктира в линию для графика после текущей или заданной
   * даты
   */
  beforeDatasetsUpdate(chart: Chart, args?, options?): void {
    const doLightness: boolean = !!this.lightness || this.lightness === 0;
    const doDash: boolean = !!this.dash && !!this.space;
    const date: Date = this.date == null ? new Date() : this.date;
    const indexAxis = chart.config.options.indexAxis || 'x';
    const datasets = chart.config.data.datasets;

    if (doLightness) {
      datasets.forEach(dataset => {
        if (dataset.type === 'bar') {
          const backgroundColor = dataset.backgroundColor;
          if (typeof backgroundColor === 'string' && backgroundColor.length >= 7
              && backgroundColor.substr(0, 1) == '#') {
            const colorHsl: string = ChartUtils.hexToHsl(backgroundColor, this.lightness);
            if (colorHsl) {
              const dateFormat = this.dateFormat;
              const timeScaleUnit = this.timeUnit;
              dataset.backgroundColor = function (context) {
                const scaleIndex = context.raw ? context.raw[indexAxis] : undefined;
                const scaleDate: Date =
                    scaleIndex
                    ? DarkBackgroundColorChartPlugin.getScaleDate(
                        scaleIndex, dateFormat, timeScaleUnit)
                    : undefined;
                return scaleDate > date ? colorHsl : backgroundColor;
              }
            }
          }
        }
      })
    }

    if (doDash) {
      datasets.forEach(dataset => {
        if (dataset.type === 'line') {
          const borderDash: number[] = [this.dash, this.space];
          const dateFormat = this.dateFormat;
          const timeScaleUnit = this.timeUnit;
          Object.assign(dataset, {
            segment: {
              borderDash: function (context) {
                const scaleIndex = context.p1.raw[indexAxis];
                const scaleDate: Date = DarkBackgroundColorChartPlugin.getScaleDate(
                    scaleIndex, dateFormat, timeScaleUnit);
                return scaleDate > date ? borderDash : undefined;
              }
            }
          })
        }
      })
    }
  }

  private static getScaleDate(scaleIndex, dateFormat?: string,
                              timeScaleUnit?: TimeScaleUnit): Date | undefined {
    const moment: Moment = DateTimeUtil.parseDateWithFormat(
        scaleIndex, dateFormat ? dateFormat : DateTimeUtil.ISO_OFFSET_DATE_TIME);
    const endOfTimeUnit: Moment = moment.endOf(timeScaleUnit);
    return endOfTimeUnit ? endOfTimeUnit.toDate() : undefined;
  }
}
