import {createPageContext, createSearchContext, usePage} from '@hooks';
import {useQueryTableList as useQueryList} from '.';
import {FC} from 'react';
import {BaseListResult, ListParams} from '@models';
import {act, render, waitFor} from '@testing-library/react';
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
import {PageProvider} from '@components';

function mockQuery({page}: ListParams): BaseListResult<number> {
  return Promise.resolve({
    msg: '200',
    data: {
      total: page === '1' ? 4 : 2,
      list: page === '1' ? [1, 2, 3, 4] : [1, 2],
      pageNum: 1,
      pageSize: 1,
      size: 1,
      startRow: 1,
      endRow: 1,
      pages: 1,
      prePage: 1,
      nextPage: 1,
      isFirstPage: false,
      isLastPage: false,
      hasPreviousPage: false,
      hasNextPage: true,
      navigatePages: 1,
      navigatepageNums: [],
      navigateFirstPage: 1,
      navigateLastPage: 1,
    },
  });
}

describe('useQueryList', function () {
  it('basic', function () {
    expect(useQueryList).toBeDefined();
    expect(useQueryList).toBeInstanceOf(Function);
  });

  it('数据测试', async function () {
    const pageContext = createPageContext();
    const searchContext = createSearchContext();
    const client = new QueryClient();

    const App: FC = function () {
      const [{isFetching, data, count}] = useQueryList({
        queryFn: mockQuery,
        params: {},
        pageContext,
        searchContext,
      });
      const [, {onCurrentPageChange}] = usePage(pageContext);
      function onNextPage() {
        onCurrentPageChange(2);
      }

      return (
        <>
          <p data-testid='count'>{count}</p>
          <p data-testid='is_fetching'>{isFetching.toString()}</p>
          <button data-testid='next_page' onClick={onNextPage} />
          <ul data-testid='list'>
            {data.map(function (val) {
              return <li key={val}>{val}</li>;
            })}
          </ul>
        </>
      );
    };

    const {getByTestId} = render(
      <QueryClientProvider client={client}>
        <PageProvider context={pageContext}>
          <App />
        </PageProvider>
      </QueryClientProvider>,
    );

    await waitFor(function () {
      expect(getByTestId('count').innerHTML).toBe('0');
      expect(getByTestId('is_fetching').innerHTML).toBe('true');
      expect(getByTestId('list').children.length).toBe(0);
    });

    await waitFor(function () {
      expect(getByTestId('count').innerHTML).toBe('4');
      expect(getByTestId('is_fetching').innerHTML).toBe('false');
      expect(getByTestId('list').children.length).toBe(4);
    });

    act(() => getByTestId('next_page').click());

    await waitFor(function () {
      expect(getByTestId('is_fetching').innerHTML).toBe('true');
    });

    await waitFor(function () {
      expect(getByTestId('count').innerHTML).toBe('2');
      expect(getByTestId('is_fetching').innerHTML).toBe('false');
      expect(getByTestId('list').children.length).toBe(2);
    });
  });

  it('格式化result', async function () {
    const pageContext = createPageContext();
    const searchContext = createSearchContext();
    const client = new QueryClient();

    const App: FC = function () {
      const [{isFetching, data, count}] = useQueryList({
        queryFn: mockQuery,
        params: {},
        pageContext,
        searchContext,
        formatResult(data) {
          return data.msg === '200' ? data.data.list.map(val => val + 1) : [];
        },
      });
      const [, {onCurrentPageChange}] = usePage(pageContext);
      function onNextPage() {
        onCurrentPageChange(2);
      }

      return (
        <>
          <p data-testid='count'>{count}</p>
          <p data-testid='is_fetching'>{isFetching.toString()}</p>
          <button data-testid='next_page' onClick={onNextPage} />
          <ul data-testid='list'>
            {data.map(function (val) {
              return <li key={val}>{val}</li>;
            })}
          </ul>
        </>
      );
    };

    const {getByTestId} = render(
      <QueryClientProvider client={client}>
        <PageProvider context={pageContext}>
          <App />
        </PageProvider>
      </QueryClientProvider>,
    );

    await waitFor(function () {
      expect(getByTestId('count').innerHTML).toBe('0');
      expect(getByTestId('is_fetching').innerHTML).toBe('true');
      expect(getByTestId('list').children.length).toBe(0);
    });

    await waitFor(function () {
      expect(getByTestId('count').innerHTML).toBe('4');
      expect(getByTestId('is_fetching').innerHTML).toBe('false');
      const list = getByTestId('list');
      expect(list.children.length).toBe(4);

      expect(list.children[0].innerHTML).toBe('2');
      expect(list.children[1].innerHTML).toBe('3');
      expect(list.children[2].innerHTML).toBe('4');
      expect(list.children[3].innerHTML).toBe('5');
    });
  });
});
