// FE-COMP-SCOPE-001 to FE-COMP-SCOPE-009
import { render, screen, waitFor } from '../../../tests/helpers/render';
import userEvent from '@testing-library/user-event';
import { resetAllStores } from '../../../tests/helpers/store';
import ScopeGroupPicker from './ScopeGroupPicker';

beforeEach(() => {
  resetAllStores();
});

describe('ScopeGroupPicker', () => {
  it('FE-COMP-SCOPE-001: renders scope groups', () => {
    render(<ScopeGroupPicker selected={[]} onChange={vi.fn()} />);
    // Several group headers should be visible
    expect(screen.getAllByRole('button').length).toBeGreaterThan(0);
  });

  it('FE-COMP-SCOPE-002: shows Select All button when nothing selected', () => {
    render(<ScopeGroupPicker selected={[]} onChange={vi.fn()} />);
    expect(screen.getByRole('button', { name: /select all/i })).toBeInTheDocument();
  });

  it('FE-COMP-SCOPE-003: Select All calls onChange with all scopes', async () => {
    const user = userEvent.setup();
    const onChange = vi.fn();
    render(<ScopeGroupPicker selected={[]} onChange={onChange} />);
    await user.click(screen.getByRole('button', { name: /select all/i }));
    expect(onChange).toHaveBeenCalledTimes(1);
    const called = onChange.mock.calls[0][0] as string[];
    expect(called.length).toBeGreaterThan(0);
  });

  it('FE-COMP-SCOPE-004: shows Deselect All button when all selected', async () => {
    // First collect all scopes by clicking Select All and capturing the callback
    const user = userEvent.setup();
    const captured: string[][] = [];
    const { rerender } = render(
      <ScopeGroupPicker selected={[]} onChange={s => captured.push(s)} />
    );
    await user.click(screen.getByRole('button', { name: /select all/i }));
    const allScopes = captured[0];

    // Now rerender with all scopes selected
    rerender(<ScopeGroupPicker selected={allScopes} onChange={vi.fn()} />);
    expect(screen.getByRole('button', { name: /deselect all/i })).toBeInTheDocument();
  });

  it('FE-COMP-SCOPE-005: Deselect All calls onChange with empty array', async () => {
    const user = userEvent.setup();
    const captured: string[][] = [];

    // Get all scopes first
    const { rerender } = render(
      <ScopeGroupPicker selected={[]} onChange={s => captured.push(s)} />
    );
    await user.click(screen.getByRole('button', { name: /select all/i }));
    const allScopes = captured[0];

    const onChange = vi.fn();
    rerender(<ScopeGroupPicker selected={allScopes} onChange={onChange} />);
    await user.click(screen.getByRole('button', { name: /deselect all/i }));
    expect(onChange).toHaveBeenCalledWith([]);
  });

  it('FE-COMP-SCOPE-006: expanding a group reveals individual scope checkboxes', async () => {
    const user = userEvent.setup();
    render(<ScopeGroupPicker selected={[]} onChange={vi.fn()} />);

    // Groups are collapsed by default — checkboxes for individual scopes not visible
    const groupToggles = screen.getAllByRole('button').filter(b =>
      !b.textContent?.toLowerCase().includes('select all') &&
      !b.textContent?.toLowerCase().includes('deselect all')
    );
    // Click the first group expand button
    await user.click(groupToggles[0]);
    // Individual scope checkboxes should now appear (more than just group-level ones)
    const checkboxes = screen.getAllByRole('checkbox');
    expect(checkboxes.length).toBeGreaterThan(0);
  });

  it('FE-COMP-SCOPE-007: group checkbox selects all scopes in the group', async () => {
    const user = userEvent.setup();
    const onChange = vi.fn();
    render(<ScopeGroupPicker selected={[]} onChange={onChange} />);

    const groupCheckboxes = screen.getAllByRole('checkbox');
    await user.click(groupCheckboxes[0]);
    expect(onChange).toHaveBeenCalledTimes(1);
    const called = onChange.mock.calls[0][0] as string[];
    expect(called.length).toBeGreaterThan(0);
  });

  it('FE-COMP-SCOPE-008: individual scope toggle adds/removes that scope', async () => {
    const user = userEvent.setup();
    const onChange = vi.fn();
    render(<ScopeGroupPicker selected={[]} onChange={onChange} />);

    // Expand first group
    const groupToggles = screen.getAllByRole('button').filter(b =>
      !b.textContent?.toLowerCase().includes('select all') &&
      !b.textContent?.toLowerCase().includes('deselect all')
    );
    await user.click(groupToggles[0]);

    // There are now individual scope checkboxes — click the second one (first is group-level)
    const checkboxes = screen.getAllByRole('checkbox');
    await user.click(checkboxes[1]); // individual scope
    expect(onChange).toHaveBeenCalledTimes(1);
  });

  it('FE-COMP-SCOPE-009: count badge shown when some scopes selected in group', () => {
    // Get any single scope key from the first group via Select All trick + manual slice
    // We'll just select a scope by triggering group checkbox and passing it in
    const firstGroupScope = 'trips:read'; // known scope from SCOPE_GROUPS
    render(<ScopeGroupPicker selected={[firstGroupScope]} onChange={vi.fn()} />);
    // Count badge like "(1/N)" should be visible
    expect(screen.getByText(/\(\d+\/\d+\)/)).toBeInTheDocument();
  });
});
