import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { AgentTypeList } from '@/components/agents/AgentTypeList';
import type { AgentTypeResponse } from '@/lib/api/types/agentTypes';

const mockAgentTypes: AgentTypeResponse[] = [
  {
    id: 'type-001',
    name: 'Product Owner',
    slug: 'product-owner',
    description: 'Manages product backlog and prioritizes features',
    expertise: ['requirements', 'user stories', 'prioritization'],
    personality_prompt: 'You are a Product Owner...',
    primary_model: 'claude-opus-4-5-20251101',
    fallback_models: ['claude-sonnet-4-20250514'],
    model_params: { temperature: 0.7, max_tokens: 8192, top_p: 0.95 },
    mcp_servers: ['gitea', 'knowledge'],
    tool_permissions: {},
    is_active: true,
    created_at: '2025-01-15T00:00:00Z',
    updated_at: '2025-01-20T00:00:00Z',
    instance_count: 3,
  },
  {
    id: 'type-002',
    name: 'Software Architect',
    slug: 'software-architect',
    description: 'Designs system architecture and makes technology decisions',
    expertise: ['system design', 'api design', 'security'],
    personality_prompt: 'You are a Software Architect...',
    primary_model: 'claude-opus-4-5-20251101',
    fallback_models: [],
    model_params: { temperature: 0.5, max_tokens: 8192, top_p: 0.9 },
    mcp_servers: ['gitea'],
    tool_permissions: {},
    is_active: false,
    created_at: '2025-01-10T00:00:00Z',
    updated_at: '2025-01-18T00:00:00Z',
    instance_count: 0,
  },
];

describe('AgentTypeList', () => {
  const defaultProps = {
    agentTypes: mockAgentTypes,
    isLoading: false,
    searchQuery: '',
    onSearchChange: jest.fn(),
    statusFilter: 'all',
    onStatusFilterChange: jest.fn(),
    onSelect: jest.fn(),
    onCreate: jest.fn(),
  };

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

  it('renders page title and description', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByText('Agent Types')).toBeInTheDocument();
    expect(
      screen.getByText('Configure templates for spawning AI agent instances')
    ).toBeInTheDocument();
  });

  it('renders create button', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByRole('button', { name: /create agent type/i })).toBeInTheDocument();
  });

  it('renders search input', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByPlaceholderText('Search agent types...')).toBeInTheDocument();
  });

  it('renders all agent types', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByText('Product Owner')).toBeInTheDocument();
    expect(screen.getByText('Software Architect')).toBeInTheDocument();
  });

  it('shows description for each agent type', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(
      screen.getByText('Manages product backlog and prioritizes features')
    ).toBeInTheDocument();
    expect(
      screen.getByText('Designs system architecture and makes technology decisions')
    ).toBeInTheDocument();
  });

  it('shows active status badge for active agent types', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByText('Active')).toBeInTheDocument();
    expect(screen.getByText('Inactive')).toBeInTheDocument();
  });

  it('shows expertise tags', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByText('requirements')).toBeInTheDocument();
    expect(screen.getByText('user stories')).toBeInTheDocument();
  });

  it('shows instance count', () => {
    render(<AgentTypeList {...defaultProps} />);
    expect(screen.getByText('3 instances')).toBeInTheDocument();
    expect(screen.getByText('0 instances')).toBeInTheDocument();
  });

  it('calls onSelect when agent type card is clicked', async () => {
    const user = userEvent.setup();
    render(<AgentTypeList {...defaultProps} />);

    await user.click(screen.getByText('Product Owner'));
    expect(defaultProps.onSelect).toHaveBeenCalledWith('type-001');
  });

  it('calls onCreate when create button is clicked', async () => {
    const user = userEvent.setup();
    render(<AgentTypeList {...defaultProps} />);

    await user.click(screen.getByRole('button', { name: /create agent type/i }));
    expect(defaultProps.onCreate).toHaveBeenCalledTimes(1);
  });

  it('calls onSearchChange when search input changes', async () => {
    const user = userEvent.setup();
    render(<AgentTypeList {...defaultProps} />);

    const searchInput = screen.getByPlaceholderText('Search agent types...');
    await user.type(searchInput, 'architect');
    expect(defaultProps.onSearchChange).toHaveBeenCalled();
  });

  it('shows loading skeletons when isLoading is true', () => {
    const { container } = render(
      <AgentTypeList {...defaultProps} agentTypes={[]} isLoading={true} />
    );
    expect(container.querySelectorAll('.animate-pulse').length).toBeGreaterThan(0);
  });

  it('shows empty state when no agent types', () => {
    render(<AgentTypeList {...defaultProps} agentTypes={[]} />);
    expect(screen.getByText('No agent types found')).toBeInTheDocument();
    expect(screen.getByText('Create your first agent type to get started')).toBeInTheDocument();
  });

  it('shows filter hint in empty state when filters are applied', () => {
    render(<AgentTypeList {...defaultProps} agentTypes={[]} searchQuery="nonexistent" />);
    expect(screen.getByText('Try adjusting your search or filters')).toBeInTheDocument();
  });

  it('shows +N badge when expertise has more than 3 items', () => {
    const agentWithManySkills: AgentTypeResponse = {
      ...mockAgentTypes[0],
      expertise: ['skill1', 'skill2', 'skill3', 'skill4', 'skill5'],
    };
    render(<AgentTypeList {...defaultProps} agentTypes={[agentWithManySkills]} />);
    expect(screen.getByText('+2')).toBeInTheDocument();
  });

  it('supports keyboard navigation on agent type cards', async () => {
    const user = userEvent.setup();
    render(<AgentTypeList {...defaultProps} />);

    const cards = screen.getAllByRole('button', { name: /view .* agent type/i });
    cards[0].focus();
    await user.keyboard('{Enter}');
    expect(defaultProps.onSelect).toHaveBeenCalledWith('type-001');
  });

  it('supports Space key navigation on agent type cards', async () => {
    const user = userEvent.setup();
    const onSelect = jest.fn();
    render(<AgentTypeList {...defaultProps} onSelect={onSelect} />);

    const cards = screen.getAllByRole('button', { name: /view .* agent type/i });
    cards[0].focus();
    await user.keyboard(' ');
    expect(onSelect).toHaveBeenCalledWith('type-001');
  });

  it('shows fallback text when agent type has no description', () => {
    const agentWithoutDescription: AgentTypeResponse = {
      ...mockAgentTypes[0],
      description: '',
    };
    render(<AgentTypeList {...defaultProps} agentTypes={[agentWithoutDescription]} />);
    expect(screen.getByText('No description provided')).toBeInTheDocument();
  });

  it('applies custom className', () => {
    const { container } = render(<AgentTypeList {...defaultProps} className="custom-class" />);
    expect(container.firstChild).toHaveClass('custom-class');
  });
});
