/**
 * IssueFilters Component Tests
 */

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { IssueFilters } from '@/features/issues/components/IssueFilters';
import type { IssueFilters as IssueFiltersType } from '@/features/issues/types';

describe('IssueFilters', () => {
  const defaultFilters: IssueFiltersType = {
    status: 'all',
    priority: 'all',
    sprint: 'all',
    assignee: 'all',
  };

  const mockOnFiltersChange = jest.fn();

  beforeEach(() => {
    mockOnFiltersChange.mockClear();
  });

  it('renders search input', () => {
    render(<IssueFilters filters={defaultFilters} onFiltersChange={mockOnFiltersChange} />);

    expect(screen.getByPlaceholderText('Search issues...')).toBeInTheDocument();
  });

  it('calls onFiltersChange when search changes', async () => {
    const user = userEvent.setup();
    render(<IssueFilters filters={defaultFilters} onFiltersChange={mockOnFiltersChange} />);

    const searchInput = screen.getByPlaceholderText('Search issues...');
    await user.type(searchInput, 'test');

    // onFiltersChange should be called at least once
    expect(mockOnFiltersChange).toHaveBeenCalled();
    // The final state should contain the search term 'test' (may be in the last call)
    const allCalls = mockOnFiltersChange.mock.calls;
    const lastCall = allCalls[allCalls.length - 1][0];
    // The search value could include the typed characters
    expect(lastCall.search).toMatch(/t/);
  });

  it('renders status filter', () => {
    render(<IssueFilters filters={defaultFilters} onFiltersChange={mockOnFiltersChange} />);

    expect(screen.getByRole('combobox', { name: /filter by status/i })).toBeInTheDocument();
  });

  it('toggles extended filters when filter button is clicked', async () => {
    const user = userEvent.setup();
    render(<IssueFilters filters={defaultFilters} onFiltersChange={mockOnFiltersChange} />);

    // Extended filters should not be visible initially
    expect(screen.queryByLabelText('Priority')).not.toBeInTheDocument();

    // Click the filter toggle button
    const filterButton = screen.getByRole('button', { name: /toggle extended filters/i });
    await user.click(filterButton);

    // Extended filters should now be visible
    expect(screen.getByLabelText('Priority')).toBeInTheDocument();
    expect(screen.getByLabelText('Sprint')).toBeInTheDocument();
    expect(screen.getByLabelText('Assignee')).toBeInTheDocument();
  });

  it('shows clear filters button when filters are active', async () => {
    const user = userEvent.setup();
    const activeFilters: IssueFiltersType = {
      ...defaultFilters,
      status: 'open',
    };

    render(<IssueFilters filters={activeFilters} onFiltersChange={mockOnFiltersChange} />);

    // Open extended filters
    const filterButton = screen.getByRole('button', { name: /toggle extended filters/i });
    await user.click(filterButton);

    // Clear filters button should be visible
    expect(screen.getByRole('button', { name: /clear filters/i })).toBeInTheDocument();
  });

  it('clears filters when clear button is clicked', async () => {
    const user = userEvent.setup();
    const activeFilters: IssueFiltersType = {
      ...defaultFilters,
      status: 'open',
      search: 'test',
    };

    render(<IssueFilters filters={activeFilters} onFiltersChange={mockOnFiltersChange} />);

    // Open extended filters
    const filterButton = screen.getByRole('button', { name: /toggle extended filters/i });
    await user.click(filterButton);

    // Click clear filters
    const clearButton = screen.getByRole('button', { name: /clear filters/i });
    await user.click(clearButton);

    // Should call onFiltersChange with cleared filters
    expect(mockOnFiltersChange).toHaveBeenCalledWith({
      search: undefined,
      status: 'all',
      priority: 'all',
      sprint: 'all',
      assignee: 'all',
      labels: undefined,
    });
  });

  it('applies custom className', () => {
    const { container } = render(
      <IssueFilters
        filters={defaultFilters}
        onFiltersChange={mockOnFiltersChange}
        className="custom-class"
      />
    );

    expect(container.firstChild).toHaveClass('custom-class');
  });
});
