import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { QuestFilterBar } from '../../src/components/QuestFilterBar';
import { Quest, Location } from '../../src/types';

const mockLocations: Location[] = [
  { id: 1, name: 'Rivendell', description: 'A hidden valley' },
  { id: 2, name: 'Mordor', description: 'The dark realm' },
  { id: 3, name: 'Moria', description: 'Deep dwarf kingdom' },
];

const mockQuests: Quest[] = [
  {
    id: 1,
    title: 'Test Quest 1',
    description: 'A test quest',
    status: 'not_yet_begun',
    quest_type: 'The Journey',
    priority: 'Important',
    location_id: 1,
    assignee_name: 'Frodo',
    completion_required_type: 'minigame',
    created_at: '2025-01-01T00:00:00Z',
    updated_at: '2025-01-01T00:00:00Z',
  },
  {
    id: 2,
    title: 'Test Quest 2',
    description: 'Another test quest',
    status: 'the_road_goes_ever_on',
    quest_type: 'The Fellowship',
    priority: 'Critical',
    location_id: 2,
    assignee_name: 'Legolas',
    completion_required_type: 'minigame',
    created_at: '2025-01-01T00:00:00Z',
    updated_at: '2025-01-01T00:00:00Z',
  },
  {
    id: 3,
    title: 'Test Quest 3',
    description: 'Completed quest',
    status: 'it_is_done',
    quest_type: 'The Battle',
    priority: 'Important',
    location_id: 1,
    assignee_name: 'Aragorn',
    completion_required_type: 'minigame',
    created_at: '2025-01-01T00:00:00Z',
    updated_at: '2025-01-01T00:00:00Z',
  },
  {
    id: 4,
    title: 'Test Quest 4',
    description: 'Blocked quest',
    status: 'the_shadow_falls',
    quest_type: 'The Ring',
    priority: 'Standard',
    location_id: 3,
    assignee_name: 'Gandalf',
    completion_required_type: 'minigame',
    created_at: '2025-01-01T00:00:00Z',
    updated_at: '2025-01-01T00:00:00Z',
  },
];

describe('QuestFilterBar', () => {
  const mockOnStatusChange = vi.fn();
  const mockOnTypeChange = vi.fn();
  const mockOnLocationChange = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should render filter categories', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    expect(screen.getByText('Quest Status')).toBeTruthy();
    expect(screen.getByText('Quest Type')).toBeTruthy();
    expect(screen.getByText('Location')).toBeTruthy();
  });

  it('should render status filter buttons when expanded', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    // Status is expanded by default
    expect(screen.getByText(/All Quests/)).toBeTruthy();
    expect(screen.getByText(/In Progress/)).toBeTruthy();
    expect(screen.getByText(/Completed/)).toBeTruthy();
    expect(screen.getByText(/Blocked/)).toBeTruthy();
  });

  it('should call onStatusChange when status filter is clicked', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    const completedButton = screen.getByRole('button', { name: /Completed/ });
    fireEvent.click(completedButton);

    expect(mockOnStatusChange).toHaveBeenCalledWith('it_is_done');
  });

  it('should toggle type filter category', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    // Initially type filters are not visible
    const typeHeaderButton = screen.getAllByText('Quest Type')[0].closest('button');
    expect(typeHeaderButton).toBeTruthy();

    // Click to expand
    fireEvent.click(typeHeaderButton!);

    // Now the type filters should be visible
    expect(screen.getByText(/The Journey/)).toBeTruthy();
    expect(screen.getByText(/The Fellowship/)).toBeTruthy();
    expect(screen.getByText(/The Battle/)).toBeTruthy();
    expect(screen.getByText(/The Ring/)).toBeTruthy();
  });

  it('should call onTypeChange when quest type filter is clicked', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    // Expand type filters
    const typeHeaderButton = screen.getAllByText('Quest Type')[0].closest('button');
    fireEvent.click(typeHeaderButton!);

    const journeyButton = screen.getByRole('button', { name: /The Journey/ });
    fireEvent.click(journeyButton);

    expect(mockOnTypeChange).toHaveBeenCalledWith('The Journey');
  });

  it('should toggle location filter category', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    // Expand location filters
    const locationHeaderButton = screen.getAllByText('Location')[0].closest('button');
    expect(locationHeaderButton).toBeTruthy();

    fireEvent.click(locationHeaderButton!);

    // Now location options should be visible - use role buttons with name patterns
    expect(screen.getByRole('button', { name: /Rivendell/ })).toBeTruthy();
    expect(screen.getByRole('button', { name: /Mordor/ })).toBeTruthy();
    expect(screen.getByRole('button', { name: /Moria/ })).toBeTruthy();
  });

  it('should call onLocationChange when location filter is clicked', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    // Expand location filters
    const locationHeaderButton = screen.getAllByText('Location')[0].closest('button');
    fireEvent.click(locationHeaderButton!);

    const rivendellButton = screen.getByRole('button', { name: /Rivendell/ });
    fireEvent.click(rivendellButton);

    expect(mockOnLocationChange).toHaveBeenCalledWith(1);
  });

  it('should display correct quest counts for each filter', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    expect(screen.getByText(/All Quests \(4\)/)).toBeTruthy();
    expect(screen.getByText(/In Progress \(1\)/)).toBeTruthy();
    expect(screen.getByText(/Completed \(1\)/)).toBeTruthy();
    expect(screen.getByText(/Blocked \(1\)/)).toBeTruthy();
  });

  it('should highlight selected status filter', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus="it_is_done"
        selectedType={null}
        selectedLocation={null}
      />
    );

    const completedButton = screen.getByRole('button', { name: /Completed/ });
    expect(completedButton.className.includes('bg-forest')).toBeTruthy();
  });

  it('should highlight selected type filter', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType="The Journey"
        selectedLocation={null}
      />
    );

    // Expand type filters
    const typeHeaderButton = screen.getAllByText('Quest Type')[0].closest('button');
    fireEvent.click(typeHeaderButton!);

    const journeyButton = screen.getByRole('button', { name: /The Journey/ });
    expect(journeyButton.className.includes('bg-forest')).toBeTruthy();
  });

  it('should highlight selected location filter', () => {
    render(
      <QuestFilterBar
        quests={mockQuests}
        locations={mockLocations}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={1}
      />
    );

    // Expand location filters
    const locationHeaderButton = screen.getAllByText('Location')[0].closest('button');
    fireEvent.click(locationHeaderButton!);

    const rivendellButton = screen.getByRole('button', { name: /Rivendell/ });
    expect(rivendellButton.className.includes('bg-forest')).toBeTruthy();
  });

  it('should handle empty locations list gracefully', () => {
    const { container } = render(
      <QuestFilterBar
        quests={mockQuests}
        locations={[]}
        onStatusChange={mockOnStatusChange}
        onTypeChange={mockOnTypeChange}
        onLocationChange={mockOnLocationChange}
        selectedStatus={null}
        selectedType={null}
        selectedLocation={null}
      />
    );

    expect(screen.getByText('Quest Status')).toBeTruthy();
    expect(screen.getByText('Quest Type')).toBeTruthy();
    // Location category should not be rendered if no locations
    const locationHeaders = screen.queryAllByText('Location');
    expect(locationHeaders.length).toBe(0);
  });
});
