/*
 * Copyright (C) 2020. Robert Bosch GmbH Copyright (C) 2020. Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { ElementRef } from '@angular/core';
import {
  BarController,
  BarElement,
  CategoryScale,
  Chart,
  ChartConfiguration,
  ChartData,
  CommonElementOptions,
  Filler,
  Legend,
  LegendItem,
  LinearScale,
  LineController,
  LineElement,
  LineOptions,
  LogarithmicScale,
  PointElement,
  PointOptions,
  TimeScale,
  Title,
  Tooltip
} from 'chart.js';
import { BOSCH_DDS_COLORS } from '@bci-web-core/core';
import 'chartjs-adapter-date-fns';
import { enGB } from 'date-fns/locale';

function mapDatasetsToLegendItems(data: ChartData, chart: Chart) {
  return data.datasets.map(
      (dataset, i): LegendItem => ({
        datasetIndex: i,
        text: dataset.label,
        fillStyle: (dataset as CommonElementOptions).borderColor,
        hidden: !chart.isDatasetVisible(i),
        lineCap: (dataset as LineOptions).borderCapStyle,
        lineDash: (dataset as LineOptions).borderDash,
        lineDashOffset: (dataset as LineOptions).borderDashOffset,
        lineJoin: (dataset as LineOptions).borderJoinStyle,
        lineWidth: (dataset as LineOptions).borderWidth,
        strokeStyle: 'rgba(0,0,0,0)',
        pointStyle: (dataset as PointOptions).pointStyle
      })
  );
}

export function createLineChart(chartContainer: ElementRef): Chart {
  registerChartType('line');
  const config: ChartConfiguration = {
    type: 'line',
    data: {
      datasets: []
    },
    options: {
      animation: false,
      maintainAspectRatio: false,
      responsive: true,
      plugins: {
        legend: {
          display: true,
          position: 'bottom',
          align: 'center',
          labels: {
            boxWidth: 11,
            font: {
              size: 14
            },
            color: BOSCH_DDS_COLORS.boschGray40,
            padding: 21,
            generateLabels: function (chart: Chart): LegendItem[] {
              const data = chart.data;
              return Array.isArray(data.datasets) ? mapDatasetsToLegendItems(data, chart) : [];
            }
          }
        },
        tooltip: {
          mode: 'index',
          intersect: false,
          position: 'nearest'
        },
        title: {
          display: false
        }
      },
      scales: {
        x: {
          type: 'time',
          time: {
            unit: 'second'
          },
          adapters: {
            date: {
              locale: enGB
            }
          },
          display: false,
          title: {
            display: false
          },
          ticks: {
            maxRotation: 0,
            autoSkip: true,
            autoSkipPadding: 8
          }
        },
        y: {
          display: true,
          title: {
            display: false
          },
          ticks: {
            padding: 8
          }
        }
      },
      elements: {
        point: {
          hitRadius: 16
        }
      }
    }
  };

  return new Chart(chartContainer.nativeElement, config);
}

export function createBarChart(chartContainer: ElementRef): Chart {
  registerChartType('bar');
  const config: ChartConfiguration = {
    type: 'bar',
    data: {
      labels: [], // dynamically assigned
      datasets: [
        {
          data: [], // dynamically assigned
          backgroundColor: [] // dynamically assigned
        }
      ]
    },
    options: {
      animation: false,
      responsive: true,
      maintainAspectRatio: false,
      aspectRatio: 1,
      scales: {
        x: {
          display: true,
          grid: {
            display: false
          },
          ticks: {
            autoSkip: false
          }
        },
        y: {
          display: true,
          grid: {
            display: true
          },
          ticks: {
            padding: 8
          }
        }
      },
      plugins: {
        legend: {
          display: false
        },
        tooltip: {
          enabled: false
        }
      },
      layout: {
        padding: {
          bottom: 20
        }
      }
    }
  };

  return new Chart(chartContainer.nativeElement, config);
}

export function registerChartBasics() {
  Chart.register(Legend, Tooltip, Title, TimeScale, LinearScale, LogarithmicScale, PointElement, LineElement);
}

export function registerChartType(type) {
  switch (type) {
    case 'line':
      Chart.register(LineController, Filler);
      break;
    case 'bar':
      Chart.register(BarController, BarElement, CategoryScale);
      break;
  }
}
