import type { ChartModelBase } from "../chart-model/chart-model-base.js";
import type { HeatChartModel } from "../heat-chart-model/heat-chart-model.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 { ChartModel } from "../chart-model/chart-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 { ModelTypes, ModelOfType } from "../interfaces/common.js";
import type { LineChartModel } from "../line-chart-model/line-chart-model.js";
import type { PieChartLegendModel } from "../pie-chart-model/pie-chart-legend-model.js";
import type { PieChartModel } from "../pie-chart-model/pie-chart-model.js";
import type { ScatterplotModel } from "../scatterplot-model/scatterplot-model.js";
import type { SerialChartModel } from "../serial-chart-model/serial-chart-model.js";
import type { WebChart } from "../../spec/web-chart.js";
import type { ModelWithMultiAxes } from "../mixins/model-with-multi-axes.js";
import type { ModelWithLineMarkerStyling } from "../mixins/model-with-line-marker-styling.js";
import type { ModelWithTooltips } from "../mixins/model-with-tooltips.js";
import type { ModelWithGuides } from "../mixins/model-with-guides.js";
import type { ModelWithXGuides } from "../mixins/model-with-x-guides.js";
import type { ModelWithYGuides } from "../mixins/model-with-y-guides.js";
import type { ModelWithLegend } from "../mixins/model-with-legend.js";
import type { ModelWithTemporalBinning } from "../mixins/model-with-temporal-binning.js";

/**
 * Determines if the provided model or config is a `ChartModel`.
 *
 * @param model - The model to check.
 */
export function isChartModel(model: ChartModel | WebChart | undefined): model is ChartModel;

/**
 * Determines if the provided `model` is of type `BarChartModel`.
 *
 * @param model - The model to check.
 */
export function isBarChartModel(model: ChartModelBase | undefined): model is BarChartModel;

/**
 * Determines if the provided `model` is of type `LineChartModel`.
 *
 * @param model - The model to check.
 */
export function isLineChartModel(model: ChartModelBase | undefined): model is LineChartModel;

/**
 * Determines if the provided `model` is of type `ComboBarLineChartModel`.
 *
 * @param model - The model to check.
 */
export function isComboBarLineChartModel(model: ChartModelBase | undefined): model is ComboBarLineChartModel;

/**
 * Determines if the provided `model` is of type `SerialChartModel`.
 * This includes LineSeries, BarSeries, ComboLineAndBarSeries, and RadarSeries.
 *
 * @param model - The model to check.
 */
export function isSerialChartModel(model: ChartModelBase | undefined): model is SerialChartModel;

/**
 * Determines if the provided `model` is of type `PieChartModel`.
 *
 * @param model - The model to check.
 */
export function isPieChartModel(model: ChartModelBase | undefined): model is PieChartModel;

/**
 * Determines if the provided `model` is of type `BoxPlotModel`.
 *
 * @param model - The model to check.
 */
export function isBoxPlotModel(model: ChartModelBase | undefined): model is BoxPlotModel;

/**
 * Determines if the provided `model` is of type `ScatterplotModel`.
 *
 * @param model - The model to check.
 */
export function isScatterplotModel(model: ChartModelBase | undefined): model is ScatterplotModel;

/**
 * Determines if the provided `model` is of type `HistogramModel`.
 *
 * @param model - The model to check.
 */
export function isHistogramModel(model: ChartModelBase | undefined): model is HistogramModel;

/**
 * Determines if the provided `model` is of type `HeatChartModel`.
 *
 * @param model - The model to check.
 */
export function isHeatChartModel(model: ChartModelBase | undefined): model is HeatChartModel;

/**
 * Determines if the provided `model` is of type `GaugeModel`.
 *
 * @param model - The model to check.
 */
export function isGaugeModel(model: ChartModelBase | undefined): model is GaugeModel;

/**
 * Type guard for ModelWithMultiAxes
 *
 * @param model
 */
export function isModelWithMultiAxes(model: ChartModel | undefined): model is ModelWithMultiAxes;

/**
 * Type guard for ModelWithLineMarkerStyling
 *
 * @param model
 */
export function isModelWithLineMarkerStyling(model: ChartModel | undefined): model is ModelWithLineMarkerStyling;

/**
 * Type guard for ModelWithTooltips
 *
 * @param model
 */
export function isModelWithTooltips(model: ChartModel | undefined): model is ModelWithTooltips;

/**
 * Determines if the provided `model` is of type `ModelWithGuides`.
 *
 * @param model - The model to check.
 */
export function isModelWithGuides(model: ChartModel | undefined): model is ModelWithGuides;

/**
 * Determines if the provided `model` is of type `ModelWithXGuides`.
 *
 * @param model - The model to check.
 */
export function isModelWithXGuides(model: ChartModel | undefined): model is ModelWithXGuides;

/**
 * Determines if the provided `model` is of type `ModelWithYGuides`.
 *
 * @param model - The model to check.
 */
export function isModelWithYGuides(model: ChartModel | undefined): model is ModelWithYGuides;

/**
 * Determines if the provided `model` is of type `ModelWithLegend`.
 *
 * @param model - The model to check.
 */
export function isModelWithLegend(model: ChartModel | undefined): model is ModelWithLegend;

/**
 * Determines if the provided `model` is of type `PieChartLegendModel`.
 *
 * @param model - The model to check.
 */
export function isPieChartLegendModel(model: ChartModel | undefined): model is PieChartLegendModel;

/**
 * Determines if the provided `model` is of type `ModelWithTemporalBinning`.
 *
 * @param model - The model to check.
 */
export function isModelWithTemporalBinning(model: ChartModel | undefined): model is ModelWithTemporalBinning;

/**
 * Determines if the provided model's type matches the `type` argument.
 *
 * @param model - The model to check.
 * @param type
 */
export function isModelOfType<T extends ModelTypes | undefined>(model: ChartModel | undefined, type: T): model is ModelOfType<T>;