import type { SupportedLayer } from "../../interfaces.js";
import type { WebChartTypes } from "../../spec/chart-object-literals.js";
import type { IField } from "../../spec/rest-js-types.js";
import type { WebChartBarChartSeries, WebChartBoxPlotSeries, WebChartGaugeSeries, WebChartHeatChartSeries, WebChartHistogramSeries, WebChartLineChartSeries, WebChartPieChartSeries, WebChartRadarChartSeries, WebChartScatterplotSeries } from "../../spec/web-chart.js";
import type { SupportedChartSeries } from "../../utils/types/index.js";
import type { BarChartModel } from "../bar-chart-model/bar-chart-model.js";
import type { BoxPlotModel } from "../box-plot-model/box-plot-model.js";
import type { ComboBarLineChartModel } from "../combo-bar-line-chart-model/combo-bar-line-chart-model.js";
import type { GaugeModel } from "../gauge-model/gauge-model.js";
import type { HistogramModel } from "../histogram-model/histogram-model.js";
import type { LineChartModel } from "../line-chart-model/line-chart-model.js";
import type { PieChartModel } from "../pie-chart-model/pie-chart-model.js";
import type { RadarChartModel } from "../radar-chart-model/radar-chart-model.js";
import type { ScatterplotModel } from "../scatterplot-model/scatterplot-model.js";

export const customSortString: "customSort";

export const SerialChartDataSortingKinds: {
    readonly xAxisAsc: "xAxisAsc";
    readonly xAxisDesc: "xAxisDesc";
    readonly yAxisAsc: "yAxisAsc";
    readonly yAxisDesc: "yAxisDesc";
    readonly customSort: "customSort";
};

export type SerialChartDataSortingKinds = (typeof SerialChartDataSortingKinds)[keyof typeof SerialChartDataSortingKinds];

export const BoxPlotDataSortingKinds: {
    readonly xAxisAsc: "xAxisAsc";
    readonly xAxisDesc: "xAxisDesc";
    readonly meanAsc: "meanAsc";
    readonly meanDesc: "meanDesc";
    readonly medianAsc: "medianAsc";
    readonly medianDesc: "medianDesc";
    readonly customSort: "customSort";
};

export type BoxPlotDataSortingKinds = (typeof BoxPlotDataSortingKinds)[keyof typeof BoxPlotDataSortingKinds];

export const HeatChartDataSortingKinds: {
    readonly Asc: "Asc";
    readonly Desc: "Desc";
    readonly customSort: "customSort";
};

export type HeatChartDataSortingKinds = (typeof HeatChartDataSortingKinds)[keyof typeof HeatChartDataSortingKinds];

export const PieChartDataSortingKinds: {
    readonly labelAsc: "labelAsc";
    readonly labelDesc: "labelDesc";
    readonly valueAsc: "valueAsc";
    readonly valueDesc: "valueDesc";
    readonly customSort: "customSort";
};

export type PieChartDataSortingKinds = (typeof PieChartDataSortingKinds)[keyof typeof PieChartDataSortingKinds];

export const PieChartDataModes: {
    readonly Category: "category";
    readonly Fields: "fields";
};

export type PieChartDataModes = (typeof PieChartDataModes)[keyof typeof PieChartDataModes];

export const PieChartSlicesDisplay: {
    readonly Category: "category";
    readonly Value: "value";
    readonly Percentage: "percentage";
    readonly Both: "both";
};

export type PieChartSlicesDisplay = (typeof PieChartSlicesDisplay)[keyof typeof PieChartSlicesDisplay];

export const FormatKeys: {
    readonly TextElements: "textElements";
    readonly XAxisTitle: "xAxisTitle";
    readonly YAxisTitle: "yAxisTitle";
    readonly AxisLabels: "axisLabels";
    readonly GuideLabels: "guideLabels";
    readonly Title: "title";
    readonly LegendText: "legendText";
    readonly LegendTitle: "legendTitle";
    readonly Description: "description";
    readonly DataLabels: "dataLabels";
    readonly Background: "background";
    readonly LeaderLines: "leaderLines";
    readonly AxisLines: "axisLines";
    readonly GridLines: "gridLines";
};

export type FormatKeys = (typeof FormatKeys)[keyof typeof FormatKeys];

export const LineFormatKeys: {
    readonly AxisLines: "axisLines";
    readonly GridLines: "gridLines";
    readonly LeaderLines: "leaderLines";
};

export type LineFormatKeys = (typeof LineFormatKeys)[keyof typeof LineFormatKeys];

