import React from 'react';
import { mount, shallow } from 'enzyme';

import Tutorial from '.';
import TutorialCard from '@ui/compositions/TutorialCard';
import TutorialModal from '@ui/compositions/TutorialModal';
import TutorialObstacle from '@ui/compositions/TutorialObstacle';
import Toggle from '@ui/components/Toggle';

import * as ApiActions from './apiActions';
import fetchMock from 'fetch-mock';
import 'isomorphic-fetch';

const tutorials = [
  {
    _id: '222',
    backgroundColor: '#fff',
    description: 'First title card desc',
    emoji: '',
    hero: true,
    published: true,
    title: 'First title',
  },
  {
    _id: '443',
    backgroundColor: '#fff',
    description: 'Second title card desc',
    emoji: '',
    hero: false,
    published: false,
    title: 'Second Title',
  },
];

const getClientRectSpy = jest.fn(() => ({ width: 100 }));
Range.prototype.getBoundingClientRect = getClientRectSpy;
Range.prototype.getClientRects = getClientRectSpy;

describe('Tutorial', () => {
  describe('Defaults', () => {
    it('should display empty state by default', () => {
      const node = shallow(<Tutorial isAdmin={true} modalTarget={'body'} />);
      setTimeout(() => {
        expect(node.find(TutorialObstacle)).toHaveLength(1);
      });
    });
  });

  describe('View and Data', () => {
    let node;

    beforeAll(() => {
      fetchMock.get('http://localhost:3000/tutorials/data', { tutorials, hero: tutorials[0], moduleEnabled: true });
      fetchMock.get('http://localhost:3000/tutorials/endpoints', {
        categoryId: 'id',
        children: [],
        title: 'page title',
      });
    });

    beforeEach(() => {
      node = mount(<Tutorial baseUrl={'http://localhost:3000'} isAdmin={true} modalTarget={'body'} />);
    });

    afterAll(() => {
      fetchMock.restore();
      fetchMock.reset();
    });

    it('should not display button bar contents if not admin', () => {
      const n2 = mount(<Tutorial baseUrl={'http://localhost:3000'} isAdmin={false} modalTarget={'body'} />);
      const buttonBar = n2.find(TutorialCard).find('CardButtonBar');
      expect(buttonBar.find('.TutorialCard-Toolbar-Arrow')).toHaveLength(0);
    });

    it('should call getTutorials on init', () => {
      setTimeout(() => {
        expect(node.find(TutorialCard)).toHaveLength(1);
      });
    });

    it('should handle module toggle', () => {
      fetchMock.post('http://localhost:3000/tutorials/toggleModule', { success: true });
      const toggle = node.find(Toggle).find('input');
      const spy = jest.spyOn(ApiActions, 'toggleModule');

      toggle.simulate('change', { test: true });
      expect(spy).toHaveBeenCalledTimes(1);
    });

    it('should set state when modal is opened from creation', () => {
      const button = node.find('.TutorialToolbar').find('button');
      button.simulate('click');

      const modal = node.find(TutorialModal);
      expect(modal.prop('action')).toStrictEqual('Create');
    });

    it('should call closeTutorialModal correctly', () => {
      const modal = node.find(TutorialModal);
      modal.invoke('closeTutorialModal');

      expect(modal.prop('open')).toStrictEqual(false);
    });

    it('should call for tutorial data when a slug is passed', () => {
      fetchMock.get('http://localhost:3000/tutorials/test/data', { tutorial: {} });
      const spy = jest.spyOn(ApiActions, 'getTutorialBySlug');
      mount(<Tutorial baseUrl={'http://localhost:3000'} isAdmin={false} modalTarget={'body'} slug={'test'} />);

      expect(spy).toHaveBeenCalledTimes(1);
    });
  });
});
