import * as React from 'react';
import {shallow, mount, ReactWrapper, ShallowWrapper} from 'enzyme';
import {createMockEnvironment, MockPayloadGenerator} from 'relay-test-utils';
import {QueryRenderer, graphql} from 'react-relay';
import * as ReactTestRenderer from 'react-test-renderer';

// FIXME: imports in this manner work fine via `yarn test` but fails in-editor for code completion
//import FragmentedPokemonShow, {PokemonShow, Props} from 'packs/frontend/components/pages/pokemon/Show';
//import {Show_pokemon} from 'packs/frontend/components/pages/pokemon/__generated__/Show_pokemon.graphql';
import FragmentedPokemonShow, {
  PokemonShow,
  Props,
} from '../../../../../../app/javascript/packs/frontend/components/pages/pokemon/Show';
import {Show_pokemon} from '../../../../../../app/javascript/packs/frontend/components/pages/pokemon/__generated__/Show_pokemon.graphql';

const pokemon: Show_pokemon = {
  id: '1',
  iid: 'x1',
  nickname: 'Bulbasaur',
  pokedexNumber: 1,
  ' $refType': '' as any,
};

const defaultProps = {
  pokemon: pokemon,
};

function setup(props = defaultProps): ShallowWrapper {
  return shallow(<PokemonShow {...props} />);
}

function mountSetup(props = defaultProps): ReactWrapper {
  return mount(<PokemonShow {...props} />);
}

describe('<PokemonShow />', () => {
  it('displays a pokemon', () => {
    const wrapper = setup();
    expect(wrapper).toMatchSnapshot();
  });

  it('requests data from a GraphQL fragment', () => {
    const environment = createMockEnvironment();
    const mockId = 'mock-id-1';

    const TestRenderer = () => (
      <QueryRenderer
        environment={environment}
        query={graphql`
          query Show_pokemonSuccessQuery($mockId: ID!) @relay_test_operation {
            pokemon: node(id: $mockId) {
              ...Show_pokemon
            }
          }
        `}
        variables={{mockId}}
        render={args => {
          const {error, props} = args as {error: Error; props: Props};
          if (props) {
            // Prevent TS Compiler from complaining about unsupplied props
            const Component = FragmentedPokemonShow as any;

            return <Component pokemon={props.pokemon} />;
          } else if (error) {
            return error.message;
          }
          return 'Loading...';
        }}
      />
    );

    environment.mock.queueOperationResolver(operation =>
      MockPayloadGenerator.generate(operation, {
        Pokemon: () => ({
          id: mockId,
          iid: '1',
          nickname: 'Bulba',
          pokedexNumber: 3,
        }),
      })
    );

    const renderer = ReactTestRenderer.create(<TestRenderer />);
    expect(renderer).toMatchSnapshot();
  });
});
