/* eslint-disable object-curly-newline */
/* eslint-disable unicorn/prefer-set-has */
import type { Elements, ElementsTypes } from 'Components/Calculation/config/map/values';
import defaultOptions from 'config/default-options';
import { makeAutoObservable } from 'mobx';
import type RootStore from 'stores/root';
import type { BaseOption } from 'ui/elements/types';
import type { CalculationOptions } from './types';

export default class OptionsStore {
  root: RootStore;
  options: CalculationOptions = defaultOptions;

  constructor(rootStore: RootStore) {
    makeAutoObservable(this);
    this.root = rootStore;
  }

  hydrate = (initialOptions: CalculationOptions) => {
    this.options = { ...defaultOptions, ...initialOptions };
  };

  getOptions<T extends Elements>(elementName: T) {
    const options = this.options[elementName];

    return options;
  }

  private checkValueInOptions = (elementName: Elements) => {
    /**
     * Проверяем, что значение есть в новом списке, иначе сбрасываем значение
     */
    const value = this.root.$calculation.element(elementName).getValue();
    if (
      !this.options[elementName]?.length ||
      !this.options[elementName].some((x) => x.value === value)
    ) {
      this.root.$calculation.element(elementName).resetValue();
    }
  };

  setOptions = <T extends Elements>(elementName: T, options: BaseOption<ElementsTypes[T]>[]) => {
    /**
     * TODO: use T instead of any in BaseOption type
     * at this moment T causes typescript error
     * but infer works just perfect
     */
    this.options[elementName] = options as BaseOption<any>[];

    this.checkValueInOptions(elementName);
  };

  resetOptions = <T extends Elements>(elementName: T) => {
    this.setOptions(elementName, defaultOptions[elementName]);
  };
}
