import React, { useEffect, useRef, useState } from 'react';
import { render, fireEvent, waitFor, screen, cleanup } from '@testing-library/react';
import { FormHandles } from '@unform/core';
import { Form } from '@unform/web';
import { Observable } from 'rxjs';
import { InputAutoComplete } from '.';
import 'jest-styled-components';
import { SelectAutocomplete } from '../SelectAutocomplete';

const fetchGroupMock = (): Observable<any> =>
   new Observable((observable) => {
      setTimeout(() => {
         observable.next([
            { disabled: true, name: 'Bairro', title: true },
            { name: 'Mogi das cruzes' },
            { name: 'Suzano' },
            { disabled: true, name: 'Cidade', title: true },
            { name: 'São Paulo' },
            { name: 'Suzano' },
            { name: 'Guarulhos' },
         ]);
         observable.complete();
         observable.unsubscribe();
      }, 10);
   });

const fetchSimpleMock = (): Observable<any> =>
   new Observable((observable) => {
      setTimeout(() => {
         observable.next(['São Paulo', 'Suzano', 'Guarulhos']);
         observable.complete();
         observable.unsubscribe();
      }, 10);
   });

it('renderizar default', () => {
   function Component(): any {
      return (
         <Form onSubmit={() => {}}>
            <InputAutoComplete
               fetch={fetchSimpleMock}
               name="autocomplete"
               getValueText={(v) => v}
               renderInput={(item: any) => <div>{item}</div>}
            />
         </Form>
      );
   }

   const { container } = render(<Component />);

   expect(container.firstChild).toMatchSnapshot();
});

it('renderizar valor inicial', () => {
   function Component(): any {
      return (
         <Form onSubmit={() => {}} initialData={{ autocomplete: 'Suzano' }}>
            <InputAutoComplete
               fetch={fetchSimpleMock}
               name="autocomplete"
               getValueText={(v) => v}
               renderInput={(item: any) => <div>{item}</div>}
            />
         </Form>
      );
   }

   const { container, queryByTestId } = render(<Component />);

   expect((queryByTestId('autocomplete--input') as any).value).toBe('Suzano');

   expect(container.firstChild).toMatchSnapshot();
});

it('renderizar abrir/fechar popup', async () => {
   function Component(): any {
      return (
         <Form onSubmit={() => {}}>
            <InputAutoComplete
               fetch={fetchSimpleMock}
               name="autocomplete"
               getValueText={(v) => v}
               renderInput={(item: any) => <div>{item}</div>}
            />
         </Form>
      );
   }

   const { container } = render(<Component />);

   fireEvent.input(screen.getByTestId('autocomplete--input'), { target: { value: 'Suzano' } });

   // Deve aparecer popup
   await waitFor(() => !!screen.getByTestId('autocomplete-list'));
   expect(screen.getByTestId('autocomplete-list--row-0').innerHTML).toEqual('<div>São Paulo</div>');
   expect(screen.getByTestId('autocomplete-list--row-1').innerHTML).toEqual('<div>Suzano</div>');
   expect(screen.getByTestId('autocomplete-list--row-2').innerHTML).toEqual('<div>Guarulhos</div>');
   expect(container.firstChild).toMatchSnapshot();

   // Deve sumir popup
   fireEvent.blur(screen.getByTestId('autocomplete--input'));

   await waitFor(() => expect(screen.queryByTestId('autocomplete-list')).toBeNull());

   expect(container.firstChild).toMatchSnapshot();
});

it('selecionar item popup', async () => {
   function Component(): any {
      return (
         <Form onSubmit={() => {}}>
            <InputAutoComplete
               fetch={fetchSimpleMock}
               name="autocomplete"
               getValueText={(v) => v}
               renderInput={(item: any) => <div>{item}</div>}
            />
         </Form>
      );
   }

   const { container } = render(<Component />);

   fireEvent.input(screen.getByTestId('autocomplete--input'), { target: { value: 'Suzano' } });

   // Deve aparecer popup
   await waitFor(() => !!screen.getByTestId('autocomplete-list'));
   expect(screen.getByTestId('autocomplete-list--row-0').innerHTML).toEqual('<div>São Paulo</div>');
   expect(screen.getByTestId('autocomplete-list--row-1').innerHTML).toEqual('<div>Suzano</div>');
   expect(screen.getByTestId('autocomplete-list--row-2').innerHTML).toEqual('<div>Guarulhos</div>');
   fireEvent.click(screen.getByTestId('autocomplete-list--row-2'));
   fireEvent.blur(screen.getByTestId('autocomplete--input'));

   // Esperar fechar popup
   await waitFor(() => expect(screen.queryByTestId('autocomplete-list')).toBeNull());

   await waitFor(() => expect((screen.queryByTestId('autocomplete--input') as any).value).toEqual('Guarulhos'));

   expect(container.firstChild).toMatchSnapshot();
});

it('renderizar with error', () => {
   function Component(): any {
      const formRef = useRef<FormHandles>();

      useEffect(() => {
         formRef.current.setFieldError('autocomplete', 'Field Invalid');
      }, []);

      return (
         <Form onSubmit={() => {}} ref={formRef}>
            <InputAutoComplete
               fetch={fetchSimpleMock}
               name="autocomplete"
               getValueText={(v) => v}
               renderInput={(item: any) => <div>{item}</div>}
            />
         </Form>
      );
   }

   const { container } = render(<Component />);

   expect(screen.getByTestId('input-error')).not.toBeUndefined();

   expect(container.firstChild).toMatchSnapshot();
});
