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

// Mock react-router-dom BEFORE imports
vi.mock('react-router-dom', () => ({
  Link: ({ to, children, ...props }: any) =>
    React.createElement('a', { ...props, href: to }, children),
  useLocation: () => ({ pathname: '/dashboard' }),
}));

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, fallback?: string) => fallback || key,
  }),
}));

// Mock lucide-react icons
vi.mock('lucide-react', () => ({
  User: () => React.createElement('div', { 'data-testid': 'user-icon' }),
  Settings: () => React.createElement('div', { 'data-testid': 'settings-icon' }),
  LogOut: () => React.createElement('div', { 'data-testid': 'logout-icon' }),
  ChevronDown: () => React.createElement('div', { 'data-testid': 'chevron-icon' }),
}));

// Mock useAuth hook
const mockLogout = vi.fn();
vi.mock('../../hooks/useAuth', () => ({
  useLogout: () => ({
    mutate: mockLogout,
    isPending: false,
  }),
}));

describe('UserProfileDropdown', () => {
  const mockUser: User = {
    id: 1,
    email: 'john@example.com',
    name: 'John Doe',
    role: 'owner' as any,
    phone: '',
    isActive: true,
    permissions: {},
  };

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

  describe('rendering', () => {
    it('renders user name', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      expect(screen.getByText('John Doe')).toBeInTheDocument();
    });

    it('renders formatted role', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      expect(screen.getByText('Owner')).toBeInTheDocument();
    });

    it('renders formatted role with underscores replaced', () => {
      const staffUser = { ...mockUser, role: 'platform_manager' as any };
      render(React.createElement(UserProfileDropdown, { user: staffUser }));
      expect(screen.getByText('Platform Manager')).toBeInTheDocument();
    });

    it('renders user avatar when avatarUrl is provided', () => {
      const userWithAvatar = { ...mockUser, avatarUrl: 'https://example.com/avatar.jpg' };
      const { container } = render(React.createElement(UserProfileDropdown, { user: userWithAvatar }));
      const img = container.querySelector('img[alt="John Doe"]');
      expect(img).toBeInTheDocument();
      expect(img).toHaveAttribute('src', 'https://example.com/avatar.jpg');
    });

    it('renders user initials when no avatar', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      expect(screen.getByText('JD')).toBeInTheDocument();
    });

    it('renders single letter initial for single name', () => {
      const singleNameUser = { ...mockUser, name: 'Madonna' };
      render(React.createElement(UserProfileDropdown, { user: singleNameUser }));
      expect(screen.getByText('M')).toBeInTheDocument();
    });

    it('renders first two initials for multi-word name', () => {
      const multiNameUser = { ...mockUser, name: 'John Paul Jones' };
      render(React.createElement(UserProfileDropdown, { user: multiNameUser }));
      expect(screen.getByText('JP')).toBeInTheDocument();
    });
  });

  describe('dropdown interaction', () => {
    it('is closed by default', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      expect(screen.queryByText('Profile Settings')).not.toBeInTheDocument();
    });

    it('opens dropdown when button clicked', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);
      expect(screen.getByText('Profile Settings')).toBeInTheDocument();
    });

    it('shows user email in dropdown header', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);
      expect(screen.getByText('john@example.com')).toBeInTheDocument();
    });

    it('closes dropdown when clicking outside', async () => {
      const { container } = render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);
      expect(screen.getByText('Profile Settings')).toBeInTheDocument();

      // Click outside
      fireEvent.mouseDown(document.body);
      await waitFor(() => {
        expect(screen.queryByText('Profile Settings')).not.toBeInTheDocument();
      });
    });

    it('closes dropdown on escape key', async () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);
      expect(screen.getByText('Profile Settings')).toBeInTheDocument();

      fireEvent.keyDown(document, { key: 'Escape' });
      await waitFor(() => {
        expect(screen.queryByText('Profile Settings')).not.toBeInTheDocument();
      });
    });

    it('sets aria-expanded attribute correctly', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      expect(button).toHaveAttribute('aria-expanded', 'false');

      fireEvent.click(button);
      expect(button).toHaveAttribute('aria-expanded', 'true');
    });
  });

  describe('navigation', () => {
    it('links to /profile for non-platform routes', () => {
      const { container } = render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);

      const link = container.querySelector('a[href="/profile"]');
      expect(link).toBeInTheDocument();
    });

    it('profile settings link renders correctly', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);

      expect(screen.getByText('Profile Settings')).toBeInTheDocument();
    });

    it('closes dropdown when profile link is clicked', async () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);

      const profileLink = screen.getByText('Profile Settings');
      fireEvent.click(profileLink);

      await waitFor(() => {
        expect(screen.queryByText('Sign Out')).not.toBeInTheDocument();
      });
    });
  });

  describe('sign out', () => {
    it('renders sign out button', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);
      expect(screen.getByText('Sign Out')).toBeInTheDocument();
    });

    it('calls logout when sign out clicked', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);

      const signOutButton = screen.getByText('Sign Out');
      fireEvent.click(signOutButton);

      expect(mockLogout).toHaveBeenCalled();
    });

    it('sign out button is functional', () => {
      render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = screen.getByRole('button');
      fireEvent.click(button);

      const signOutButton = screen.getByText('Sign Out').closest('button');
      expect(signOutButton).not.toBeDisabled();
    });
  });

  describe('variants', () => {
    it('applies default variant styles', () => {
      const { container } = render(React.createElement(UserProfileDropdown, { user: mockUser }));
      const button = container.querySelector('button');
      expect(button?.className).toContain('border-gray-200');
    });

    it('applies light variant styles', () => {
      const { container } = render(
        React.createElement(UserProfileDropdown, {
          user: mockUser,
          variant: 'light',
        })
      );
      const button = container.querySelector('button');
      expect(button?.className).toContain('border-white/20');
    });

    it('shows white text in light variant', () => {
      const { container } = render(
        React.createElement(UserProfileDropdown, {
          user: mockUser,
          variant: 'light',
        })
      );
      const userName = screen.getByText('John Doe');
      expect(userName.className).toContain('text-white');
    });
  });
});
