import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { ActionList } from './ActionList';
import { ActionItem } from '@/lib/queries/ActionsPageQuery';

describe('ActionList', () => {
  const mockActions: ActionItem[] = [
    {
      id: 'action-1',
      timestamp: '2024-01-15T10:30:00Z',
      type: 'USER_UPDATE',
      initiator: 'John Doe',
      status: 'COMPLETED',
      details: 'Updated profile settings',
    },
    {
      id: 'action-2',
      timestamp: '2024-01-15T11:45:00Z',
      type: 'ONBOARDING',
      initiator: 'Jane Smith',
      status: 'PENDING',
      details: 'Started onboarding process',
    },
    {
      id: 'action-3',
      timestamp: '2024-01-15T12:00:00Z',
      type: 'USER_UPDATE',
      initiator: 'Bob Johnson',
      status: 'FAILED',
      details: 'Failed to update email',
    },
    {
      id: 'action-4',
      timestamp: '2024-01-15T13:15:00Z',
      type: 'ONBOARDING',
      initiator: 'Alice Brown',
      status: 'IN_PROGRESS',
      details: 'Completing verification',
    },
  ];

  describe('Rendering states', () => {
    it('renders table headers', () => {
      render(<ActionList actions={mockActions} />);
      
      expect(screen.getByText('Timestamp')).toBeDefined();
      expect(screen.getByText('Type')).toBeDefined();
      expect(screen.getByText('Initiator')).toBeDefined();
      expect(screen.getByText('Status')).toBeDefined();
      expect(screen.getByText('Details')).toBeDefined();
    });

    it('renders all action rows', () => {
      render(<ActionList actions={mockActions} />);
      
      mockActions.forEach((action) => {
        expect(screen.getByText(action.timestamp)).toBeDefined();
        expect(screen.getAllByText(action.type).length).toBeGreaterThan(0);
        expect(screen.getByText(action.initiator)).toBeDefined();
        expect(screen.getByText(action.details)).toBeDefined();
      });
    });

    it('renders action status badges', () => {
      render(<ActionList actions={mockActions} />);
      
      // Check that status badges are rendered for each action
      expect(screen.getByText('COMPLETED')).toBeDefined();
      expect(screen.getByText('PENDING')).toBeDefined();
      expect(screen.getByText('FAILED')).toBeDefined();
      expect(screen.getByText('IN PROGRESS')).toBeDefined();
    });

    it('renders empty table when no actions provided', () => {
      render(<ActionList actions={[]} />);
      
      // Table headers should still be visible
      expect(screen.getByText('Timestamp')).toBeDefined();
      expect(screen.getByText('Type')).toBeDefined();
      expect(screen.getByText('Initiator')).toBeDefined();
      expect(screen.getByText('Status')).toBeDefined();
      expect(screen.getByText('Details')).toBeDefined();
    });
  });

  describe('Interaction behavior', () => {
    it('renders clickable rows', () => {
      render(<ActionList actions={mockActions} />);
      
      // Check that rows have clickable attribute
      const rows = screen.getAllByRole('row');
      // Skip the header row
      const dataRows = rows.slice(1);
      
      dataRows.forEach((row) => {
        expect(row).toBeDefined();
      });
    });

    it('renders row with key based on action id', () => {
      const { container } = render(<ActionList actions={mockActions} />);
      
      // Verify that each row has a unique key
      const rows = container.querySelectorAll('tbody tr');
      expect(rows.length).toBe(mockActions.length);
      
      mockActions.forEach((action, index) => {
        const row = rows[index];
        expect(row).toBeDefined();
      });
    });
  });

  describe('Visual presentation', () => {
    it('renders table structure correctly', () => {
      const { container } = render(<ActionList actions={mockActions} />);
      
      // Verify table structure
      const table = container.querySelector('table');
      expect(table).toBeDefined();
      
      const thead = container.querySelector('thead');
      expect(thead).toBeDefined();
      
      const tbody = container.querySelector('tbody');
      expect(tbody).toBeDefined();
    });

    it('renders timestamp in monospace font', () => {
      render(<ActionList actions={mockActions} />);
      
      // The timestamp should be rendered with monospace font
      const timestamp = screen.getByText('2024-01-15T10:30:00Z');
      expect(timestamp).toBeDefined();
    });

    it('renders type with medium weight', () => {
      render(<ActionList actions={mockActions} />);
      
      // The type should be rendered with medium weight
      const types = screen.getAllByText('USER_UPDATE');
      expect(types.length).toBeGreaterThan(0);
    });

    it('renders initiator with low variant', () => {
      render(<ActionList actions={mockActions} />);
      
      // The initiator should be rendered with low variant
      const initiator = screen.getByText('John Doe');
      expect(initiator).toBeDefined();
    });

    it('renders details with low variant', () => {
      render(<ActionList actions={mockActions} />);
      
      // The details should be rendered with low variant
      const details = screen.getByText('Updated profile settings');
      expect(details).toBeDefined();
    });
  });

  describe('Edge cases', () => {
    it('handles single action', () => {
      const singleAction = [mockActions[0]];
      render(<ActionList actions={singleAction} />);
      
      expect(screen.getByText(singleAction[0].timestamp)).toBeDefined();
      expect(screen.getByText(singleAction[0].type)).toBeDefined();
      expect(screen.getByText(singleAction[0].initiator)).toBeDefined();
      expect(screen.getByText(singleAction[0].details)).toBeDefined();
    });

    it('handles actions with long details', () => {
      const longDetailsAction: ActionItem = {
        id: 'action-long',
        timestamp: '2024-01-15T14:00:00Z',
        type: 'USER_UPDATE',
        initiator: 'Long Name User',
        status: 'COMPLETED',
        details: 'This is a very long details text that might wrap to multiple lines and should still be displayed correctly in the table',
      };
      
      render(<ActionList actions={[longDetailsAction]} />);
      
      expect(screen.getByText(longDetailsAction.details)).toBeDefined();
    });

    it('handles actions with special characters in details', () => {
      const specialDetailsAction: ActionItem = {
        id: 'action-special',
        timestamp: '2024-01-15T15:00:00Z',
        type: 'USER_UPDATE',
        initiator: 'Special User',
        status: 'COMPLETED',
        details: 'Updated settings & preferences (admin)',
      };
      
      render(<ActionList actions={[specialDetailsAction]} />);
      
      expect(screen.getByText(specialDetailsAction.details)).toBeDefined();
    });

    it('handles actions with unicode characters', () => {
      const unicodeAction: ActionItem = {
        id: 'action-unicode',
        timestamp: '2024-01-15T16:00:00Z',
        type: 'USER_UPDATE',
        initiator: 'Über User',
        status: 'COMPLETED',
        details: 'Updated profile with emoji 🚀',
      };
      
      render(<ActionList actions={[unicodeAction]} />);
      
      expect(screen.getByText(unicodeAction.details)).toBeDefined();
    });
  });

  describe('Status badge integration', () => {
    it('renders ActionStatusBadge for each action', () => {
      render(<ActionList actions={mockActions} />);
      
      // Each action should have a status badge
      const completedBadge = screen.getByText('COMPLETED');
      const pendingBadge = screen.getByText('PENDING');
      const failedBadge = screen.getByText('FAILED');
      const inProgressBadge = screen.getByText('IN PROGRESS');
      
      expect(completedBadge).toBeDefined();
      expect(pendingBadge).toBeDefined();
      expect(failedBadge).toBeDefined();
      expect(inProgressBadge).toBeDefined();
    });

    it('renders correct badge variant for each status', () => {
      render(<ActionList actions={mockActions} />);
      
      // Verify that badges are rendered with correct variants
      // This is verified by the ActionStatusBadge component tests
      expect(screen.getByText('COMPLETED')).toBeDefined();
      expect(screen.getByText('PENDING')).toBeDefined();
      expect(screen.getByText('FAILED')).toBeDefined();
      expect(screen.getByText('IN PROGRESS')).toBeDefined();
    });
  });
});
