import { reaction } from 'mobx';
import { History, replaceSearchParamsWith } from '@wix/bex-core';
import { CustomColumnsState } from './CustomColumnsState';

function parseSelectedColumnsString(selectedColumnsFromUrl: string) {
  return selectedColumnsFromUrl
    .split(',')
    .map((columnExpression) => {
      const [id = '', isSelected] = columnExpression.split(' ');

      return {
        id: decodeURIComponent(id),
        isSelected: isSelected !== 'false',
      };
    })
    .filter(({ id }) => id);
}

export interface CustomColumnsHistoryStateParams {
  customColumns: CustomColumnsState<any, any>;
  history: History;
}

export class CustomColumnsHistoryState {
  readonly customColumns;
  readonly history;

  selectedColumnsSearchParamName = 'selectedColumns';

  _selectedColumnsFromUrl?: string | null;

  constructor(params: CustomColumnsHistoryStateParams) {
    this.customColumns = params.customColumns;
    this.history = params.history;

    this._preInitHistoryPersistence();
  }

  _preInitHistoryPersistence() {
    const { history, customColumns } = this;

    const searchParams = new URLSearchParams(history.location.search);

    this._selectedColumnsFromUrl = searchParams.get(
      this.selectedColumnsSearchParamName,
    );

    if (this._selectedColumnsFromUrl) {
      this.customColumns.table.selectedColumns.setValue(
        parseSelectedColumnsString(this._selectedColumnsFromUrl),
      );
      customColumns.table.multi.collections.forEach(({ query }) => {
        query._initializedFromHistory = true;
      });
    }
  }

  init() {
    const disposers = [
      reaction(
        () => this.customColumns.table.selectedColumns.value,
        (selectedColumns) => {
          replaceSearchParamsWith(this.history, (searchParams) => {
            if (selectedColumns.length) {
              searchParams.set(
                this.selectedColumnsSearchParamName,
                selectedColumns
                  .map(
                    (c) =>
                      `${encodeURIComponent(c.id)}${
                        !c.isSelected ? ' false' : ''
                      }`,
                  )
                  .join(','),
              );
            } else {
              searchParams.delete(this.selectedColumnsSearchParamName);
            }
          });
        },
        {
          fireImmediately: true,
          delay: 250,
        },
      ),
    ];

    return () => {
      disposers.forEach((d) => d());
    };
  }
}
