/* eslint-disable @typescript-eslint/no-empty-function */
import React from 'react';
import { screen, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Context as ResponsiveContext } from 'react-responsive';

import { useOverlayTriggerState, OverlayTriggerState } from 'react-stately';
import { DOMAttributes, FocusableElement } from '@react-types/shared';
import { useOverlayTrigger } from 'react-aria';

import { PreviewPanel } from './PreviewPanel';

function PreviewPanelTestWrapper({
  constructFunction,
}: {
  constructFunction: (
    previewModalState: OverlayTriggerState,
    overlayProps: DOMAttributes<FocusableElement>,
  ) => JSX.Element;
}) {
  const previewModalState = useOverlayTriggerState({});
  const { overlayProps } = useOverlayTrigger({ type: 'dialog' }, previewModalState);

  return constructFunction(previewModalState, overlayProps);
}

function mockResource(properties: Partial<any> = {}): any {
  return {
    id: 'test-resource',
    name: 'Test resource',
    type: { code: 'folder', name: 'Folder' },
    status: { code: 'live', name: 'Live' },
    url: 'https://no-where.com',
    urls: [],
    childCount: 0,
    ...properties,
  };
}

const ResourceComponent = () => {
  return <div>TestResource</div>;
};

describe('PreviewPanel', () => {
  it('Renders a message when no item selected', async () => {
    const onSelect = jest.fn();
    const onClose = jest.fn();

    render(
      <PreviewPanelTestWrapper
        constructFunction={(previewModalState, overlayProps) => {
          return (
            <PreviewPanel
              resource={null}
              allowedTypes={undefined}
              modalState={previewModalState}
              previewModalOverlayProps={overlayProps}
              onSelect={onSelect}
              onClose={onClose}
              ResourceComponent={ResourceComponent}
            />
          );
        }}
      />,
    );

    await waitFor(() => {
      expect(screen.getAllByText('Make a selection to see more info here.')).toBeTruthy();
    });
  });

  it('Renders tablet / desktop very above 640px', async () => {
    const onSelect = jest.fn();
    const onClose = jest.fn();

    render(
      <ResponsiveContext.Provider value={{ width: 641 }}>
        <PreviewPanelTestWrapper
          constructFunction={(previewModalState, overlayProps) => {
            return (
              <PreviewPanel
                resource={mockResource({ name: 'TestResource' })}
                allowedTypes={undefined}
                modalState={previewModalState}
                previewModalOverlayProps={overlayProps}
                onSelect={onSelect}
                onClose={onClose}
                ResourceComponent={ResourceComponent}
              />
            );
          }}
        />
      </ResponsiveContext.Provider>,
    );

    await waitFor(() => {
      expect(screen.queryByRole('dialog')).toBeFalsy();
      expect(screen.queryByText('TestResource')).toBeTruthy();
    });
  });

  it('Renders mobile below 640px', async () => {
    const onSelect = jest.fn();
    const onClose = jest.fn();

    render(
      <ResponsiveContext.Provider value={{ width: 640 }}>
        <PreviewPanelTestWrapper
          constructFunction={(previewModalState, overlayProps) => {
            return (
              <PreviewPanel
                resource={mockResource({ name: 'TestResource' })}
                allowedTypes={undefined}
                modalState={previewModalState}
                previewModalOverlayProps={overlayProps}
                onSelect={onSelect}
                onClose={onClose}
                ResourceComponent={ResourceComponent}
              />
            );
          }}
        />
      </ResponsiveContext.Provider>,
    );

    await waitFor(() => {
      expect(screen.queryByRole('dialog')).toBeTruthy();
      expect(screen.queryByText('TestResource')).toBeTruthy();
    });
  });

  it('Clicking select button return source and id of resource being shown', async () => {
    const onSelect = jest.fn();
    const onClose = jest.fn();
    const resource = mockResource();

    render(
      <PreviewPanelTestWrapper
        constructFunction={(previewModalState, overlayProps) => {
          return (
            <PreviewPanel
              resource={resource}
              allowedTypes={undefined}
              modalState={previewModalState}
              previewModalOverlayProps={overlayProps}
              onSelect={onSelect}
              onClose={onClose}
              ResourceComponent={ResourceComponent}
            />
          );
        }}
      />,
    );

    const user = userEvent.setup();
    user.click(screen.getByRole('button'));

    await waitFor(() => {
      expect(onSelect).toHaveBeenCalledWith(resource);
    });
  });
});
