import type { ModelTypes } from "../../model/interfaces/common.js";
import type { WebChartStackedKinds } from "../../spec/chart-object-literals.js";
import type { WebChartDataTypes, WebChartGenericDataItem, WebChartHistogramDataItem, WebChartScatterplotDataItem } from "../../spec/data-source.js";
import type { IFeatureLayer, ISimpleFillSymbol, ISimpleLineSymbol, ISimpleMarkerSymbol } from "../../spec/rest-js-types.js";
import type { CategoryFormatOptions, DateTimeFormatOptions, NumberFormatOptions, WebBoxPlot, WebChart, WebChartBarChartSeries, WebChartBoxPlotSeries, WebChartHeatChartSeries, WebChartLineChartSeries, WebChartRadarChartSeries, WebChartSeries, WebChartTextSymbol, WebGaugeChart, WebHeatChart } from "../../spec/web-chart.js";
import type { ChartTypes } from "../misc/index.js";
import type { ChartConfig } from "../types/index.js";

/** @internal */
export type StringIndexable<T> = Record<string, unknown>
  & T;

/**
 * Web chart series with rotated property
 *
 * @internal
 */
export type WebChartSeriesWithRotatedProp = WebChartSeries
  & {
  rotated?: boolean;
};

/**
 * Check if the chart config supports rotation or not.
 *
 * @param config - the chart config
 * @internal
 */
export function isRotationSupported(config: WebChart): config is WebChart & { series: WebChartSeriesWithRotatedProp[]; };

/**
 * Web chart series with stackedType property
 *
 * @internal
 */
export type WebChartSeriesWithStackedTypeProp = WebChartSeries
  & {
  stackedType?: WebChartStackedKinds;
};

/**
 * Check if the chart config supports rotation or not.
 *
 * @param config - the chart config
 * @internal
 */
export function isStackedTypeSupported(config: WebChart): config is WebChart & { series: WebChartSeriesWithStackedTypeProp[]; };

/**
 * Type guard for `ISimpleFillSymbol`
 *
 * @param symbol
 * @internal
 */
export function isSFS(symbol: any): symbol is ISimpleFillSymbol;

/**
 * Type guard for `ISimpleLineSymbol`
 *
 * @param symbol
 * @internal
 */
export function isSLS(symbol: any): symbol is ISimpleLineSymbol;

/**
 * Type guard for `ISimpleMarkerSymbol`
 *
 * @param symbol
 * @internal
 */
export function isSMS(symbol: any): symbol is ISimpleMarkerSymbol;

/**
 * Type guard for `WebChartTextSymbol`
 *
 * @param symbol
 * @internal
 */
export function isWebChartTextSymbol(symbol: any): symbol is WebChartTextSymbol;

/**
 * Determines if the provided `config` has a `iLayer` property.
 *
 * @param config
 * @internal
 */
export function hasILayer<T extends ModelTypes>(config: ChartConfig<T> | undefined): config is ChartConfig<T, T extends "boxPlot" ? WebBoxPlot : T extends "gauge" ? WebGaugeChart : T extends "heatChart" ? WebHeatChart : WebChart>;

/**
 * @param config
 * @internal
 */
export function hasILayer(config: WebChart | undefined): config is WebChart & { iLayer: IFeatureLayer; };

/**
 * @param config
 * @internal
 */
export function hasILayer<T extends ModelTypes>(config: ChartConfig<T> | undefined): unknown;

/**
 * Determines if the provided `config` is the specified chart type `T`.
 *
 * @param config - The chart config to check.
 * @param chartType - The chart type to check against.
 * @internal
 */
export function isChartType<T extends ChartConfig>(config: WebChart | undefined, chartType: ChartTypes | undefined): config is T;

/**
 * Determines if the series is a box plot series.
 *
 * @param series - The series to check.
 * @internal
 */
export function isBoxPlotSeries(series: WebChartSeries | undefined): series is WebChartBoxPlotSeries;

/**
 * Determines if the series is a line chart series.
 *
 * @param series - The series to check.
 * @internal
 */
export function isLineChartSeries(series: WebChartSeries | undefined): series is WebChartLineChartSeries;

/**
 * Determines if the series is a radar chart series.
 *
 * @param series - The series to check.
 * @internal
 */
export function isRadarChartSeries(series: WebChartSeries | undefined): series is WebChartRadarChartSeries;

/**
 * Determines if the series is a bar chart series.
 *
 * @param series - The series to check.
 * @internal
 */
export function isBarChartSeries(series: WebChartSeries | undefined): series is WebChartBarChartSeries;

/**
 * Determines if the series is a heat chart series.
 *
 * @param series - | undefined} series The series to check.
 * @internal
 */
export function isHeatChartSeries(series: WebChartSeries | undefined): series is WebChartHeatChartSeries;

/**
 * Type guard to check if the series is a `BarChartSeries`.
 *
 * @param series - The series to check.
 * @internal
 */
export function isBarChartSeriesArray(series: WebChartSeries[]): series is WebChartBarChartSeries[];

/**
 * Type guard to check if the series is a `LineChartSeries`.
 *
 * @param series - The series to check.
 * @internal
 */
export function isLineChartSeriesArray(series: WebChartSeries[]): series is WebChartLineChartSeries[];

/**
 * Type guard to check if the series is a `RadarChartSeries`.
 *
 * @param series - The series to check.
 * @internal
 */
export function isRadarChartSeriesArray(series: WebChartSeries[]): series is WebChartRadarChartSeries[];

/**
 * Type guard to check if the series is a HeatChartSeries.
 *
 * @param series - series - The series to check.
 * @returns {series is WebChartHeatChartSeries[]}
 * @internal
 */
export function isHeatChartSeriesArray(series: WebChartSeries[]): series is WebChartHeatChartSeries[];

/**
 * Determines if the series array is of type box plot series.
 *
 * @param series - The series to check.
 * @internal
 */
export function isBoxPlotSeriesArray(series: WebChartSeries[]): series is WebChartBoxPlotSeries[];

/**
 * Type guard for axis format being `NumberFormatOptions`
 *
 * @param valueFormat - valueFormat to check
 * @internal
 */
export function isNumberFormatOptions(valueFormat: CategoryFormatOptions | DateTimeFormatOptions | NumberFormatOptions | undefined): valueFormat is NumberFormatOptions;

/**
 * Type guard for `WebChartDataTypes` being `WebChartHistogramDataItem`.
 *
 * @param data - dataItem to check
 * @internal
 */
export function isWebChartHistogramDataItemOrUndefined(data: WebChartDataTypes | undefined): data is WebChartHistogramDataItem | undefined;

/**
 * Type guard for `WebChartDataTypes` being `WebChartGenericDataItem`.
 *
 * @param data - dataItem to check
 * @internal
 */
export function isWebChartGenericDataItemOrUndefined(data: WebChartDataTypes | undefined): data is WebChartGenericDataItem | undefined;

/**
 * Type guard for `WebChartDataTypes` being `WebChartScatterplotDataItem`.
 *
 * @param data - dataItem to check
 * @internal
 */
export function isWebChartScatterplotDataItemOrUndefined(data: WebChartDataTypes | undefined): data is WebChartScatterplotDataItem | undefined;

/**
 * TODO: Once charts-shared-utils is merged into charts-components, we can create a more official version of this type-guard using the AmCharts types.
 *
 * @param axisDataItem
 * @internal
 */
export function isValueAxisDataItem<T extends object>(axisDataItem: T): axisDataItem is T & { value: number; };