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

const mockAgentType: AgentTypeResponse = {
  id: 'type-001',
  name: 'Software Architect',
  slug: 'software-architect',
  description: 'Designs system architecture and makes technology decisions',
  expertise: ['system design', 'api design', 'security', 'scalability'],
  personality_prompt: `You are a Senior Software Architect with 15+ years of experience.

Your approach is:
1. Pragmatic: You favor proven solutions
2. Security-minded: Security is a first-class concern
3. Documentation-focused: You believe in ADRs`,
  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', 'filesystem'],
  tool_permissions: {},
  is_active: true,
  created_at: '2025-01-10T00:00:00Z',
  updated_at: '2025-01-18T00:00:00Z',
  instance_count: 2,
};

describe('AgentTypeDetail', () => {
  const defaultProps = {
    agentType: mockAgentType,
    isLoading: false,
    onBack: jest.fn(),
    onEdit: jest.fn(),
    onDuplicate: jest.fn(),
    onDeactivate: jest.fn(),
    isDeactivating: false,
  };

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

  it('renders agent type name', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Software Architect')).toBeInTheDocument();
  });

  it('renders active status badge', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Active')).toBeInTheDocument();
  });

  it('renders inactive status badge for inactive agent type', () => {
    render(
      <AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, is_active: false }} />
    );
    expect(screen.getByText('Inactive')).toBeInTheDocument();
  });

  it('renders description card', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Description')).toBeInTheDocument();
    expect(
      screen.getByText('Designs system architecture and makes technology decisions')
    ).toBeInTheDocument();
  });

  it('renders expertise areas', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Expertise Areas')).toBeInTheDocument();
    expect(screen.getByText('system design')).toBeInTheDocument();
    expect(screen.getByText('api design')).toBeInTheDocument();
    expect(screen.getByText('security')).toBeInTheDocument();
  });

  it('renders personality prompt', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Personality Prompt')).toBeInTheDocument();
    expect(
      screen.getByText(/You are a Senior Software Architect with 15\+ years of experience/i)
    ).toBeInTheDocument();
  });

  it('renders MCP permissions section', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('MCP Permissions')).toBeInTheDocument();
    expect(screen.getByText('Gitea')).toBeInTheDocument();
    expect(screen.getByText('Knowledge Base')).toBeInTheDocument();
    expect(screen.getByText('Filesystem')).toBeInTheDocument();
  });

  it('shows enabled/disabled status for MCP servers', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    // Should show 3 "Enabled" badges for gitea, knowledge, filesystem
    const enabledBadges = screen.getAllByText('Enabled');
    expect(enabledBadges.length).toBe(3);
    // Should show 2 "Disabled" badges for slack, browser
    const disabledBadges = screen.getAllByText('Disabled');
    expect(disabledBadges.length).toBe(2);
  });

  it('renders model configuration', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Model Configuration')).toBeInTheDocument();
    expect(screen.getByText('Primary Model')).toBeInTheDocument();
    expect(screen.getByText('Claude Opus 4.5')).toBeInTheDocument();
    expect(screen.getByText('Failover Model')).toBeInTheDocument();
    expect(screen.getByText('Claude Sonnet 4')).toBeInTheDocument();
  });

  it('renders model parameters', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Temperature')).toBeInTheDocument();
    expect(screen.getByText('0.7')).toBeInTheDocument();
    expect(screen.getByText('Max Tokens')).toBeInTheDocument();
    expect(screen.getByText('8,192')).toBeInTheDocument();
    expect(screen.getByText('Top P')).toBeInTheDocument();
    expect(screen.getByText('0.95')).toBeInTheDocument();
  });

  it('renders instance count', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Instances')).toBeInTheDocument();
    expect(screen.getByText('2')).toBeInTheDocument();
    expect(screen.getByText('Active instances')).toBeInTheDocument();
  });

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

    await user.click(screen.getByRole('button', { name: /go back/i }));
    expect(defaultProps.onBack).toHaveBeenCalledTimes(1);
  });

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

    await user.click(screen.getByRole('button', { name: /edit/i }));
    expect(defaultProps.onEdit).toHaveBeenCalledTimes(1);
  });

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

    await user.click(screen.getByRole('button', { name: /duplicate/i }));
    expect(defaultProps.onDuplicate).toHaveBeenCalledTimes(1);
  });

  it('shows loading skeleton when isLoading is true', () => {
    const { container } = render(
      <AgentTypeDetail {...defaultProps} agentType={null} isLoading={true} />
    );
    expect(container.querySelectorAll('.animate-pulse').length).toBeGreaterThan(0);
  });

  it('shows not found state when agentType is null', () => {
    render(<AgentTypeDetail {...defaultProps} agentType={null} isLoading={false} />);
    expect(screen.getByText('Agent type not found')).toBeInTheDocument();
    expect(screen.getByText('The requested agent type could not be found')).toBeInTheDocument();
  });

  it('shows danger zone with deactivate button', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    expect(screen.getByText('Danger Zone')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: /deactivate type/i })).toBeInTheDocument();
  });

  it('shows confirmation dialog when deactivate is clicked', async () => {
    const user = userEvent.setup();
    render(<AgentTypeDetail {...defaultProps} />);

    await user.click(screen.getByRole('button', { name: /deactivate type/i }));
    expect(screen.getByText('Are you sure?')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: /deactivate$/i })).toBeInTheDocument();
  });

  it('calls onDeactivate when confirmation is accepted', async () => {
    const user = userEvent.setup();
    render(<AgentTypeDetail {...defaultProps} />);

    await user.click(screen.getByRole('button', { name: /deactivate type/i }));
    await user.click(screen.getByRole('button', { name: /^deactivate$/i }));
    expect(defaultProps.onDeactivate).toHaveBeenCalledTimes(1);
  });

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

  it('shows no description message when description is null', () => {
    render(
      <AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, description: null }} />
    );
    expect(screen.getByText('No description provided')).toBeInTheDocument();
  });

  it('shows no expertise message when expertise is empty', () => {
    render(<AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, expertise: [] }} />);
    expect(screen.getByText('No expertise areas defined')).toBeInTheDocument();
  });

  it('shows "None configured" when no fallback model', () => {
    render(
      <AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, fallback_models: [] }} />
    );
    expect(screen.getByText('None configured')).toBeInTheDocument();
  });
});
