import type { ScaleBand, ScaleLinear, ScaleLogarithmic, ScaleOrdinal, ScalePoint, ScalePower, ScaleSequential, ScaleThreshold, ScaleTime } from '@mui/x-charts-vendor/d3-scale';
import { SxProps } from '@mui/system/styleFunctionSx';
import { type MakeOptional, MakeRequired } from '@mui/x-internals/types';
import { ChartsAxisClasses } from "../ChartsAxis/axisClasses.js";
import type { TickParams } from "../hooks/useTicks.js";
import { ChartsTextProps } from "../ChartsText/index.js";
import { ContinuousColorConfig, OrdinalColorConfig, PiecewiseColorConfig } from "./colorMapping.js";
export type AxisId = string | number;
export type D3Scale<Domain extends {
  toString(): string;
} = number | Date | string, Range = number, Output = number> = ScaleBand<Domain> | ScaleLogarithmic<Range, Output> | ScalePoint<Domain> | ScalePower<Range, Output> | ScaleTime<Range, Output> | ScaleLinear<Range, Output>;
export type D3ContinuousScale<Range = number, Output = number> = ScaleLogarithmic<Range, Output> | ScalePower<Range, Output> | ScaleTime<Range, Output> | ScaleLinear<Range, Output>;
export interface ChartsAxisSlots {
  /**
   * Custom component for the axis main line.
   * @default 'line'
   */
  axisLine?: React.JSXElementConstructor<React.SVGAttributes<SVGPathElement>>;
  /**
   * Custom component for the axis tick.
   * @default 'line'
   */
  axisTick?: React.JSXElementConstructor<React.SVGAttributes<SVGPathElement>>;
  /**
   * Custom component for tick label.
   * @default ChartsText
   */
  axisTickLabel?: React.JSXElementConstructor<ChartsTextProps>;
  /**
   * Custom component for axis label.
   * @default ChartsText
   */
  axisLabel?: React.JSXElementConstructor<ChartsTextProps>;
}
export interface ChartsAxisSlotProps {
  axisLine?: Partial<React.SVGAttributes<SVGPathElement>>;
  axisTick?: Partial<React.SVGAttributes<SVGPathElement>>;
  axisTickLabel?: Partial<ChartsTextProps>;
  axisLabel?: Partial<ChartsTextProps>;
}
export interface ChartsAxisProps extends TickParams {
  /**
   * The id of the axis to render.
   * If undefined, it will be the first defined axis.
   */
  axisId?: AxisId;
  /**
   * If true, the axis line is disabled.
   * @default false
   */
  disableLine?: boolean;
  /**
   * If true, the ticks are disabled.
   * @default false
   */
  disableTicks?: boolean;
  /**
   * The fill color of the axis text.
   * @default 'currentColor'
   */
  fill?: string;
  /**
   * The style applied to ticks text.
   */
  tickLabelStyle?: ChartsTextProps['style'];
  /**
   * The style applied to the axis label.
   */
  labelStyle?: ChartsTextProps['style'];
  /**
   * Defines which ticks get its label displayed. Its value can be:
   * - 'auto' In such case, labels are displayed if they do not overlap with the previous one.
   * - a filtering function of the form (value, index) => boolean. Warning: the index is tick index, not data ones.
   * @default 'auto'
   */
  tickLabelInterval?: 'auto' | ((value: any, index: number) => boolean);
  /**
   * The label of the axis.
   */
  label?: string;
  /**
   * The stroke color of the axis line.
   * @default 'currentColor'
   */
  stroke?: string;
  /**
   * The size of the ticks.
   * @default 6
   */
  tickSize?: number;
  /**
   * Override or extend the styles applied to the component.
   */
  classes?: Partial<ChartsAxisClasses>;
  /**
   * Overridable component slots.
   * @default {}
   */
  slots?: Partial<ChartsAxisSlots>;
  /**
   * The props used for each component slot.
   * @default {}
   */
  slotProps?: Partial<ChartsAxisSlotProps>;
  sx?: SxProps;
}
export interface ChartsYAxisProps extends ChartsAxisProps {
  axis?: 'y';
}
export interface ChartsXAxisProps extends ChartsAxisProps {
  axis?: 'x';
  /**
   * The minimum gap in pixels between two tick labels.
   * If two tick labels are closer than this minimum gap, one of them will be hidden.
   * @default 4
   */
  tickLabelMinGap?: number;
}
type AxisSideConfig<AxisProps extends ChartsAxisProps> = AxisProps extends ChartsXAxisProps ? {
  /**
   * Position of the axis.
   *
   * When set, the space for the axis is reserved, even if the axis is not displayed due to missing data.
   *
   * Set to 'none' to hide the axis.
   *
   * The first axis in the list will always have a default position.
   */
  position?: 'top' | 'bottom' | 'none';
  /**
   * The height of the axis.
   * @default 30
   */
  height?: number;
} : AxisProps extends ChartsYAxisProps ? {
  /**
   * Position of the axis.
   *
   * When set, the space for the axis is reserved, even if the axis is not displayed due to missing data.
   *
   * Set to 'none' to hide the axis.
   *
   * The first axis in the list will always have a default position.
   */
  position?: 'left' | 'right' | 'none';
  /**
   * The width of the axis.
   * @default 30
   */
  width?: number;
} : {
  position?: 'top' | 'bottom' | 'left' | 'right' | 'none';
  height?: number;
  width?: number;
};
export interface ChartsRotationAxisProps extends ChartsAxisProps {
  /**
   * The start angle (in deg).
   */
  startAngle?: number;
  /**
   * The end angle (in deg).
   */
  endAngle?: number;
  /**
   * The gap between the axis and the label.
   */
  labelGap?: number;
}
export interface ChartsRadiusAxisProps extends ChartsAxisProps {
  /**
   * The minimal radius.
   */
  minRadius?: number;
  /**
   * The maximal radius.
   */
  maxRadius?: number;
}
export type ScaleName = keyof AxisScaleConfig;
export type ContinuousScaleName = 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc';
export interface AxisScaleConfig {
  band: {
    scaleType: 'band';
    scale: ScaleBand<number | Date | string>;
    /**
     * The ratio between the space allocated for padding between two categories and the category width.
     * 0 means no gap, and 1 no data.
     * @default 0.2
     */
    categoryGapRatio: number;
    /**
     * The ratio between the width of a bar, and the gap between two bars.
     * 0 means no gap, and 1 no bar.
     * @default 0.1
     */
    barGapRatio: number;
    colorMap?: OrdinalColorConfig | ContinuousColorConfig | PiecewiseColorConfig;
  } & Pick<TickParams, 'tickPlacement' | 'tickLabelPlacement'>;
  point: {
    scaleType: 'point';
    scale: ScalePoint<number | Date | string>;
    colorMap?: OrdinalColorConfig | ContinuousColorConfig | PiecewiseColorConfig;
  };
  log: {
    scaleType: 'log';
    scale: ScaleLogarithmic<number, number>;
    colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
  };
  pow: {
    scaleType: 'pow';
    scale: ScalePower<number, number>;
    colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
  };
  sqrt: {
    scaleType: 'sqrt';
    scale: ScalePower<number, number>;
    colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
  };
  time: {
    scaleType: 'time';
    scale: ScaleTime<number, number>;
    colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
  };
  utc: {
    scaleType: 'utc';
    scale: ScaleTime<number, number>;
    colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
  };
  linear: {
    scaleType: 'linear';
    scale: ScaleLinear<number, number>;
    colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
  };
}
/**
 * Use this type instead of `AxisScaleConfig` when the values
 * shouldn't be provided by the user.
 */
