import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BrowserRouter, MemoryRouter } from 'react-router-dom';
import PlatformSidebar from '../PlatformSidebar';
import { User } from '../../types';

// Mock the i18next module
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, fallback?: string) => {
      const translations: Record<string, string> = {
        'nav.platformDashboard': 'Platform Dashboard',
        'nav.dashboard': 'Dashboard',
        'nav.businesses': 'Businesses',
        'nav.users': 'Users',
        'nav.support': 'Support',
        'nav.staff': 'Staff',
        'nav.platformSettings': 'Platform Settings',
        'nav.help': 'Help',
        'nav.apiDocs': 'API Docs',
      };
      return translations[key] || fallback || key;
    },
  }),
}));

// Mock the SmoothScheduleLogo component
vi.mock('../SmoothScheduleLogo', () => ({
  default: ({ className }: { className?: string }) => (
    <div data-testid="smooth-schedule-logo" className={className}>Logo</div>
  ),
}));

describe('PlatformSidebar', () => {
  const mockSuperuser: User = {
    id: '1',
    name: 'Super User',
    email: 'super@example.com',
    role: 'superuser',
  };

  const mockPlatformManager: User = {
    id: '2',
    name: 'Platform Manager',
    email: 'manager@example.com',
    role: 'platform_manager',
  };

  const mockPlatformSupport: User = {
    id: '3',
    name: 'Platform Support',
    email: 'support@example.com',
    role: 'platform_support',
  };

  const mockToggleCollapse = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('Rendering', () => {
    it('renders the sidebar with logo and user role', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByTestId('smooth-schedule-logo')).toBeInTheDocument();
      expect(screen.getByText('Smooth Schedule')).toBeInTheDocument();
      expect(screen.getByText('superuser')).toBeInTheDocument();
    });

    it('renders all navigation links for superuser', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Operations section
      expect(screen.getByText('Operations')).toBeInTheDocument();
      expect(screen.getByText('Dashboard')).toBeInTheDocument();
      expect(screen.getByText('Businesses')).toBeInTheDocument();
      expect(screen.getByText('Users')).toBeInTheDocument();
      expect(screen.getByText('Support')).toBeInTheDocument();
      expect(screen.getAllByText('Email Addresses')[0]).toBeInTheDocument();

      // System section (superuser only)
      expect(screen.getByText('System')).toBeInTheDocument();
      expect(screen.getByText('Staff')).toBeInTheDocument();
      expect(screen.getByText('Platform Settings')).toBeInTheDocument();

      // Help section
      expect(screen.getByText('Help')).toBeInTheDocument();
      expect(screen.getAllByText('Email Settings')[0]).toBeInTheDocument();
      expect(screen.getByText('API Docs')).toBeInTheDocument();
    });

    it('hides system section for platform manager', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformManager}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Operations section visible
      expect(screen.getByText('Dashboard')).toBeInTheDocument();
      expect(screen.getByText('Businesses')).toBeInTheDocument();

      // System section not visible
      expect(screen.queryByText('System')).not.toBeInTheDocument();
      expect(screen.queryByText('Staff')).not.toBeInTheDocument();
      expect(screen.queryByText('Platform Settings')).not.toBeInTheDocument();
    });

    it('hides system section and dashboard for platform support', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformSupport}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Dashboard not visible for support
      expect(screen.queryByText('Dashboard')).not.toBeInTheDocument();

      // Operations section visible
      expect(screen.getByText('Businesses')).toBeInTheDocument();
      expect(screen.getByText('Users')).toBeInTheDocument();

      // System section not visible
      expect(screen.queryByText('System')).not.toBeInTheDocument();
      expect(screen.queryByText('Staff')).not.toBeInTheDocument();
    });

    it('displays role with underscores replaced by spaces', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformManager}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByText('platform manager')).toBeInTheDocument();
    });
  });

  describe('Collapsed State', () => {
    it('hides text labels when collapsed', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={true}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Logo should be visible
      expect(screen.getByTestId('smooth-schedule-logo')).toBeInTheDocument();

      // Text should be hidden
      expect(screen.queryByText('Smooth Schedule')).not.toBeInTheDocument();
      expect(screen.queryByText('superuser')).not.toBeInTheDocument();

      // Section headers should show abbreviated versions
      expect(screen.getByText('Ops')).toBeInTheDocument();
      expect(screen.getByText('Sys')).toBeInTheDocument();
    });

    it('shows full section names when expanded', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByText('Operations')).toBeInTheDocument();
      expect(screen.getByText('System')).toBeInTheDocument();
      expect(screen.queryByText('Ops')).not.toBeInTheDocument();
      expect(screen.queryByText('Sys')).not.toBeInTheDocument();
    });

    it('applies correct width classes based on collapsed state', () => {
      const { container, rerender } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const sidebar = container.firstChild as HTMLElement;
      expect(sidebar).toHaveClass('w-64');
      expect(sidebar).not.toHaveClass('w-20');

      rerender(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={true}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(sidebar).toHaveClass('w-20');
      expect(sidebar).not.toHaveClass('w-64');
    });
  });

  describe('Toggle Collapse Button', () => {
    it('calls toggleCollapse when clicked', async () => {
      const user = userEvent.setup();

      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const toggleButton = screen.getByRole('button', { name: /collapse sidebar/i });
      await user.click(toggleButton);

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

    it('has correct aria-label when collapsed', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={true}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByRole('button', { name: /expand sidebar/i })).toBeInTheDocument();
    });

    it('has correct aria-label when expanded', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByRole('button', { name: /collapse sidebar/i })).toBeInTheDocument();
    });
  });

  describe('Active Link Highlighting', () => {
    it('highlights the active link based on current path', () => {
      render(
        <MemoryRouter initialEntries={['/platform/businesses']}>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </MemoryRouter>
      );

      const businessesLink = screen.getByRole('link', { name: /businesses/i });
      const usersLink = screen.getByRole('link', { name: /^users$/i });

      // Active link should have active classes
      expect(businessesLink).toHaveClass('bg-gray-700', 'text-white');
      expect(businessesLink).not.toHaveClass('text-gray-400');

      // Inactive link should have inactive classes
      expect(usersLink).toHaveClass('text-gray-400');
      expect(usersLink).not.toHaveClass('bg-gray-700');
    });

    it('highlights dashboard link when on dashboard route', () => {
      render(
        <MemoryRouter initialEntries={['/platform/dashboard']}>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </MemoryRouter>
      );

      const dashboardLink = screen.getByRole('link', { name: /dashboard/i });
      expect(dashboardLink).toHaveClass('bg-gray-700', 'text-white');
    });

    it('highlights link for nested routes', () => {
      render(
        <MemoryRouter initialEntries={['/platform/businesses/123']}>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </MemoryRouter>
      );

      const businessesLink = screen.getByRole('link', { name: /businesses/i });
      expect(businessesLink).toHaveClass('bg-gray-700', 'text-white');
    });

    it('highlights staff link when on staff route', () => {
      render(
        <MemoryRouter initialEntries={['/platform/staff']}>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </MemoryRouter>
      );

      const staffLink = screen.getByRole('link', { name: /staff/i });
      expect(staffLink).toHaveClass('bg-gray-700', 'text-white');
    });

    it('highlights help link when on help route', () => {
      render(
        <MemoryRouter initialEntries={['/help/api']}>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </MemoryRouter>
      );

      const apiDocsLink = screen.getByRole('link', { name: /api docs/i });
      expect(apiDocsLink).toHaveClass('bg-gray-700', 'text-white');
    });
  });

  describe('Navigation Links', () => {
    it('has correct href attributes for all links', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByRole('link', { name: /dashboard/i })).toHaveAttribute('href', '/platform/dashboard');
      expect(screen.getByRole('link', { name: /businesses/i })).toHaveAttribute('href', '/platform/businesses');
      expect(screen.getByRole('link', { name: /^users$/i })).toHaveAttribute('href', '/platform/users');
      expect(screen.getByRole('link', { name: /support/i })).toHaveAttribute('href', '/platform/support');
      expect(screen.getByRole('link', { name: /staff/i })).toHaveAttribute('href', '/platform/staff');
      expect(screen.getByRole('link', { name: /platform settings/i })).toHaveAttribute('href', '/platform/settings');
      expect(screen.getByRole('link', { name: /api docs/i })).toHaveAttribute('href', '/help/api');
    });

    it('shows title attributes on links for accessibility', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      expect(screen.getByRole('link', { name: /dashboard/i })).toHaveAttribute('title', 'Platform Dashboard');
      expect(screen.getByRole('link', { name: /businesses/i })).toHaveAttribute('title', 'Businesses');
      expect(screen.getByRole('link', { name: /^users$/i })).toHaveAttribute('title', 'Users');
    });
  });

  describe('Icons', () => {
    it('renders lucide-react icons for all navigation items', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Check that SVG icons are present (lucide-react renders as SVG)
      const svgs = container.querySelectorAll('svg');
      // Should have: logo + icons for each nav item
      expect(svgs.length).toBeGreaterThanOrEqual(10);
    });

    it('keeps icons visible when collapsed', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={true}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Icons should still be present when collapsed
      const svgs = container.querySelectorAll('svg');
      expect(svgs.length).toBeGreaterThanOrEqual(10);
    });
  });

  describe('Responsive Design', () => {
    it('applies flex column layout', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const sidebar = container.firstChild as HTMLElement;
      expect(sidebar).toHaveClass('flex', 'flex-col', 'h-full');
    });

    it('applies dark theme colors', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const sidebar = container.firstChild as HTMLElement;
      expect(sidebar).toHaveClass('bg-gray-900', 'text-white');
    });

    it('has transition classes for smooth collapse animation', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const sidebar = container.firstChild as HTMLElement;
      expect(sidebar).toHaveClass('transition-all', 'duration-300');
    });
  });

  describe('Role-Based Access Control', () => {
    it('shows dashboard for superuser and platform_manager only', () => {
      const { rerender } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );
      expect(screen.queryByText('Dashboard')).toBeInTheDocument();

      rerender(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformManager}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );
      expect(screen.queryByText('Dashboard')).toBeInTheDocument();

      rerender(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformSupport}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );
      expect(screen.queryByText('Dashboard')).not.toBeInTheDocument();
    });

    it('shows system section only for superuser', () => {
      const { rerender } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );
      expect(screen.queryByText('System')).toBeInTheDocument();
      expect(screen.queryByText('Staff')).toBeInTheDocument();

      rerender(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformManager}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );
      expect(screen.queryByText('System')).not.toBeInTheDocument();
      expect(screen.queryByText('Staff')).not.toBeInTheDocument();

      rerender(
        <BrowserRouter>
          <PlatformSidebar
            user={mockPlatformSupport}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );
      expect(screen.queryByText('System')).not.toBeInTheDocument();
    });

    it('always shows common operations links for all roles', () => {
      const roles: User[] = [mockSuperuser, mockPlatformManager, mockPlatformSupport];

      roles.forEach((user) => {
        const { unmount } = render(
          <BrowserRouter>
            <PlatformSidebar
              user={user}
              isCollapsed={false}
              toggleCollapse={mockToggleCollapse}
            />
          </BrowserRouter>
        );

        expect(screen.getByText('Businesses')).toBeInTheDocument();
        expect(screen.getByText('Users')).toBeInTheDocument();
        expect(screen.getByText('Support')).toBeInTheDocument();

        unmount();
      });
    });
  });

  describe('Accessibility', () => {
    it('has semantic HTML structure with nav element', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const nav = container.querySelector('nav');
      expect(nav).toBeInTheDocument();
    });

    it('provides proper button label for keyboard users', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const button = screen.getByRole('button', { name: /collapse sidebar/i });
      expect(button).toHaveAccessibleName();
    });

    it('all links have accessible names', () => {
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const links = screen.getAllByRole('link');
      links.forEach((link) => {
        expect(link).toHaveAccessibleName();
      });
    });

    it('maintains focus visibility for keyboard navigation', () => {
      const { container } = render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const button = screen.getByRole('button', { name: /collapse sidebar/i });
      expect(button).toHaveClass('focus:outline-none');
    });
  });

  describe('Edge Cases', () => {
    it('handles user with empty name gracefully', () => {
      const userWithoutName: User = {
        ...mockSuperuser,
        name: '',
      };

      render(
        <BrowserRouter>
          <PlatformSidebar
            user={userWithoutName}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Should still render without crashing
      expect(screen.getByTestId('smooth-schedule-logo')).toBeInTheDocument();
    });

    it('handles missing translation gracefully', () => {
      // Translation mock should return the key if translation is missing
      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      // Should render without errors even with missing translations
      expect(screen.getByTestId('smooth-schedule-logo')).toBeInTheDocument();
    });

    it('handles rapid collapse/expand toggling', async () => {
      const user = userEvent.setup();

      render(
        <BrowserRouter>
          <PlatformSidebar
            user={mockSuperuser}
            isCollapsed={false}
            toggleCollapse={mockToggleCollapse}
          />
        </BrowserRouter>
      );

      const button = screen.getByRole('button', { name: /collapse sidebar/i });

      // Rapidly click multiple times
      await user.click(button);
      await user.click(button);
      await user.click(button);

      expect(mockToggleCollapse).toHaveBeenCalledTimes(3);
    });
  });
});
