import { mockedMobile, mockedRestrictedMobile } from '../../../../mocks/data';
import userEvent from '@testing-library/user-event';
import ResendView, { DEFAULT_TIME_LEFT } from '../resend-view';
import { act } from '@testing-library/react-hooks';
import { renderWithClient } from '../../../../utils/test/react-query';
import * as tempUserAPI from '../../../../api/temp-user';
import { waitFor } from '@testing-library/react';

describe('ResendView component', () => {
  const mockedHandleError = jest.fn();

  afterEach(() => jest.restoreAllMocks());
  beforeEach(() => {
    jest.useFakeTimers();
  });

  afterEach(() => {
    jest.resetAllMocks();
    jest.restoreAllMocks();
    jest.useRealTimers();
  });

  test('successful render component', async () => {
    const result = renderWithClient(
      <ResendView mobile={mockedMobile} onError={mockedHandleError} />
    );
    expect(await result.findByTestId('smskey-resend-view')).toBeInTheDocument();
    expect(await result.findByText('زمان انتظار برای ارسال مجدد:')).toBeInTheDocument();
    expect(await result.findByText(DEFAULT_TIME_LEFT)).toBeInTheDocument();
    expect(await result.findByText('ثانیه')).toBeInTheDocument();

    act(() => jest.advanceTimersToNextTimer(DEFAULT_TIME_LEFT));
    expect(await result.findByRole('button', { name: 'ارسال مجدد کد' })).toBeInTheDocument();
  });

  test('call sendSmsKey function with correct arguments', async () => {
    const mockSendSmsKeyRequest = jest.spyOn(tempUserAPI, 'sendSmsKeyRequest');

    const data = { mobile: mockedMobile };
    const result = renderWithClient(
      <ResendView mobile={data.mobile} onError={mockedHandleError} />
    );

    act(() => jest.advanceTimersToNextTimer(DEFAULT_TIME_LEFT));
    const actionButton = await result.findByRole('button', { name: 'ارسال مجدد کد' });
    expect(actionButton).toBeInTheDocument();

    jest.useRealTimers();
    const user = userEvent.setup();
    await user.click(actionButton);
    await expect(mockSendSmsKeyRequest).toHaveBeenCalledWith(data);
    await waitFor(() => expect(mockedHandleError).not.toHaveBeenCalled());
  });

  test('call onError function with correct arguments', async () => {
    const mockSendSmsKeyRequest = jest.spyOn(tempUserAPI, 'sendSmsKeyRequest');

    const data = { mobile: mockedRestrictedMobile };
    const result = renderWithClient(
      <ResendView mobile={data.mobile} onError={mockedHandleError} />
    );

    act(() => jest.advanceTimersToNextTimer(DEFAULT_TIME_LEFT));
    const actionButton = await result.findByRole('button', { name: 'ارسال مجدد کد' });
    expect(actionButton).toBeInTheDocument();

    jest.useRealTimers();
    const user = userEvent.setup();
    await user.click(actionButton);
    await expect(mockSendSmsKeyRequest).toHaveBeenCalledWith(data);
    await waitFor(() => expect(mockedHandleError).toHaveBeenCalled());
  });
});