export interface AxisScaleComputedConfig {
  band: {
    colorScale?: ScaleOrdinal<string | number | Date, string, string | null> | ScaleOrdinal<number, string, string | null> | ScaleSequential<string, string | null> | ScaleThreshold<number | Date, string | null>;
  };
  point: {
    colorScale?: ScaleOrdinal<string | number | Date, string, string | null> | ScaleOrdinal<number, string, string | null> | ScaleSequential<string, string | null> | ScaleThreshold<number | Date, string | null>;
  };
  log: {
    colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
  };
  pow: {
    colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
  };
  sqrt: {
    colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
  };
  time: {
    colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number | Date, string | null>;
  };
  utc: {
    colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number | Date, string | null>;
  };
  linear: {
    colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
  };
}
export type AxisValueFormatterContext<S extends ScaleName = ScaleName> = {
  /**
   * Location indicates where the value will be displayed.
   * - `'tick'` The value is displayed on the axis ticks.
   * - `'tooltip'` The value is displayed in the tooltip when hovering the chart.
   * - `'legend'` The value is displayed in the legend when using color legend.
   */
  location: 'legend';
} | {
  /**
   * Location indicates where the value will be displayed.
   * - `'tick'` The value is displayed on the axis ticks.
   * - `'tooltip'` The value is displayed in the tooltip when hovering the chart.
   * - `'legend'` The value is displayed in the legend when using color legend.
   */
  location: 'tick' | 'tooltip';
  /**
   * The d3-scale instance associated to the axis.
   */
  scale: AxisScaleConfig[S]['scale'];
};
/**
 * Config that is shared between cartesian and polar axes.
 */
