import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import { ParentNavItem } from '../ParentNavItem';

import { TooltipProvider } from '@/common/components/tw/tooltip';
import { useIsNavItemActive } from '@/features/navigation/sidenav/hook/useIsNavItemActive';
import { useSideNavigationStore } from '@/features/navigation/sidenav/hook/useSideNavigationStore';
import { SideNavItem } from '@/features/navigation/sidenav/model/SideNavItem';

vi.mock('@/features/navigation/sidenav/hook/useSideNavigationStore', () => ({
  useSideNavigationStore: vi.fn()
}));

vi.mock('@/features/navigation/sidenav/hook/useIsNavItemActive', () => ({
  useIsNavItemActive: vi.fn()
}));

vi.mock('@/features/navigation/sidenav/components/variants/NavItemVariants', () => ({
  NavItemVariants: () => 'nav-item-class'
}));

vi.mock('@/features/navigation/sidenav/model/IconsMap', () => ({
  IconsMap: {
    testIcon: (props: React.SVGProps<SVGSVGElement>) => (
      <svg data-testid="test-icon" {...props}>
        <circle cx="10" cy="10" r="10" />
      </svg>
    )
  }
}));

describe('ParentNavItem', () => {
  const mockOnSelect = vi.fn();

  const baseNavItemConfig: SideNavItem = {
    title: 'Test Item',
    icon: 'testIcon',
    subItems: []
  } as never;

  beforeEach(() => {
    mockOnSelect.mockClear();
  });

  it('renders the component with icon and title when not collapsed', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    render(<ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} />);

    expect(screen.getByTestId('test-icon')).toBeInTheDocument();

    expect(screen.getByText('Test Item')).toBeInTheDocument();
  });

  it('renders tooltip on hover', async () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: true
    });

    render(
      <TooltipProvider>
        <ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} />
      </TooltipProvider>
    );

    // expect(screen.getByTestId('test-icon'))();

    // expect(screen.queryByText((content) => content.includes('Test Item'))).not.toBeInTheDocument();

    fireEvent.mouseOver(screen.getByTestId('test-icon'));

    expect(await screen.findByText('Test Item')).toBeInTheDocument();
  });

  it('calls onSelect when the item is clicked', async () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    render(<ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} />);

    await userEvent.click(screen.getByRole('button'));

    expect(mockOnSelect).toHaveBeenCalledTimes(1);
    expect(mockOnSelect).toHaveBeenCalledWith(baseNavItemConfig);
  });

  it('renders as a div when asDiv prop is true', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    render(<ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} asDiv />);

    const divElement = screen.getByText('Test Item').closest('div');
    expect(divElement).toBeInTheDocument();
    expect(divElement).not.toHaveAttribute('role', 'button');
  });

  it('renders as a button when asDiv prop is false', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    render(<ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} asDiv={false} />);

    const divElement = screen.getByText('Test Item').closest('button');
    expect(divElement).toBeInTheDocument();
    expect(divElement).not.toHaveAttribute('role', 'div');
  });

  it('renders in collapsed state', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: true
    });

    render(
      <TooltipProvider>
        <ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} />
      </TooltipProvider>
    );

    expect(screen.getByTestId('test-icon')).toBeInTheDocument();

    expect(screen.queryByText('Test Item')).not.toBeInTheDocument();
  });

  it('shows ChevronRightIcon when subItems are present', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    const navItemWithSubItems: SideNavItem = {
      ...baseNavItemConfig,
      subItems: [{ title: 'Sub Item', icon: 'testIcon', subItems: [] } as never]
    };

    render(<ParentNavItem navItem={navItemWithSubItems} onSelect={mockOnSelect} />);

    expect(screen.getByTestId('chevron-right-icon')).toBeInTheDocument();
  });

  it('does not show ChevronRightIcon when subItems are empty', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    render(<ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} />);

    expect(screen.queryByTestId('chevron-right-icon')).not.toBeInTheDocument();
  });

  it('applies the correct variant based on active state', () => {
    vi.mocked(useSideNavigationStore).mockReturnValue({
      isCollapsed: false
    });

    vi.mocked(useIsNavItemActive).mockReturnValue(true);

    render(<ParentNavItem navItem={baseNavItemConfig} onSelect={mockOnSelect} />);

    expect(screen.getByText('Test Item').closest('button')).toHaveClass('nav-item-class');
  });
});


test 'renders tooltip on hover' fails with 
TestingLibraryElementError: Unable to find an element with the text: Test Item. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.