import type {Membership} from '@modules/chats/interfaces';
import {ChatUserStatus} from '@modules/chats/interfaces';

const mockGetNumMembers = jest.fn();
const mockGetShortGroupMemberships = jest.fn();

jest.mock('@modules/chats/db', () => ({
  getNumMembers: (...args: unknown[]) => mockGetNumMembers(...args),
}));

jest.mock('@modules/chats/db/services/groupMembershipService', () => ({
  getShortGroupMemberships: (...args: unknown[]) =>
    mockGetShortGroupMemberships(...args),
}));

describe('visibleChat store operations', () => {
  let visibleChatStore: typeof import('../visibleChat').visibleChatStore;

  beforeEach(() => {
    jest.resetModules();
    mockGetNumMembers.mockReset();
    mockGetShortGroupMemberships.mockReset();

    jest.isolateModules(() => {
      const store =
        // eslint-disable-next-line @typescript-eslint/no-var-requires
        require('../visibleChat') as typeof import('../visibleChat');
      ({visibleChatStore} = store);
    });

    visibleChatStore.setState({id: null, isChannel: false, groupInfo: null});
  });

  it('loads group info for the visible chat', async () => {
    const members: Membership[] = [
      {
        user: {
          id: 1,
          first_name: 'John',
          last_name: 'Doe',
          employee_internal_id: 'EMP-1',
          picture_asset_url: null,
          status: ChatUserStatus.Active,
          email: 'john@test.dev',
          version: 1,
        },
        is_admin: false,
        version: 1,
      },
      {
        user: {
          id: 2,
          first_name: 'Jane',
          last_name: 'Doe',
          employee_internal_id: 'EMP-2',
          picture_asset_url: null,
          status: ChatUserStatus.Active,
          email: 'jane@test.dev',
          version: 1,
        },
        is_admin: true,
        version: 1,
      },
    ];

    mockGetNumMembers.mockResolvedValue(2);
    mockGetShortGroupMemberships.mockResolvedValue({
      memberships: members,
      isUserAdmin: true,
    });

    await visibleChatStore.getState().getGroupInfo('channel-1');

    expect(mockGetNumMembers).toHaveBeenCalledWith('channel-1');
    expect(mockGetShortGroupMemberships).toHaveBeenCalledWith('channel-1');
    expect(visibleChatStore.getState().groupInfo).toEqual({
      totalMembers: 2,
      shortGroupMembers: members,
      isUserAdmin: true,
    });
  });

  it('keeps previous group info when loading fails', async () => {
    visibleChatStore.setState({
      groupInfo: {totalMembers: 1, shortGroupMembers: [], isUserAdmin: false},
    });

    mockGetNumMembers.mockRejectedValue(new Error('fail'));
    mockGetShortGroupMemberships.mockRejectedValue(new Error('fail'));

    await visibleChatStore.getState().getGroupInfo('channel-1');

    expect(visibleChatStore.getState().groupInfo).toEqual({
      totalMembers: 1,
      shortGroupMembers: [],
      isUserAdmin: false,
    });
  });
});
