import { AxiosResponse } from 'axios';

import { queryClient } from 'src/config/react-query';
import { Updater } from 'src/types/queries';
import { Widget } from 'src/types/widgets';
import { functionalUpdate } from 'src/utils/queries';

export const widgetKeys = {
  all: () => ['widgets'],
  list: () => [...widgetKeys.all(), 'list'],
};

export const dropWidget = (widgetId: number) => {
  queryClient.setQueryData(
    widgetKeys.list(),
    (oldData: AxiosResponse<Widget[]>) => {
      if (!oldData) return oldData;

      oldData.data = [...oldData.data.filter(item => item.id !== widgetId)];

      return oldData;
    },
  );
};

export const pushWidget = (widget: Widget) => {
  queryClient.setQueryData(
    widgetKeys.list(),
    (oldData: AxiosResponse<Widget[]>) => {
      if (!oldData) return oldData;

      if (widget) {
        const index = widget.position - 1;
        const newData = [...oldData.data];
        newData.splice(index, 0, widget);

        oldData.data = newData;
      }

      return oldData;
    },
  );
};

export const updateWidget = (widget: Widget) => {
  const found = setWidget(widget.id, widget) !== -1;

  if (!found) {
    pushWidget(widget);
  }
};

export const setWidget = (
  widgetId: number,
  updater: Updater<Widget>,
): number => {
  let index = -1;

  queryClient.setQueryData(
    widgetKeys.list(),
    (oldData: AxiosResponse<Widget[]>) => {
      if (!oldData) return oldData;

      const widgetIndex = oldData.data.findIndex(item => item.id === widgetId);

      if (widgetIndex !== -1) {
        index = widgetIndex;

        const newData = [...oldData.data];
        newData[widgetIndex] = functionalUpdate(
          updater,
          oldData.data[widgetIndex],
        );

        oldData.data = newData;
      }

      return oldData;
    },
  );

  return index;
};

export const updateWidgetList = (widgetList: Widget[]) => {
  queryClient.setQueryData(
    widgetKeys.list(),
    (oldData: AxiosResponse<Widget[]>) => {
      if (!oldData) return oldData;

      oldData.data = widgetList;

      return oldData;
    },
  );
};