type CommonAxisConfig<S extends ScaleName = ScaleName, V = any> = {
  /**
   * ID used to identify the axis.
   *
   * The ID must be unique across all axes in this chart.
   */
  id: AxisId;
  /**
   * The minimal value of the domain.
   * If not provided, it gets computed to display the entire chart data.
   */
  min?: number | Date;
  /**
   * The maximal value of the domain.
   * If not provided, it gets computed to display the entire chart data.
   */
  max?: number | Date;
  /**
   * The data used by `'band'` and `'point'` scales.
   */
  data?: readonly V[];
  /**
   * The key used to retrieve `data` from the `dataset` prop.
   */
  dataKey?: string;
  /**
   * Formats the axis value.
   * @param {V} value The value to format.
   * @param {AxisValueFormatterContext} context The rendering context of the value.
   * @returns {string} The string to display.
   */
  valueFormatter?: <TScaleName extends S>(value: V, context: AxisValueFormatterContext<TScaleName>) => string;
  /**
   * If `true`, hide this value in the tooltip
   */
  hideTooltip?: boolean;
  /**
   * If `true`, Reverse the axis scaleBand.
   */
  reverse?: boolean;
  /**
   * Defines the axis scale domain based on the min/max values of series linked to it.
   * - 'nice': Rounds the domain at human friendly values.
   * - 'strict': Set the domain to the min/max value provided. No extra space is added.
   * - function: Receives the calculated extremums as parameters, and should return the axis domain.
   */
  domainLimit?: 'nice' | 'strict' | ((min: number, max: number) => {
    min: number;
    max: number;
  });
  /**
   * If `true`, the axis will be ignored by the tooltip with `trigger='axis'`.
   */
  ignoreTooltip?: boolean;
};
export type PolarAxisConfig<S extends ScaleName = ScaleName, V = any, AxisProps extends ChartsAxisProps = ChartsRotationAxisProps | ChartsRadiusAxisProps> = {
  /**
   * The offset of the axis in pixels. It can be used to move the axis from its default position.
   * X-axis: A top axis will move up, and a bottom axis will move down.
   * Y-axis: A left axis will move left, and a right axis will move right.
   * @default 0
   */
  offset?: number;
} & CommonAxisConfig<S, V> & Omit<Partial<AxisProps>, 'axisId'> & Partial<Omit<AxisScaleConfig[S], 'scale'>> & AxisConfigExtension;
/**
 * Use this type for advanced typing. For basic usage, use `XAxis`, `YAxis`, `RotationAxis` or `RadiusAxis`.
 */