export const TextFormatKeys: {
    readonly Title: "title";
    readonly XAxisTitle: "xAxisTitle";
    readonly YAxisTitle: "yAxisTitle";
    readonly AxisLabels: "axisLabels";
    readonly GuideLabels: "guideLabels";
    readonly LegendText: "legendText";
    readonly LegendTitle: "legendTitle";
    readonly Description: "description";
    readonly DataLabels: "dataLabels";
};

export type TextFormatKeys = (typeof TextFormatKeys)[keyof typeof TextFormatKeys];

export const ColorFormatKeys: { readonly Background: "background"; };

export type ColorFormatKeys = (typeof ColorFormatKeys)[keyof typeof ColorFormatKeys];

/** Axis orientation of the guide. */
export const GuideOrientation: {
    readonly X: "x";
    readonly Y: "y";
};

export type GuideOrientation = (typeof GuideOrientation)[keyof typeof GuideOrientation];

export interface SplitByFieldInfos {
  categoriesArray: (number | string)[];
  splitByFieldType?: string;
  numericalField: string;
}

export interface PieSeriesDisplayOptions {
  displayCategoryOnDataLabel: boolean;
  displayNumericValueOnDataLabel: boolean;
  displayPercentageOnDataLabel: boolean;
  displayNumericValue: boolean;
  displayPercentage: boolean;
}

export interface LayerInfo {
  /** Layer used for this bar chart. */
  layer: SupportedLayer;
  /** Fields information for the layer. */
  layerFieldsInfo: IField[];
  /** Object ID field name for the layer. */
  objectIdField: string;
}

export const ModelTypes: {
    readonly BarChart: "barChart";
    readonly LineChart: "lineChart";
    readonly ComboBarLineChart: "comboBarLineChart";
    readonly BoxPlot: "boxPlot";
    readonly PieChart: "pieChart";
    readonly Scatterplot: "scatterplot";
    readonly Histogram: "histogram";
    readonly Gauge: "gauge";
    readonly RadarChart: "radarChart";
    readonly HeatChart: "heatChart";
};

export type ModelTypes = (typeof ModelTypes)[keyof typeof ModelTypes];

/** @internal */
export type ModelTypeToSeriesType<T extends ModelTypes> = T extends typeof ModelTypes.BarChart ? WebChartBarChartSeries : T extends typeof ModelTypes.LineChart ? WebChartLineChartSeries : T extends typeof ModelTypes.ComboBarLineChart ? WebChartBarChartSeries | WebChartLineChartSeries : T extends typeof ModelTypes.BoxPlot ? WebChartBoxPlotSeries | WebChartLineChartSeries : T extends typeof ModelTypes.PieChart ? WebChartPieChartSeries : T extends typeof ModelTypes.Scatterplot ? WebChartScatterplotSeries : T extends typeof ModelTypes.Histogram ? WebChartHistogramSeries : T extends typeof ModelTypes.Gauge ? WebChartGaugeSeries : T extends typeof ModelTypes.RadarChart ? WebChartRadarChartSeries : T extends typeof ModelTypes.HeatChart ? WebChartHeatChartSeries : SupportedChartSeries;

/** @internal */
export type SeriesTypeToChartType<T extends SupportedChartSeries> = T extends WebChartBarChartSeries ? typeof WebChartTypes.BarSeries : T extends WebChartLineChartSeries ? typeof WebChartTypes.LineSeries : T extends WebChartBoxPlotSeries ? typeof WebChartTypes.BoxPlotSeries : T extends WebChartPieChartSeries ? typeof WebChartTypes.PieSeries : T extends WebChartScatterplotSeries ? typeof WebChartTypes.ScatterSeries : T extends WebChartHistogramSeries ? typeof WebChartTypes.HistogramSeries : T extends WebChartGaugeSeries ? typeof WebChartTypes.GaugeSeries : T extends WebChartRadarChartSeries ? typeof WebChartTypes.RadarSeries : T extends WebChartHeatChartSeries ? typeof WebChartTypes.HeatSeries : never;

/** @internal */
export type ModelOfType<T> = T extends typeof ModelTypes.BoxPlot ? BoxPlotModel : T extends typeof ModelTypes.LineChart ? LineChartModel : T extends typeof ModelTypes.ComboBarLineChart ? ComboBarLineChartModel : T extends typeof ModelTypes.PieChart ? PieChartModel : T extends typeof ModelTypes.Scatterplot ? ScatterplotModel : T extends typeof ModelTypes.Histogram ? HistogramModel : T extends typeof ModelTypes.Gauge ? GaugeModel : T extends typeof ModelTypes.RadarChart ? RadarChartModel : T extends typeof ModelTypes.HeatChart ? never : BarChartModel;