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

const mockSessions = [
  { id: 's1', title: 'First Chat', folder_id: null, agent_id: null, is_sidebar: false, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' },
  { id: 's2', title: 'Second Chat', folder_id: 'f1', agent_id: null, is_sidebar: false, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' },
];

const mockFolders = [
  { id: 'f1', name: 'My Folder', parent_id: null, created_at: '2024-01-01T00:00:00Z' },
];

const fetchSessionsMock = vi.fn();
const fetchFoldersMock = vi.fn();
const createSessionMock = vi.fn();
const deleteSessionMock = vi.fn();
const updateSessionMock = vi.fn();
const createFolderMock = vi.fn();
const deleteFolderMock = vi.fn();
const updateFolderMock = vi.fn();

vi.mock('@/api/ai', () => ({
  fetchSessions: (...args: any[]) => fetchSessionsMock(...args),
  fetchFolders: (...args: any[]) => fetchFoldersMock(...args),
  createSession: (...args: any[]) => createSessionMock(...args),
  deleteSession: (...args: any[]) => deleteSessionMock(...args),
  updateSession: (...args: any[]) => updateSessionMock(...args),
  createFolder: (...args: any[]) => createFolderMock(...args),
  deleteFolder: (...args: any[]) => deleteFolderMock(...args),
  updateFolder: (...args: any[]) => updateFolderMock(...args),
}));

beforeEach(() => {
  vi.clearAllMocks();
  fetchSessionsMock.mockResolvedValue(mockSessions);
  fetchFoldersMock.mockResolvedValue(mockFolders);
  createSessionMock.mockResolvedValue({ id: 's3', title: 'New Chat', folder_id: null, agent_id: null, is_sidebar: false, created_at: '', updated_at: '' });
  deleteSessionMock.mockResolvedValue({});
  updateSessionMock.mockResolvedValue({});
  createFolderMock.mockResolvedValue({ id: 'f2', name: 'New Folder', parent_id: null, created_at: '' });
  deleteFolderMock.mockResolvedValue({});
  updateFolderMock.mockResolvedValue({});
});

describe('SessionList', () => {
  it('renders session list with sessions', async () => {
    render(<SessionList activeSessionId="s1" onSelectSession={vi.fn()} />);
    await waitFor(() => {
      expect(screen.getByText('First Chat')).toBeInTheDocument();
    });
  });

  it('renders folder names', async () => {
    render(<SessionList activeSessionId="s1" onSelectSession={vi.fn()} />);
    await waitFor(() => {
      expect(screen.getByText('My Folder')).toBeInTheDocument();
    });
  });

  it('renders sessions inside folders', async () => {
    render(<SessionList activeSessionId="s1" onSelectSession={vi.fn()} />);
    await waitFor(() => {
      expect(screen.getByText('Second Chat')).toBeInTheDocument();
    });
  });

  it('calls onSelectSession when session clicked', async () => {
    const onSelect = vi.fn();
    render(<SessionList activeSessionId={null} onSelectSession={onSelect} />);
    await waitFor(() => {
      expect(screen.getByText('First Chat')).toBeInTheDocument();
    });
    fireEvent.click(screen.getByText('First Chat'));
    expect(onSelect).toHaveBeenCalledWith('s1');
  });

  it('shows loading state initially', () => {
    fetchSessionsMock.mockReturnValue(new Promise(() => {}));
    fetchFoldersMock.mockReturnValue(new Promise(() => {}));
    render(<SessionList activeSessionId={null} onSelectSession={vi.fn()} />);
    expect(screen.getByText('Laden...')).toBeInTheDocument();
  });

  it('displays error when fetch fails', async () => {
    fetchSessionsMock.mockRejectedValueOnce(new Error('Failed to load'));
    render(<SessionList activeSessionId={null} onSelectSession={vi.fn()} />);
    await waitFor(() => {
      expect(screen.getByText('Failed to load')).toBeInTheDocument();
    });
  });
});
