import { render } from '@testing-library/react';
import React from 'react';
import { useHistory } from 'react-router-dom';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { setTitle } from '../../initialize';
import { useTabTitle } from './useTabTitle';

vi.mock('../../initialize');
vi.mock('react-router-dom', () => ({
  useHistory: vi.fn(),
}));

const TestWrapper: React.FC<{ title?: string; setTabTitle: boolean }> = ({
  title,
  setTabTitle,
}) => {
  useTabTitle(title, setTabTitle);

  return null;
};

describe('useTabTitle', () => {
  beforeEach(() => {
    vi.mocked(useHistory).mockReturnValue({
      location: {
        pathname: '/test',
      },
    } as any);
  });

  it('should set the tab title when setTabTitle is true', () => {
    const firstTitle = 'First Title';
    const secondTitle = 'Second Title';

    const setTabTitle = true;

    const { rerender } = render(
      <TestWrapper title={firstTitle} setTabTitle={setTabTitle} />,
    );

    expect(setTitle).toHaveBeenCalledWith(firstTitle);

    rerender(<TestWrapper title={secondTitle} setTabTitle={setTabTitle} />);

    expect(setTitle).toHaveBeenNthCalledWith(2, secondTitle);
  });

  it('should not set the tab title when setTabTitle is false', () => {
    const title = 'Test Title';
    const setTabTitle = false;

    render(<TestWrapper title={title} setTabTitle={setTabTitle} />);

    expect(setTitle).not.toHaveBeenCalled();
  });

  it('should not set the tab title when the URL has changed', () => {
    vi.mocked(useHistory)
      .mockReturnValueOnce({
        location: {
          pathname: '/test',
        },
      } as any)
      .mockReturnValueOnce({
        location: {
          pathname: '/test2',
        },
      } as any);

    const firstTitle = 'First Title';
    const secondTitle = 'Second Title';
    const setTabTitle = true;

    const { rerender } = render(
      <TestWrapper title={firstTitle} setTabTitle={setTabTitle} />,
    );

    expect(setTitle).toHaveBeenCalledWith(firstTitle);

    rerender(<TestWrapper title={secondTitle} setTabTitle={setTabTitle} />);

    expect(setTitle).toHaveBeenCalledTimes(1);
  });

  it('should set the tab title outside a react router context', () => {
    vi.mocked(useHistory).mockReturnValue(undefined as any);

    const title = 'Test Title';
    const setTabTitle = true;

    render(<TestWrapper title={title} setTabTitle={setTabTitle} />);

    expect(setTitle).toHaveBeenCalled();
  });
});
