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,
  // Category and display fields
  category: 'development',
  icon: 'git-branch',
  color: '#3B82F6',
  sort_order: 40,
  typical_tasks: ['Design system architecture', 'Create ADRs'],
  collaboration_hints: ['backend-engineer', 'frontend-engineer'],
  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 in hero header', () => {
    render(<AgentTypeDetail {...defaultProps} />);
    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: /back to agent types/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();
  });

  describe('Hero Header', () => {
    it('renders hero header with agent name', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(
        screen.getByRole('heading', { level: 1, name: 'Software Architect' })
      ).toBeInTheDocument();
    });

    it('renders dynamic icon in hero header', () => {
      const { container } = render(<AgentTypeDetail {...defaultProps} />);
      expect(container.querySelector('svg.lucide-git-branch')).toBeInTheDocument();
    });

    it('applies agent color to hero header gradient', () => {
      const { container } = render(<AgentTypeDetail {...defaultProps} />);
      const heroHeader = container.querySelector('[style*="linear-gradient"]');
      expect(heroHeader).toBeInTheDocument();
    });

    it('renders category badge in hero header', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Development')).toBeInTheDocument();
    });

    it('shows last updated date in hero header', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText(/Last updated:/)).toBeInTheDocument();
      expect(screen.getByText(/Jan 18, 2025/)).toBeInTheDocument();
    });
  });

  describe('Typical Tasks Card', () => {
    it('renders "What This Agent Does Best" card', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('What This Agent Does Best')).toBeInTheDocument();
    });

    it('displays all typical tasks', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Design system architecture')).toBeInTheDocument();
      expect(screen.getByText('Create ADRs')).toBeInTheDocument();
    });

    it('does not render typical tasks card when empty', () => {
      render(
        <AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, typical_tasks: [] }} />
      );
      expect(screen.queryByText('What This Agent Does Best')).not.toBeInTheDocument();
    });
  });

  describe('Collaboration Hints Card', () => {
    it('renders "Works Well With" card', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Works Well With')).toBeInTheDocument();
    });

    it('displays collaboration hints as badges', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('backend-engineer')).toBeInTheDocument();
      expect(screen.getByText('frontend-engineer')).toBeInTheDocument();
    });

    it('does not render collaboration hints card when empty', () => {
      render(
        <AgentTypeDetail
          {...defaultProps}
          agentType={{ ...mockAgentType, collaboration_hints: [] }}
        />
      );
      expect(screen.queryByText('Works Well With')).not.toBeInTheDocument();
    });
  });

  describe('Category Badge', () => {
    it('renders category badge with correct label', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Development')).toBeInTheDocument();
    });

    it('does not render category badge when category is null', () => {
      render(
        <AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, category: null }} />
      );
      // Should not have a Development badge in the hero header area
      // The word "Development" should not appear
      expect(screen.queryByText('Development')).not.toBeInTheDocument();
    });
  });

  describe('Details Card', () => {
    it('renders details card with slug', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Slug')).toBeInTheDocument();
      expect(screen.getByText('software-architect')).toBeInTheDocument();
    });

    it('renders details card with sort order', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Sort Order')).toBeInTheDocument();
      expect(screen.getByText('40')).toBeInTheDocument();
    });

    it('renders details card with creation date', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      expect(screen.getByText('Created')).toBeInTheDocument();
      expect(screen.getByText(/Jan 10, 2025/)).toBeInTheDocument();
    });
  });

  describe('Dynamic Icon', () => {
    it('renders fallback icon when icon is null', () => {
      const { container } = render(
        <AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, icon: null }} />
      );
      // Should fall back to 'bot' icon
      expect(container.querySelector('svg.lucide-bot')).toBeInTheDocument();
    });

    it('renders correct icon based on agent type', () => {
      const agentWithBrainIcon = { ...mockAgentType, icon: 'brain' };
      const { container } = render(
        <AgentTypeDetail {...defaultProps} agentType={agentWithBrainIcon} />
      );
      expect(container.querySelector('svg.lucide-brain')).toBeInTheDocument();
    });
  });

  describe('Color Styling', () => {
    it('applies custom color to instance count', () => {
      render(<AgentTypeDetail {...defaultProps} />);
      const instanceCount = screen.getByText('2');
      expect(instanceCount).toHaveStyle({ color: 'rgb(59, 130, 246)' });
    });

    it('uses default color when color is null', () => {
      render(<AgentTypeDetail {...defaultProps} agentType={{ ...mockAgentType, color: null }} />);
      // Should still render without errors
      expect(screen.getByText('Software Architect')).toBeInTheDocument();
    });
  });
});
