/**
 * Tests for DynamicIcon Component
 * Verifies dynamic icon rendering by name string
 */

import { render, screen } from '@testing-library/react';
import { DynamicIcon, getAvailableIconNames } from '@/components/ui/dynamic-icon';

describe('DynamicIcon', () => {
  describe('Basic Rendering', () => {
    it('renders an icon by name', () => {
      render(<DynamicIcon name="bot" data-testid="icon" />);
      const icon = screen.getByTestId('icon');
      expect(icon).toBeInTheDocument();
      expect(icon.tagName).toBe('svg');
    });

    it('renders different icons by name', () => {
      const { rerender } = render(<DynamicIcon name="code" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-code');

      rerender(<DynamicIcon name="brain" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-brain');

      rerender(<DynamicIcon name="shield" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-shield');
    });

    it('renders kebab-case icon names correctly', () => {
      render(<DynamicIcon name="clipboard-check" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-clipboard-check');
    });
  });

  describe('Fallback Behavior', () => {
    it('renders fallback icon when name is null', () => {
      render(<DynamicIcon name={null} data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
    });

    it('renders fallback icon when name is undefined', () => {
      render(<DynamicIcon name={undefined} data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
    });

    it('renders fallback icon when name is not found', () => {
      render(<DynamicIcon name="nonexistent-icon" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
    });

    it('uses custom fallback when specified', () => {
      render(<DynamicIcon name={null} fallback="code" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-code');
    });

    it('falls back to bot when custom fallback is also invalid', () => {
      render(<DynamicIcon name="invalid" fallback="also-invalid" data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
    });
  });

  describe('Props Forwarding', () => {
    it('forwards className to icon', () => {
      render(<DynamicIcon name="bot" className="h-5 w-5 text-primary" data-testid="icon" />);
      const icon = screen.getByTestId('icon');
      expect(icon).toHaveClass('h-5');
      expect(icon).toHaveClass('w-5');
      expect(icon).toHaveClass('text-primary');
    });

    it('forwards style to icon', () => {
      render(<DynamicIcon name="bot" style={{ color: 'red' }} data-testid="icon" />);
      const icon = screen.getByTestId('icon');
      expect(icon).toHaveStyle({ color: 'rgb(255, 0, 0)' });
    });

    it('forwards aria-hidden to icon', () => {
      render(<DynamicIcon name="bot" aria-hidden="true" data-testid="icon" />);
      const icon = screen.getByTestId('icon');
      expect(icon).toHaveAttribute('aria-hidden', 'true');
    });
  });

  describe('Available Icons', () => {
    it('includes development icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('clipboard-check');
      expect(icons).toContain('briefcase');
      expect(icons).toContain('code');
      expect(icons).toContain('server');
    });

    it('includes design icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('palette');
      expect(icons).toContain('search');
    });

    it('includes quality icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('shield');
      expect(icons).toContain('shield-check');
    });

    it('includes ai_ml icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('brain');
      expect(icons).toContain('microscope');
      expect(icons).toContain('eye');
    });

    it('includes data icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('bar-chart');
      expect(icons).toContain('database');
    });

    it('includes domain expert icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('calculator');
      expect(icons).toContain('heart-pulse');
      expect(icons).toContain('flask-conical');
      expect(icons).toContain('lightbulb');
      expect(icons).toContain('book-open');
    });

    it('includes generic icons', () => {
      const icons = getAvailableIconNames();
      expect(icons).toContain('bot');
      expect(icons).toContain('cpu');
    });
  });

  describe('Icon Categories Coverage', () => {
    const iconTestCases = [
      // Development
      { name: 'clipboard-check', expectedClass: 'lucide-clipboard-check' },
      { name: 'briefcase', expectedClass: 'lucide-briefcase' },
      { name: 'file-text', expectedClass: 'lucide-file-text' },
      { name: 'git-branch', expectedClass: 'lucide-git-branch' },
      { name: 'layout', expectedClass: 'lucide-panels-top-left' },
      { name: 'smartphone', expectedClass: 'lucide-smartphone' },
      // Operations
      { name: 'settings', expectedClass: 'lucide-settings' },
      { name: 'settings-2', expectedClass: 'lucide-settings-2' },
      // AI/ML
      { name: 'message-square', expectedClass: 'lucide-message-square' },
      // Leadership
      { name: 'users', expectedClass: 'lucide-users' },
      { name: 'target', expectedClass: 'lucide-target' },
    ];

    it.each(iconTestCases)('renders $name icon correctly', ({ name, expectedClass }) => {
      render(<DynamicIcon name={name} data-testid="icon" />);
      expect(screen.getByTestId('icon')).toHaveClass(expectedClass);
    });
  });
});
