import {
  FIRST_ARRAY_ELEMENT,
  SECOND_ARRAY_ELEMENT,
  THIRD_ARRAY_ELEMENT,
  ZERO,
} from '@/constants/common';
import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
import {
  PLUGINS_INITIAL_STATE_LIST_MOCK,
  PLUGINS_INITIAL_STATE_MOCK,
} from '@/redux/plugins/plugins.mock';
import { AppDispatch, RootState } from '@/redux/store';
import { PluginsManager } from '@/services/pluginsManager';
import { MinervaPlugin } from '@/types/models';
import {
  InitialStoreState,
  getReduxStoreWithActionsListener,
} from '@/utils/testing/getReduxStoreActionsListener';
import { render, screen } from '@testing-library/react';
import { MockStoreEnhanced } from 'redux-mock-store';
import { LEGEND_INITIAL_STATE_MOCK } from '@/redux/legend/legend.mock';
import { PluginSingleTab } from './PluginSingleTab.component';

const renderComponent = (
  initialStore: InitialStoreState,
  plugin: MinervaPlugin,
): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
  return (
    render(
      <Wrapper>
        <PluginSingleTab plugin={plugin} />
      </Wrapper>,
    ),
    {
      store,
    }
  );
};

const removePluginContentSpy = jest.spyOn(PluginsManager, 'removePluginContent');

const PLUGIN = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
const PLUGIN_2 = PLUGINS_MOCK[SECOND_ARRAY_ELEMENT];
const PLUGIN_3 = PLUGINS_MOCK[THIRD_ARRAY_ELEMENT];

const STATE = {
  plugins: {
    ...PLUGINS_INITIAL_STATE_MOCK,
    drawer: {
      ...PLUGINS_INITIAL_STATE_MOCK.drawer,
      currentPluginHash: PLUGIN.hash,
    },
    activePlugins: {
      data: {
        [PLUGIN.hash]: PLUGIN,
      },
      pluginsId: [PLUGIN.hash],
    },
    list: PLUGINS_INITIAL_STATE_LIST_MOCK,
  },
  legend: LEGEND_INITIAL_STATE_MOCK,
};

describe('PluginSingleTab - component', () => {
  describe('when always', () => {
    it('should render plugin name', () => {
      renderComponent(STATE, PLUGIN);

      const element = screen.getByText(PLUGIN.name);
      expect(element).toBeInTheDocument();
    });

    it('should render close button', () => {
      renderComponent(STATE, PLUGIN);

      const element = screen.getByTestId('close-icon');
      expect(element).toBeInTheDocument();
    });

    it('should dispatch close action on close btn click', () => {
      const { store } = renderComponent(STATE, PLUGIN);
      const element = screen.getByTestId('close-icon');
      element.click();

      const actions = store.getActions();

      expect(removePluginContentSpy).toHaveBeenCalledWith({
        hash: PLUGIN.hash,
      });

      expect(actions[ZERO]).toEqual({
        payload: { pluginId: '5e3fcb59588cc311ef9839feea6382eb' },
        type: 'plugins/removePlugin',
      });
    });

    it('should dispatch close action on close btn click and new current drawer on last active plugin', () => {
      const { store } = renderComponent(
        {
          ...STATE,
          plugins: {
            ...PLUGINS_INITIAL_STATE_MOCK,
            activePlugins: {
              data: {
                [PLUGIN.hash]: PLUGIN,
                [PLUGIN_2.hash]: PLUGIN_2,
                [PLUGIN_3.hash]: PLUGIN_3,
              },
              pluginsId: [PLUGIN.hash, PLUGIN_2.hash, PLUGIN_3.hash],
            },
          },
        },
        PLUGIN,
      );
      const element = screen.getByTestId('close-icon');
      element.click();

      const actions = store.getActions();

      expect(removePluginContentSpy).toHaveBeenCalledWith({
        hash: PLUGIN.hash,
      });

      expect(actions).toEqual([
        { payload: { pluginId: '5e3fcb59588cc311ef9839feea6382eb' }, type: 'plugins/removePlugin' },
        { payload: '5e3fcb59588cc311ef9839feea6382eb', type: 'legend/removePluginLegend' },
        {
          payload: '5314b9f996e56e67f0dad65e7df8b73b',
          type: 'plugins/setCurrentDrawerPluginHash',
        },
      ]);
    });

    it('should dispatch set current drawer on tab click', () => {
      const { store } = renderComponent(STATE, PLUGIN);
      const element = screen.getByText(PLUGIN.name);
      element.click();

      const actions = store.getActions();

      expect(actions).toStrictEqual([
        { payload: '5e3fcb59588cc311ef9839feea6382eb', type: 'plugins/setCurrentDrawerPluginHash' },
      ]);
    });
  });
});