import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MessagingProvider } from '../provider';
import { MockAdapter } from '../adapters/mock';
import { Messenger } from './messenger';

function mount(adapter = new MockAdapter()) {
  render(
    <MessagingProvider adapter={adapter}>
      <Messenger />
    </MessagingProvider>,
  );
  return adapter;
}

describe('MockAdapter directory + openThread', () => {
  it('directory lists people you can message', async () => {
    const a = new MockAdapter();
    const people = await a.directory();
    expect(people.some((p) => p.name === 'Dan Whitaker')).toBe(true);
  });

  it('one participant opens a dm; two+ open a group with a subject', async () => {
    const a = new MockAdapter();
    const dm = await a.openThread({ participantIds: ['pp_dan'], membership: 'dm' });
    const list = await a.listConversations();
    expect(list.find((c) => c.threadId === dm.threadId)?.membership).toBe('dm');

    const group = await a.openThread({ participantIds: ['pp_dan', 'pp_priya'], membership: 'group', subject: 'Roof crew' });
    const g = (await a.listConversations()).find((c) => c.threadId === group.threadId);
    expect(g?.membership).toBe('group');
    expect(g?.title).toBe('Roof crew');
  });

  it('opening a dm with the same person reuses the existing thread', async () => {
    const a = new MockAdapter();
    const first = await a.openThread({ participantIds: ['pp_priya'], membership: 'dm' });
    const second = await a.openThread({ participantIds: ['pp_priya'], membership: 'dm' });
    expect(second.threadId).toBe(first.threadId);
  });
});

describe('<Messenger /> new conversation flow', () => {
  it('opens the picker from the Direct messages +, and starting a chat leaves the picker', async () => {
    mount();
    // Open the "New message" picker.
    fireEvent.click(await screen.findByTitle('New message'));
    expect(await screen.findByText('New message')).toBeTruthy();

    // Pick a person and start a DM.
    fireEvent.click(await screen.findByText('Dan Whitaker'));
    fireEvent.click(screen.getByText('Start chat'));

    // The picker closes (we're back in a thread view — the picker heading is gone).
    await waitFor(() => expect(screen.queryByText('Start chat')).toBeNull());
  });

  it('selecting two people switches the action to group create', async () => {
    mount();
    fireEvent.click(await screen.findByTitle('New message'));
    fireEvent.click(await screen.findByText('Dan Whitaker'));
    fireEvent.click(await screen.findByText('Priya Nair'));
    expect(screen.getByText(/Create group \(2\)/)).toBeTruthy();
    expect(screen.getByLabelText('Group name')).toBeTruthy();
  });
});
