import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
import MasqueradeBanner from '../MasqueradeBanner';
import { User } from '../../types';

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, options?: any) => {
      const translations: Record<string, string> = {
        'platform.masquerade.masqueradingAs': 'Masquerading as',
        'platform.masquerade.loggedInAs': `Logged in as ${options?.name || ''}`,
        'platform.masquerade.returnTo': `Return to ${options?.name || ''}`,
        'platform.masquerade.stopMasquerading': 'Stop Masquerading',
      };
      return translations[key] || key;
    },
  }),
}));

// Mock lucide-react icons
vi.mock('lucide-react', () => ({
  Eye: ({ size }: { size: number }) => <svg data-testid="eye-icon" width={size} height={size} />,
  XCircle: ({ size }: { size: number }) => <svg data-testid="xcircle-icon" width={size} height={size} />,
}));

describe('MasqueradeBanner', () => {
  const mockOnStop = vi.fn();

  const effectiveUser: User = {
    id: '2',
    name: 'John Doe',
    email: 'john@example.com',
    role: 'owner',
  };

  const originalUser: User = {
    id: '1',
    name: 'Admin User',
    email: 'admin@platform.com',
    role: 'superuser',
  };

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

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

  describe('Rendering', () => {
    it('renders the banner with correct structure', () => {
      const { container } = render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      // Check for main container - it's the first child div
      const banner = container.firstChild as HTMLElement;
      expect(banner).toBeInTheDocument();
      expect(banner).toHaveClass('bg-orange-600', 'text-white');
    });

    it('displays the Eye icon', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const eyeIcon = screen.getByTestId('eye-icon');
      expect(eyeIcon).toBeInTheDocument();
      expect(eyeIcon).toHaveAttribute('width', '18');
      expect(eyeIcon).toHaveAttribute('height', '18');
    });

    it('displays the XCircle icon in the button', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const xCircleIcon = screen.getByTestId('xcircle-icon');
      expect(xCircleIcon).toBeInTheDocument();
      expect(xCircleIcon).toHaveAttribute('width', '14');
      expect(xCircleIcon).toHaveAttribute('height', '14');
    });
  });

  describe('User Information Display', () => {
    it('displays the effective user name and role', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByText('John Doe')).toBeInTheDocument();
      expect(screen.getByText(/owner/i)).toBeInTheDocument();
    });

    it('displays the original user name', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByText(/Logged in as Admin User/i)).toBeInTheDocument();
    });

    it('displays masquerading as message', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByText(/Masquerading as/i)).toBeInTheDocument();
    });

    it('displays different user roles correctly', () => {
      const staffUser: User = {
        id: '4',
        name: 'Staff Member',
        email: 'staff@example.com',
        role: 'staff',
      };

      render(
        <MasqueradeBanner
          effectiveUser={staffUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByText('Staff Member')).toBeInTheDocument();
      // Use a more specific query to avoid matching "Staff Member" text
      expect(screen.getByText(/\(staff\)/i)).toBeInTheDocument();
    });
  });

  describe('Stop Masquerade Button', () => {
    it('renders the stop masquerade button when no previous user', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button', { name: /Stop Masquerading/i });
      expect(button).toBeInTheDocument();
    });

    it('renders the return to user button when previous user exists', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={previousUser}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button', { name: /Return to Manager User/i });
      expect(button).toBeInTheDocument();
    });

    it('calls onStop when button is clicked', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button', { name: /Stop Masquerading/i });
      fireEvent.click(button);

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

    it('calls onStop when return button is clicked with previous user', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={previousUser}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button', { name: /Return to Manager User/i });
      fireEvent.click(button);

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

    it('can be clicked multiple times', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button', { name: /Stop Masquerading/i });
      fireEvent.click(button);
      fireEvent.click(button);
      fireEvent.click(button);

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

  describe('Styling and Visual State', () => {
    it('has warning/info styling with orange background', () => {
      const { container } = render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const banner = container.firstChild as HTMLElement;
      expect(banner).toHaveClass('bg-orange-600');
      expect(banner).toHaveClass('text-white');
    });

    it('has proper button styling', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button', { name: /Stop Masquerading/i });
      expect(button).toHaveClass('bg-white');
      expect(button).toHaveClass('text-orange-600');
      expect(button).toHaveClass('hover:bg-orange-50');
    });

    it('has animated pulse effect on Eye icon container', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const eyeIcon = screen.getByTestId('eye-icon');
      const iconContainer = eyeIcon.closest('div');
      expect(iconContainer).toHaveClass('animate-pulse');
    });

    it('has proper layout classes for flexbox', () => {
      const { container } = render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const banner = container.firstChild as HTMLElement;
      expect(banner).toHaveClass('flex');
      expect(banner).toHaveClass('items-center');
      expect(banner).toHaveClass('justify-between');
    });

    it('has z-index for proper stacking', () => {
      const { container } = render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const banner = container.firstChild as HTMLElement;
      expect(banner).toHaveClass('z-50');
      expect(banner).toHaveClass('relative');
    });

    it('has shadow for visual prominence', () => {
      const { container } = render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const banner = container.firstChild as HTMLElement;
      expect(banner).toHaveClass('shadow-md');
    });
  });

  describe('Edge Cases', () => {
    it('handles users with numeric IDs', () => {
      const numericIdUser: User = {
        id: 123,
        name: 'Numeric User',
        email: 'numeric@example.com',
        role: 'customer',
      };

      render(
        <MasqueradeBanner
          effectiveUser={numericIdUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByText('Numeric User')).toBeInTheDocument();
    });

    it('handles users with long names', () => {
      const longNameUser: User = {
        id: '5',
        name: 'This Is A Very Long User Name That Should Still Display Properly',
        email: 'longname@example.com',
        role: 'manager',
      };

      render(
        <MasqueradeBanner
          effectiveUser={longNameUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(
        screen.getByText('This Is A Very Long User Name That Should Still Display Properly')
      ).toBeInTheDocument();
    });

    it('handles all possible user roles', () => {
      const roles: Array<User['role']> = [
        'superuser',
        'platform_manager',
        'platform_support',
        'owner',
        'manager',
        'staff',
        'resource',
        'customer',
      ];

      roles.forEach((role) => {
        const { unmount } = render(
          <MasqueradeBanner
            effectiveUser={{ ...effectiveUser, role }}
            originalUser={originalUser}
            previousUser={null}
            onStop={mockOnStop}
          />
        );

        expect(screen.getByText(new RegExp(role, 'i'))).toBeInTheDocument();
        unmount();
      });
    });

    it('handles previousUser being null', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByRole('button', { name: /Stop Masquerading/i })).toBeInTheDocument();
      expect(screen.queryByText(/Return to/i)).not.toBeInTheDocument();
    });

    it('handles previousUser being defined', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={previousUser}
          onStop={mockOnStop}
        />
      );

      expect(screen.getByRole('button', { name: /Return to Manager User/i })).toBeInTheDocument();
      expect(screen.queryByText(/Stop Masquerading/i)).not.toBeInTheDocument();
    });
  });

  describe('Accessibility', () => {
    it('has a clickable button element', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button');
      expect(button).toBeInTheDocument();
      expect(button.tagName).toBe('BUTTON');
    });

    it('button has descriptive text', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const button = screen.getByRole('button');
      expect(button).toHaveTextContent(/Stop Masquerading/i);
    });

    it('displays user information in semantic HTML', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      const strongElement = screen.getByText('John Doe');
      expect(strongElement.tagName).toBe('STRONG');
    });
  });

  describe('Component Integration', () => {
    it('renders without crashing with minimal props', () => {
      const minimalEffectiveUser: User = {
        id: '1',
        name: 'Test',
        email: 'test@test.com',
        role: 'customer',
      };

      const minimalOriginalUser: User = {
        id: '2',
        name: 'Admin',
        email: 'admin@test.com',
        role: 'superuser',
      };

      expect(() =>
        render(
          <MasqueradeBanner
            effectiveUser={minimalEffectiveUser}
            originalUser={minimalOriginalUser}
            previousUser={null}
            onStop={mockOnStop}
          />
        )
      ).not.toThrow();
    });

    it('renders all required elements together', () => {
      render(
        <MasqueradeBanner
          effectiveUser={effectiveUser}
          originalUser={originalUser}
          previousUser={null}
          onStop={mockOnStop}
        />
      );

      // Check all major elements are present
      expect(screen.getByTestId('eye-icon')).toBeInTheDocument();
      expect(screen.getByTestId('xcircle-icon')).toBeInTheDocument();
      expect(screen.getByText(/Masquerading as/i)).toBeInTheDocument();
      expect(screen.getByText('John Doe')).toBeInTheDocument();
      expect(screen.getByText(/Logged in as Admin User/i)).toBeInTheDocument();
      expect(screen.getByRole('button')).toBeInTheDocument();
    });
  });
});
