import { ConfigPropertyTypes } from '../../types';
import { IKosDataModel } from '../../core';
import { SchemaNodeType, SchemaOptionsType } from '../../../services/config-bean';
import { UnitConverter } from '../../../decorators';


export interface ConfigPropConverter {
  measure?: string;
  from?: UnitConverter;
  to?: UnitConverter;
}

export type FormatOptions =
  | Intl.NumberFormatOptions
  | ((system: string) => Intl.NumberFormatOptions);

export interface OptionsType {
  value: string;
  label: string;
}
export type OptionsExpander =
  | OptionsType[]
  | ((system: string, options?: string[]) => OptionsType[]);
/**
 * Options that are passed into the model via the constructor
 *
 * @property path - the handle path for the config bean
 * @property attribute - the attribute on the config bean
 * @property converter - the converter indicating the source and target unit conversions
 * @property formatter - the formatting to be applied to numeric values.  Uses the Intl.NumberFormatOptions
 */
export interface ConfigBeanPropOptions {
  path: string;
  attribute: string;
  converter?: { from?: UnitConverter; to?: UnitConverter };
  formatter?: FormatOptions;
  optionsExpander?: OptionsExpander;
  serviceBasePath?: string;
}

/**
 * @property id - the unique identifier of the config bean property
 * @property value - the raw value of the config property after any unit conversion
 * The value does not perform any rounding or formatting
 * @property displayValue - the string value of the value after all formatting, rounding
 * and unit conversion
 * @property unit - the unit of measure for the property.  This unit will be formatted based
 * on the formatter options provided.
 *
 * @category Configuration Service
 *
 */
export interface KosConfigProperty<
  PropertyType extends ConfigPropertyTypes = ConfigPropertyTypes
> extends ConfigBeanPropOptions,
    IKosDataModel {
  id: string;
  serviceBasePath?: string;
  readonly unit?: string;
  readonly value?: PropertyType;
  readonly rawValue?: PropertyType;
  readonly significantValue?: PropertyType;
  readonly previousValue?: PropertyType;
  readonly displayValue?: string;
  readonly displayOptions?: SchemaOptionsType;
  readonly options?: OptionsType[];
  readonly schemaType: SchemaNodeType | "enum";
  readonly schemaFormat?: string;
  /**
   * Update the property value of the config bean property resulting in a
   * the value being pushed to the backend for persistence.
   * @param value - the value of the property
   * @returns - void
   */
  updateProperty: (value: PropertyType | string) => void;
}
