// Libs
// -----------------------------------------------------------------------------
import { action, makeObservable, observable, override } from 'mobx';
import { TableColumnProps } from 'antd';

// App
// -----------------------------------------------------------------------------
import { TypeCardSize } from 'types/default';

export abstract class GenericDashboardUiStore<T> {
  constructor() {
    makeObservable(this, {
      currentElement: observable,
      setCurrentElement: action,
      setNewCurrentElement: action,
      isFormDisabled: observable,
      setIsFormDisabled: action,
      cardSize: observable,
      setCardSize: action,
      toggleCardSize: action,
      isNewElement: observable,
      checkedColumns: observable,
      setCheckedColumns: action,
      closeForm: action,
      reset: action,
      selectedRowKeys: observable,
      setSelectedRowKeys: action,
    });
  }

  // Метод-помощник для классов-потомков.
  // Поля и экшены, перечисленные в конструкторе, нужно здесь задать как override.
  // См. https://mobx.js.org/subclassing.html
  override = (): void => {
    makeObservable(this, {
      currentElement: override,
      setCurrentElement: override,
      setNewCurrentElement: override,
      isFormDisabled: override,
      setIsFormDisabled: override,
      cardSize: override,
      setCardSize: override,
      toggleCardSize: override,
      isNewElement: override,
      checkedColumns: override,
      setCheckedColumns: override,
      closeForm: override,
      reset: override,
      selectedRowKeys: override,
      setSelectedRowKeys: override,
    });
  };

  // Выбранный элемент
  currentElement: T | null = null;

  // Задать выбранный элемент
  setCurrentElement = (element: T | null): void => {
    this.cardSize = 'small';
    this.isNewElement = false;
    this.currentElement = element;
  };

  // Создать и выбрать новый элемент
  setNewCurrentElement = (): void => {
    this.cardSize = 'small';
    this.isFormDisabled = false;
    this.isNewElement = true;
    this.currentElement = this.makeNewElement();
  };

  // Функция создания нового элемента (переопределите в наследнике)
  abstract makeNewElement: () => T;

  // Заблокирована ли форма
  isFormDisabled = true;

  // Задать блокировку формы
  setIsFormDisabled = (newState: boolean): void => {
    this.isFormDisabled = newState;
  };

  // Размер карточки
  cardSize: TypeCardSize = undefined;

  // Задать размер карточки
  setCardSize = (newCardSize: TypeCardSize): void => {
    this.cardSize = newCardSize;
  };

  // Переключить размер карточки
  toggleCardSize = (): void => {
    this.cardSize = this.cardSize === 'small' ? 'large' : 'small';
  };

  // Новый элемент или открыт имеющийся
  isNewElement = false;

  // Выбранные колонки таблицы
  checkedColumns: Array<TableColumnProps<T>> = [];

  // Список видимых колонок таблицы
  setCheckedColumns = (columns: Array<TableColumnProps<T>>): void => {
    this.checkedColumns = columns;
  };

  // Закрыть форму, сбросить состояние
  closeForm = (): void => {
    this.currentElement = null;
    this.cardSize = undefined;
    this.isFormDisabled = true;
    this.isNewElement = false;
  };

  // Полностью сбросить состояние
  reset = (): void => {
    this.currentElement = null;
    this.cardSize = undefined;
    this.isFormDisabled = true;
    this.isNewElement = false;
    this.checkedColumns = [];
  };

  // ID выделенных строк таблицы
  selectedRowKeys: Array<number> = [];

  // Задать ID выделенных строк таблицы (напрямую или через колбэк, как в useState)
  setSelectedRowKeys = (
    value: Array<number> | ((prevIds: Array<number>) => Array<number>),
  ): void => {
    if (typeof value === 'function') {
      this.selectedRowKeys = value(this.selectedRowKeys);
    } else {
      this.selectedRowKeys = value;
    }
  };
}