export type AxisConfig<S extends ScaleName = ScaleName, V = any, AxisProps extends ChartsAxisProps = ChartsXAxisProps | ChartsYAxisProps> = {
  /**
   * The offset of the axis in pixels. It can be used to move the axis from its default position.
   * X-axis: A top axis will move up, and a bottom axis will move down.
   * Y-axis: A left axis will move left, and a right axis will move right.
   * @default 0
   */
  offset?: number;
} & CommonAxisConfig<S, V> & Omit<Partial<AxisProps>, 'axisId'> & Partial<Omit<AxisScaleConfig[S], 'scale'>> & AxisSideConfig<AxisProps> & TickParams & AxisConfigExtension;
export interface AxisConfigExtension {}
export type PolarAxisDefaultized<S extends ScaleName = ScaleName, V = any, AxisProps extends ChartsAxisProps = ChartsRotationAxisProps | ChartsRadiusAxisProps> = Omit<PolarAxisConfig<S, V, AxisProps>, 'scaleType'> & AxisScaleConfig[S] & AxisScaleComputedConfig[S] & {
  /**
   * If true, the contents of the axis will be displayed by a tooltip with `trigger='axis'`.
   */
  triggerTooltip?: boolean;
};
export type ComputedAxis<S extends ScaleName = ScaleName, V = any, AxisProps extends ChartsAxisProps = ChartsXAxisProps | ChartsYAxisProps> = MakeRequired<Omit<AxisConfig<S, V, AxisProps>, 'scaleType'>, 'offset'> & AxisScaleConfig[S] & AxisScaleComputedConfig[S] & {
  /**
   * An indication of the expected number of ticks.
   */
  tickNumber: number;
  /**
   * Indicate if the axis should be consider by a tooltip with `trigger='axis'`.
   */
  triggerTooltip?: boolean;
} & (AxisProps extends ChartsXAxisProps ? MakeRequired<AxisSideConfig<AxisProps>, 'height'> : AxisProps extends ChartsYAxisProps ? MakeRequired<AxisSideConfig<AxisProps>, 'width'> : AxisSideConfig<AxisProps>);
export type ComputedXAxis<S extends ScaleName = ScaleName, V = any> = ComputedAxis<S, V, ChartsXAxisProps>;
export type ComputedYAxis<S extends ScaleName = ScaleName, V = any> = ComputedAxis<S, V, ChartsYAxisProps>;
export declare function isBandScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'band'> & {
  scaleType: 'band';
};
export declare function isPointScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'point'> & {
  scaleType: 'point';
};
/**
 * The data format returned by onAxisClick.
 */
export interface ChartsAxisData {
  /**
   * The index in the axis' data property.
   */
  dataIndex: number;
  /**
   * Tha value associated to the axis item.
   */
  axisValue: number | Date | string;
  /**
   * The mapping of series ids to their value for this particular axis index.
   */
  seriesValues: Record<string, number | null | undefined>;
}
export type XAxis<S extends ScaleName = ScaleName, V = any> = S extends ScaleName ? MakeOptional<AxisConfig<S, V, ChartsXAxisProps>, 'id'> : never;
export type YAxis<S extends ScaleName = ScaleName, V = any> = S extends ScaleName ? MakeOptional<AxisConfig<S, V, ChartsYAxisProps>, 'id'> : never;
export type RotationAxis<S extends ScaleName = ScaleName, V = any> = S extends ScaleName ? AxisConfig<S, V, ChartsRotationAxisProps> : never;
export type RadiusAxis<S extends 'linear' = 'linear', V = any> = S extends 'linear' ? AxisConfig<S, V, ChartsRadiusAxisProps> : never;
/**
 * The x-axis configuration with missing values filled with default values.
 */
export type DefaultedXAxis<S extends ScaleName = ScaleName, V = any> = AxisConfig<S, V, ChartsXAxisProps>;
/**
 * The y-axis configuration with missing values filled with default values.
 */
export type DefaultedYAxis<S extends ScaleName = ScaleName, V = any> = AxisConfig<S, V, ChartsYAxisProps>;
export {};