import '@angular/compiler';
import {
  describe,
  it,
  expect,
  vi
} from 'vitest';
import {
  Injector,
  runInInjectionContext,
  signal
} from '@angular/core';
import { Store } from '@ngrx/store';

import { FindPeopleComponent } from './find-people.component';
import { selectAllUsers } from '../../../../store/users/users.selectors';
import { selectSavedRooms } from '../../../../store/rooms/rooms.selectors';
import type { User, Room } from '../../../../shared-kernel';

interface HarnessOptions {
  users?: User[];
  saved?: Room[];
}

function createHarness(options: HarnessOptions = {}) {
  const usersSig = signal<User[]>(options.users ?? []);
  const savedSig = signal<Room[]>(options.saved ?? []);
  const store = {
    selectSignal: (selector: unknown) => {
      if (selector === selectAllUsers) {
        return usersSig;
      }

      if (selector === selectSavedRooms) {
        return savedSig;
      }

      return signal(null);
    },
    dispatch: vi.fn()
  } as unknown as Store;
  const injector = Injector.create({
    providers: [FindPeopleComponent, { provide: Store, useValue: store }]
  });
  const component = runInInjectionContext(injector, () => injector.get(FindPeopleComponent));

  return { component };
}

describe('FindPeopleComponent', () => {
  it('has no discoverable people for a brand-new account', () => {
    const { component } = createHarness();

    expect(component.hasDiscoverablePeople()).toBe(false);
  });

  it('reports discoverable people when users are known', () => {
    const { component } = createHarness({ users: [{ id: 'u1' } as unknown as User] });

    expect(component.hasDiscoverablePeople()).toBe(true);
  });

  it('reports discoverable people from saved-room members', () => {
    const { component } = createHarness({
      saved: [{ id: 'r1', members: [{ id: 'm1' }] } as unknown as Room]
    });

    expect(component.hasDiscoverablePeople()).toBe(true);
  });

  it('updates the search query', () => {
    const { component } = createHarness();

    component.onSearchChange('alice');

    expect(component.searchQuery()).toBe('alice');
  });
});
