import type { ChartConfiguration } from "chart.js";
import { ChartTypeBuilder } from "../../../registries/chart_registry";
import { WaterfallChartRuntime } from "../../../types/chart/waterfall_chart";
import { CommandResult } from "../../../types/commands";
import { ColorThemeName } from "../../../types/rendering";
import { AbstractChart } from "./abstract_chart";
import { CHART_COMMON_OPTIONS } from "./chart_ui_common";
import { getBarChartData } from "./runtime/chart_data_extractor";
import { getWaterfallDatasetAndLabels } from "./runtime/chartjs_dataset";
import { getChartLayout } from "./runtime/chartjs_layout";
import { getWaterfallChartLegend } from "./runtime/chartjs_legend";
import { getWaterfallChartScales } from "./runtime/chartjs_scales";
import { getWaterfallChartShowValues } from "./runtime/chartjs_show_values";
import { getChartTitle } from "./runtime/chartjs_title";
import { getWaterfallChartTooltip } from "./runtime/chartjs_tooltip";

export const WaterfallChart: ChartTypeBuilder<"waterfall"> = {
  sequence: 70,
  allowedDefinitionKeys: [
    ...AbstractChart.commonKeys,
    "dataSource",
    "legendPosition",
    "dataSetStyles",
    "verticalAxisPosition",
    "aggregated",
    "showSubTotals",
    "showConnectorLines",
    "firstValueAsSubtotal",
    "positiveValuesColor",
    "negativeValuesColor",
    "subTotalValuesColor",
    "zoomable",
    "axesDesign",
    "showValues",
  ],

  fromStrDefinition: (definition) => definition,

  toStrDefinition: (definition) => definition,

  copyInSheetId: (definition) => definition,

  duplicateInDuplicatedSheet: (definition) => definition,

  transformDefinition: (definition) => definition,

  validateDefinition: () => CommandResult.Success,

  updateRanges: (definition) => definition,

  getContextCreation: (definition) => definition,

  getFormulas: () => [],

  getDefinitionFromContextCreation(context, dataSourceBuilder) {
    return {
      background: context.background,
      dataSource: dataSourceBuilder.fromContextCreation(context),
      dataSetStyles: context.dataSetStyles ? context.dataSetStyles : {},
      aggregated: context.aggregated ?? false,
      legendPosition: context.legendPosition ?? "top",
      title: context.title || { text: "" },
      type: "waterfall",
      verticalAxisPosition: "left",
      showSubTotals: context.showSubTotals ?? false,
      showConnectorLines: context.showConnectorLines ?? true,
      firstValueAsSubtotal: context.firstValueAsSubtotal ?? false,
      axesDesign: context.axesDesign,
      showValues: context.showValues,
      zoomable: context.zoomable ?? false,
      humanize: context.humanize,
      annotationLink: context.annotationLink,
      annotationText: context.annotationText,
    };
  },

  getDefinitionForExcel: () => undefined,

  getRuntime(
    getters,
    definition,
    { extractData },
    sheetId,
    eventHandlers,
    colorThemeName: ColorThemeName
  ): WaterfallChartRuntime {
    const data = extractData();
    const chartData = getBarChartData(definition, data, getters, colorThemeName);

    const { labels, datasets } = getWaterfallDatasetAndLabels(definition, chartData);
    const config: ChartConfiguration = {
      type: "bar",
      data: {
        labels,
        datasets,
      },
      options: {
        ...CHART_COMMON_OPTIONS,
        layout: getChartLayout(definition, chartData),
        scales: getWaterfallChartScales(definition, chartData),
        plugins: {
          title: getChartTitle(definition, getters),
          legend: getWaterfallChartLegend(definition, chartData),
          tooltip: getWaterfallChartTooltip(definition, chartData),
          chartShowValuesPlugin: getWaterfallChartShowValues(definition, chartData),
          waterfallLinesPlugin: { showConnectorLines: definition.showConnectorLines },
          background: { color: chartData.background },
        },
        ...eventHandlers,
      },
    };

    return { chartJsConfig: config };
  },
};
