import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { SuggestionList, SuggestionSidebar } from '@/components/ai/SuggestionSidebar';

const mockSuggestions = [
  {
    id: 'sug1',
    entity_type: 'mail',
    entity_id: 'm1',
    suggestion_type: 'info',
    title: 'Email suggestion',
    content: 'You have an important email',
    confidence: 0.85,
    actions: [{ method: 'POST', path: '/mail/read', body: {}, description: 'Mark as read' }],
    created_at: '2024-01-01T00:00:00Z',
    is_dismissed: false,
    is_acted_upon: false,
  },
  {
    id: 'sug2',
    entity_type: 'task',
    entity_id: 't1',
    suggestion_type: 'warning',
    title: 'Task overdue',
    content: 'Task is overdue',
    confidence: 0.92,
    actions: [],
    created_at: '2024-01-01T00:00:00Z',
    is_dismissed: false,
    is_acted_upon: false,
  },
];

const apiGetMock = vi.fn();
const apiPostMock = vi.fn();
const apiPutMock = vi.fn();

vi.mock('@/api/client', () => ({
  apiClient: {
    get: (...args: any[]) => apiGetMock(...args),
    post: (...args: any[]) => apiPostMock(...args),
    put: (...args: any[]) => apiPutMock(...args),
  },
}));

beforeEach(() => {
  vi.clearAllMocks();
  apiGetMock.mockResolvedValue({ data: { items: mockSuggestions } });
  apiPostMock.mockResolvedValue({ data: {} });
  apiPutMock.mockResolvedValue({ data: {} });
});

describe('SuggestionList', () => {
  it('renders suggestion list container', async () => {
    render(<SuggestionList />);
    await waitFor(() => {
      expect(screen.getByTestId('suggestion-list')).toBeInTheDocument();
    });
  });

  it('renders suggestion titles', async () => {
    render(<SuggestionList />);
    await waitFor(() => {
      expect(screen.getByText('Email suggestion')).toBeInTheDocument();
      expect(screen.getByText('Task overdue')).toBeInTheDocument();
    });
  });

  it('renders filter buttons', async () => {
    render(<SuggestionList />);
    await waitFor(() => {
      expect(screen.getByText('Alle')).toBeInTheDocument();
      expect(screen.getByText('Info')).toBeInTheDocument();
      expect(screen.getByText('Warnung')).toBeInTheDocument();
    });
  });

  it('renders suggestion count', async () => {
    render(<SuggestionList />);
    await waitFor(() => {
      expect(screen.getByText(/2 Vorschläge/)).toBeInTheDocument();
    });
  });

  it('shows empty state when no suggestions', async () => {
    apiGetMock.mockResolvedValueOnce({ data: { items: [] } });
    render(<SuggestionList />);
    await waitFor(() => {
      expect(screen.getByText('Keine Vorschläge vorhanden')).toBeInTheDocument();
    });
  });

  it('filters suggestions by type', async () => {
    render(<SuggestionList />);
    await waitFor(() => {
      expect(screen.getByText('Email suggestion')).toBeInTheDocument();
    });
    fireEvent.click(screen.getByText('Warnung'));
    await waitFor(() => {
      expect(screen.getByText('Task overdue')).toBeInTheDocument();
      expect(screen.queryByText('Email suggestion')).not.toBeInTheDocument();
    });
  });
});

describe('SuggestionSidebar', () => {
  it('renders sidebar with close button when open', async () => {
    render(<SuggestionSidebar isOpen={true} onClose={vi.fn()} />);
    await waitFor(() => {
      expect(screen.getByText('KI Vorschläge')).toBeInTheDocument();
      expect(screen.getAllByText('✕').length).toBeGreaterThan(0);
    });
  });

  it('calls onClose when close button clicked', async () => {
    const onClose = vi.fn();
    render(<SuggestionSidebar isOpen={true} onClose={onClose} />);
    await waitFor(() => {
      expect(screen.getByText('KI Vorschläge')).toBeInTheDocument();
    });
    // The close button is the first ✕ in the sidebar header
    const closeButtons = screen.getAllByText('✕');
    fireEvent.click(closeButtons[0]);
    expect(onClose).toHaveBeenCalled();
  });
});
