import type Color from "../../Color.js";
import type HeatmapColorStop from "../../renderers/support/HeatmapColorStop.js";
import type ColorSizeStop from "../../renderers/visualVariables/support/ColorSizeStop.js";
import type ColorStop from "../../renderers/visualVariables/support/ColorStop.js";
import type OpacityStop from "../../renderers/visualVariables/support/OpacityStop.js";
import type SizeStop from "../../renderers/visualVariables/support/SizeStop.js";
import type { HistogramBin } from "../../smartMapping/statistics/types.js";
import type { BarCreatedFunction, DataLineInfos, DataLineCreatedFunction } from "../Histogram/types.js";

/** @since 5.0 */
export type VisualVariableStop = ColorSizeStop | ColorStop | SizeStop | OpacityStop;

/** @since 5.0 */
export type SmartMappingSupportedStop = VisualVariableStop | HeatmapColorStop;

/** @since 5.0 */
export type SupportedBreaks = ColorBreak | SizeBreak;

/** @since 5.0 */
export type ViewModelState = "disabled" | "ready";

/** @since 5.0 */
export interface ZoomOptions {
  /**
   * The upper bound of the zoom.
   *
   * @since 5.0
   */
  max?: number | null;
  /**
   * The lower bound of the zoom.
   *
   * @since 5.0
   */
  min?: number | null;
}

/**
 * Configuration options for defining the slider's [Histogram](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Histogram.html).
 *
 * @since 5.0
 */
export interface HistogramConfig {
  /**
   * Indicates the average value of the dataset. When set,
   *   a solid line on the histogram will render at the location of the average value along
   *   with a label defaulting to the value set here.
   *
   * @since 5.0
   */
  average?: number;
  /**
   * Function for styling bars representing histogram bins.
   *   This can be used to style bins or add custom interaction to them. For
   *   example, you can use this function to color bins that match the colors on the slider's track.
   *
   * @since 5.0
   */
  barCreatedFunction?: BarCreatedFunction;
  /**
   * The bins of the histogram. This is
   *   an array of objects indicating the range and count of data in each bin. This value is
   *   typically retrieved from the [histogram](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-statistics-histogram.html)
   *   function.
   *
   * @since 5.0
   */
  bins?: HistogramBin[];
  /**
   * When set, renders lines on the histogram that indicate important or
   *   meaningful values to the end user.
   *
   * @since 5.0
   */
  dataLines?: DataLineInfos[];
  /**
   * Function
   *   that fires each time a data line is created.
   *   You can use this to style individual dataLines on the data axis.
   *
   * @since 5.0
   */
  dataLineCreatedFunction?: DataLineCreatedFunction;
  /**
   * Indicates the standard deviation of the dataset.
   *   When set, data lines are on the histogram at the locations of the standard deviations
   *   above and below the `average`.
   *
   * @since 5.0
   */
  standardDeviation?: number;
  /**
   * Indicates the standard deviation of the dataset.
   *   When set, data lines are on the histogram at the locations of the standard deviations
   *   above and below the `average`.
   *
   * @since 5.0
   */
  standardDeviationCount?: number;
}

/**
 * The return object of the `getStopInfo()` and `getColorStopInfo()` methods.
 *
 * @since 5.0
 */
export interface GradientStopInfo {
  /**
   * The color of the stop.
   *
   * @since 5.0
   */
  color: Color;
  /**
   * The offset of the stop.
   *
   * @since 5.0
   */
  offset: number;
}

/** @since 5.0 */
export interface ColorBreak {
  /**
   * Features with values within the provided `min`
   *   and `max` will be rendered with this color.
   *
   * @since 5.0
   */
  color: Color;
  /**
   * The max value of the break. The `max` of each break should match the `min`
   *   value of the break directly above it.
   *
   * @since 5.0
   */
  max: number;
  /**
   * The min value of the break. The `min` of each break should match the `max`
   *   value of the break directly below it.
   *
   * @since 5.0
   */
  min: number;
}

/** @since 5.0 */
export interface SizeBreak {
  /**
   * The size in points of the symbol representing features with values within
   *   the given `min` and `max`.
   *
   * @since 5.0
   */
  size: number;
  /**
   * The max value of the break. The `max` of each break should match the `min`
   *   value of the break directly above it.
   *
   * @since 5.0
   */
  max: number;
  /**
   * The min value of the break. The `min` of each break should match the `max`
   *   value of the break directly below it.
   *
   * @since 5.0
   */
  min: number;
}