// @vitest-environment jsdom
/**
 * Component tests for FilterBar — the search box, sort menu, and status filter
 * tabs that drive the task list. Verifies counts render, callbacks fire on user
 * interaction (search input, status tab click, sort selection), and aria state
 * reflects the current selection.
 */
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'; // initialize i18next so useTranslation('list') resolves
import { FilterBar } from './FilterBar';

function baseProps(overrides: Record<string, unknown> = {}) {
  return {
    selectedStatus: 'all' as const,
    sortMode: 'updated' as const,
    searchQuery: '',
    counts: { running: 2, failed: 1, queued: 5 },
    totalCount: 8,
    onStatusChange: vi.fn(),
    onSortChange: vi.fn(),
    onSearchChange: vi.fn(),
    ...overrides,
  };
}

describe('FilterBar', () => {
  it('renders the total count on the All tab and per-status counts', () => {
    renderWithProviders(<FilterBar {...baseProps()} />);
    const allTab = screen.getByRole('tab', { name: /All/ });
    expect(allTab).toHaveTextContent('8');
    // Running status tab shows its count from the counts map.
    const runningTab = screen.getByRole('tab', { name: /Running/ });
    expect(runningTab).toHaveTextContent('2');
  });

  it('marks the selected status tab as aria-selected', () => {
    renderWithProviders(<FilterBar {...baseProps({ selectedStatus: 'running' })} />);
    expect(screen.getByRole('tab', { name: /Running/ })).toHaveAttribute('aria-selected', 'true');
    expect(screen.getByRole('tab', { name: /All/ })).toHaveAttribute('aria-selected', 'false');
  });

  it('calls onSearchChange as the user types in the search box', async () => {
    const user = userEvent.setup();
    const props = baseProps();
    renderWithProviders(<FilterBar {...props} />);
    const input = screen.getByRole('textbox', { name: /Search/i });
    await user.type(input, 'a');
    expect(props.onSearchChange).toHaveBeenCalledWith('a');
  });

  it('calls onStatusChange when a status tab is clicked', async () => {
    const user = userEvent.setup();
    const props = baseProps();
    renderWithProviders(<FilterBar {...props} />);
    await user.click(screen.getByRole('tab', { name: /Failed/ }));
    expect(props.onStatusChange).toHaveBeenCalledWith('failed');
  });

  it('opens the sort menu and calls onSortChange with the picked mode', async () => {
    const user = userEvent.setup();
    const props = baseProps();
    renderWithProviders(<FilterBar {...props} />);
    // Sort menu is collapsed initially.
    const trigger = screen.getByRole('button', { name: /Sort/i });
    expect(trigger).toHaveAttribute('aria-expanded', 'false');
    await user.click(trigger);
    expect(trigger).toHaveAttribute('aria-expanded', 'true');
    // Pick "By title".
    const menu = trigger.closest('div')!;
    await user.click(within(menu).getByRole('button', { name: 'By title' }));
    expect(props.onSortChange).toHaveBeenCalledWith('title');
  });
});
