// @vitest-environment jsdom
/**
 * Component tests for TaskListPanel — the list container that wires FilterBar +
 * TaskListItem to the filter/sort libs. Verifies the full task set renders, the
 * status filter narrows the rendered rows, the search query narrows them, the
 * empty-state shows when nothing matches, the summary header counts are correct,
 * and selecting a row fires onSelectTask with the task id.
 */
import '../../test/dom-setup';
import { describe, it, expect, vi } from 'vitest';
import { screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from '../../test/render-helpers';
import '../../i18n';
import type { LocalTask } from '../../api';
import { TaskListPanel } from './TaskListPanel';

function makeTask(id: number, title: string, status: string, body = ''): LocalTask {
  return {
    id,
    title,
    body,
    pieceName: 'chat',
    profile: 'default',
    outputFormat: 'markdown',
    askPolicy: 'auto',
    priority: 'normal',
    state: 'open',
    workspacePath: null,
    createdAt: '2026-06-01T00:00:00Z',
    updatedAt: `2026-06-0${id}T00:00:00Z`,
    latestJob: { id: `job-${id}`, status },
  };
}

const TASKS: LocalTask[] = [
  makeTask(1, 'Alpha report', 'running', 'first task body'),
  makeTask(2, 'Beta export', 'failed', 'second task body'),
  makeTask(3, 'Gamma sync', 'running', 'third task body'),
];

function baseProps(overrides: Record<string, unknown> = {}) {
  return {
    localTasks: TASKS,
    selectedStatus: 'all' as const,
    sortMode: 'updated' as const,
    searchQuery: '',
    activeTaskId: null,
    onStatusChange: vi.fn(),
    onSortChange: vi.fn(),
    onSearchChange: vi.fn(),
    onSelectTask: vi.fn(),
    onOpenCreate: vi.fn(),
    ...overrides,
  };
}

describe('TaskListPanel', () => {
  it('renders every task when status=all and no query', () => {
    renderWithProviders(<TaskListPanel {...baseProps()} />);
    expect(screen.getByText('Alpha report')).toBeInTheDocument();
    expect(screen.getByText('Beta export')).toBeInTheDocument();
    expect(screen.getByText('Gamma sync')).toBeInTheDocument();
  });

  it('filters the rendered rows by selected status', () => {
    renderWithProviders(<TaskListPanel {...baseProps({ selectedStatus: 'failed' })} />);
    expect(screen.getByText('Beta export')).toBeInTheDocument();
    expect(screen.queryByText('Alpha report')).not.toBeInTheDocument();
    expect(screen.queryByText('Gamma sync')).not.toBeInTheDocument();
  });

  it('filters the rendered rows by search query (title match)', () => {
    renderWithProviders(<TaskListPanel {...baseProps({ searchQuery: 'gamma' })} />);
    expect(screen.getByText('Gamma sync')).toBeInTheDocument();
    expect(screen.queryByText('Alpha report')).not.toBeInTheDocument();
    expect(screen.queryByText('Beta export')).not.toBeInTheDocument();
  });

  it('shows the empty-state when no task matches', () => {
    renderWithProviders(<TaskListPanel {...baseProps({ searchQuery: 'nonexistent-xyz' })} />);
    expect(screen.getByText('No threads yet')).toBeInTheDocument();
    expect(screen.queryByText('Alpha report')).not.toBeInTheDocument();
  });

  it('shows the summary header counts (total + running)', () => {
    renderWithProviders(<TaskListPanel {...baseProps()} />);
    // total = 3, running = 2. The summary header carries these.
    const allTab = screen.getByRole('tab', { name: /All/ });
    expect(allTab).toHaveTextContent('3');
    expect(screen.getByRole('tab', { name: /Running/ })).toHaveTextContent('2');
  });

  it('fires onSelectTask with the task id when a row is clicked', async () => {
    const user = userEvent.setup();
    const props = baseProps();
    renderWithProviders(<TaskListPanel {...props} />);
    await user.click(screen.getByText('Beta export'));
    expect(props.onSelectTask).toHaveBeenCalledWith(2);
  });

  it('fires onOpenCreate when the new-request button is clicked', async () => {
    const user = userEvent.setup();
    const props = baseProps();
    renderWithProviders(<TaskListPanel {...props} />);
    await user.click(screen.getByRole('button', { name: /New request/i }));
    expect(props.onOpenCreate).toHaveBeenCalledTimes(1);
  });

  it('renders the scope toggle only when scope is enabled', () => {
    const { rerender } = renderWithProviders(
      <TaskListPanel {...baseProps({ scopeEnabled: false })} />,
    );
    expect(screen.queryByRole('group', { name: /scope/i })).not.toBeInTheDocument();
    rerender(
      <TaskListPanel {...baseProps({ scopeEnabled: true, onScopeChange: vi.fn(), currentUserId: 'u1' })} />,
    );
    expect(screen.getByRole('group', { name: /scope/i })).toBeInTheDocument();
  });
});
