import type { ChartOptions } from "chart.js";
import { Color } from "../misc";
import { Range } from "../range";
import { TitleDesign } from "./chart";
import { NonDataSourceBaseChartDefinition } from "./common_chart";

export interface GaugeChartDefinition<T extends string | Range = string>
  extends NonDataSourceBaseChartDefinition {
  readonly type: "gauge";
  readonly dataRange?: T;
  readonly sectionRule: SectionRule;
}

export interface SectionRule {
  readonly colors: ColorSet;
  readonly rangeMin: string;
  readonly rangeMax: string;
  readonly lowerInflectionPoint: SectionThreshold;
  readonly upperInflectionPoint: SectionThreshold;
}

interface ColorSet {
  readonly lowerColor: Color;
  readonly middleColor: Color;
  readonly upperColor: Color;
}

export interface SectionThreshold {
  readonly type: "number" | "percentage";
  readonly value: string;
  readonly operator: "<" | "<=";
}

export interface GaugeValue {
  value: number;
  label: string;
}

export interface GaugeInflectionValue extends GaugeValue {
  operator: "<" | "<=";
}

export interface GaugeChartRuntime {
  background: Color;
  title: TitleDesign;
  minValue: GaugeValue;
  maxValue: GaugeValue;
  gaugeValue?: GaugeValue;
  inflectionValues: GaugeInflectionValue[];
  colors: Color[];
}

export interface GaugeAnimatedRuntime extends GaugeChartRuntime {
  animationValue?: number;
}

export interface GaugeChartOptions extends ChartOptions {
  needle?: NeedleOptions;
  valueLabel?: ValueLabelOptions;
  inflectionValues: InflectionValuesOptions[];
  minValue: string;
  maxValue: string;
}

export interface NeedleOptions {
  display?: boolean;
  borderColor?: Color;
  backgroundColor?: Color;
  /**
   * Needle width as the percentage of the chart area width
   */
  width?: number;
}

export interface InflectionValuesOptions {
  value: number;
  color: Color;
  label: string;
}

export interface ValueLabelOptions {
  display?: boolean;
  formatter?: (value) => string;
  font?: {
    size?: number;
    family?: string;
    color?: Color;
  };
  backgroundColor?: Color;
  borderColor?: Color;
  borderRadius?: number;
  padding?: {
    left: number;
    right: number;
    top: number;
    bottom: number;
  };
}
