import React from 'react';
import { act } from 'react-dom/test-utils';
import { mount } from 'enzyme';
import sinon from 'sinon';
import i18n from './i18n';
import BackendMock from './backendMock';
import { useTranslation } from '../src/useTranslation';

jest.unmock('../src/useTranslation');

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      hasError: false,
    };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    const { spy } = this.props;
    spy(error, info);
  }

  render() {
    const { hasError } = this.state;
    const { children } = this.props;

    if (hasError) {
      // You can render any custom fallback UI
      return <div>Something went wrong.</div>;
    }

    return children;
  }
}

describe('useTranslation loading ns', () => {
  let newI18n;
  let backend;

  beforeEach(() => {
    newI18n = i18n.createInstance();
    backend = new BackendMock();
    newI18n.use(backend).init({
      lng: 'en',
      fallbackLng: 'en',

      interpolation: {
        escapeValue: false, // not needed for react!!
      },
    });
  });

  const TestElement = ({ useSuspense = undefined }) => {
    const [t] = useTranslation('common', { i18n: newI18n, useSuspense });
    return <div>{t('key1')}</div>;
  };

  it('should wait for correct translation', done => {
    const spy = sinon.spy();

    console.error = jest.fn(); // silent down the error boundary error from react-dom
    let wrapper = mount(
      <ErrorBoundary spy={spy}>
        <TestElement />
      </ErrorBoundary>,
    );

    expect(wrapper.contains(<div>Something went wrong.</div>)).toBe(true);
    expect(spy.callCount).toBe(1);

    backend.flush();

    setTimeout(() => {
      // mount again - no suspense recovering from promise resolve
      wrapper = mount(
        <ErrorBoundary spy={spy}>
          <TestElement />
        </ErrorBoundary>,
      );

      // console.log(wrapper.debug());
      expect(wrapper.contains(<div>test</div>)).toBe(true);
      done();
    }, 500);
  });

  it('should wait for correct translation without suspense', done => {
    const spy = sinon.spy();

    let wrapper;
    act(() => {
      wrapper = mount(
        <ErrorBoundary spy={spy}>
          <TestElement useSuspense={false} />
        </ErrorBoundary>,
      );
    });

    expect(wrapper.contains(<div>key1</div>)).toBe(true);
    expect(spy.callCount).toBe(0);

    act(() => {
      backend.flush();
    });

    setTimeout(() => {
      // mount again with translation loaded

      act(() => {
        wrapper = mount(
          <ErrorBoundary spy={spy}>
            <TestElement useSuspense={false} />
          </ErrorBoundary>,
        );
      });

      // console.log(wrapper.debug());
      expect(wrapper.contains(<div>test</div>)).toBe(true);
      expect(spy.callCount).toBe(0);
      done();
    }, 500);
  });
});

@@ -24,52 +24,8 @@
 t';%0A
-import %7B act %7D from 'react-dom/test-utils';%0A
 impo
@@ -2248,39 +2248,8 @@
 let 
-wrapper;%0A    act(() =%3E %7B%0A      
 wrap
@@ -2253,34 +2253,32 @@
 rapper = mount(%0A
-  
       %3CErrorBoun
@@ -2293,34 +2293,32 @@
 =%7Bspy%7D%3E%0A        
-  
 %3CTestElement use
@@ -2335,34 +2335,32 @@
 false%7D /%3E%0A      
- 
- 
 %3C/ErrorBoundary%3E
@@ -2369,18 +2369,8 @@
     
-  );%0A    %7D
 );%0A%0A
@@ -2463,34 +2463,16 @@
 Be(0);%0A%0A
-    act(() =%3E %7B%0A  
     back
@@ -2483,24 +2483,16 @@
 flush();
-%0A    %7D);
 %0A%0A    se
@@ -2557,35 +2557,14 @@
 ded%0A
-%0A      act(() =%3E %7B%0A 
       
- 
 wrap
@@ -2572,26 +2572,24 @@
 er = mount(%0A
-  
         %3CErr
@@ -2602,34 +2602,32 @@
 dary spy=%7Bspy%7D%3E%0A
-  
           %3CTestE
@@ -2660,26 +2660,24 @@
  /%3E%0A        
-  
 %3C/ErrorBound
@@ -2692,20 +2692,8 @@
     
-  );%0A      %7D
 );%0A%0A

remove not needed act