import { describe, expect, it, vi } from 'vitest';
import { buildEmptyMenuItems } from './treeMenus';

const ctx = (overrides = {}) => ({
  tab: 'workspace',
  isTauri: true,
  hasWorkspace: true,
  fileManagerLabel: 'Show in File Manager',
  canRefresh: true,
  canNewFolder: true,
  onNewFolder: vi.fn(),
  onReveal: vi.fn(),
  onCopyPath: vi.fn(),
  onSelectAll: vi.fn(),
  onExpandAll: vi.fn(),
  onCollapseAll: vi.fn(),
  onRefresh: vi.fn(),
  ...overrides,
});

const labels = (items) => items.filter((i) => !i.separator).map((i) => i.label);
const byKey = (items, key) => items.find((i) => i.key === key);

describe('buildEmptyMenuItems', () => {
  it('offers only container-scoped actions, never selection-scoped ones', () => {
    const found = labels(buildEmptyMenuItems(ctx()));
    // Right-clicking nothing must not offer to act on a selection.
    for (const gone of ['Pull Latest', 'Submit', 'Checkout', 'Delete', 'Revert']) {
      expect(found).not.toContain(gone);
    }
    expect(found).toEqual([
      'New Folder…',
      'Show in File Manager',
      'Copy Path',
      'Select All',
      'Expand All',
      'Collapse All',
      'Refresh',
    ]);
  });

  it('offers New Folder first on the Workspace tab', () => {
    const items = buildEmptyMenuItems(ctx());
    expect(items[0].key).toBe('newFolder');
    expect(items[0].label).toBe('New Folder…');
    expect(items[1].separator).toBe(true);
  });

  it('omits New Folder on the Server tab', () => {
    // Cambium stores no empty directories, so a folder created on the server
    // side would have nothing to represent.
    expect(byKey(buildEmptyMenuItems(ctx({ tab: 'repo' })), 'newFolder')).toBeUndefined();
  });

  it('omits New Folder on the web build and with no workspace folder', () => {
    expect(byKey(buildEmptyMenuItems(ctx({ isTauri: false })), 'newFolder')).toBeUndefined();
    expect(byKey(buildEmptyMenuItems(ctx({ hasWorkspace: false })), 'newFolder')).toBeUndefined();
  });

  it('uses the per-platform file manager label', () => {
    const items = buildEmptyMenuItems(ctx({ fileManagerLabel: 'Reveal in Finder' }));
    expect(byKey(items, 'reveal').label).toBe('Reveal in Finder');
  });

  it('greys out reveal when no workspace folder is set', () => {
    const items = buildEmptyMenuItems(ctx({ hasWorkspace: false }));
    expect(byKey(items, 'reveal').disabled).toBe(true);
  });

  it('greys out refresh while something is already running', () => {
    const items = buildEmptyMenuItems(ctx({ canRefresh: false }));
    expect(byKey(items, 'refresh').disabled).toBe(true);
  });

  it('greys out New Folder while a transfer is in flight', () => {
    const items = buildEmptyMenuItems(ctx({ canNewFolder: false }));
    const item = byKey(items, 'newFolder');
    expect(item).toBeDefined();
    expect(item.disabled).toBe(true);
  });

  it('enables New Folder when no transfer is in flight', () => {
    const items = buildEmptyMenuItems(ctx({ canNewFolder: true }));
    expect(byKey(items, 'newFolder').disabled).toBeFalsy();
  });

  it('drops the reveal item entirely on the web build', () => {
    const items = buildEmptyMenuItems(ctx({ isTauri: false }));
    expect(byKey(items, 'reveal')).toBeUndefined();
    expect(labels(items)).toEqual([
      'Copy Path',
      'Select All',
      'Expand All',
      'Collapse All',
      'Refresh',
    ]);
  });

  it('wires each item to its callback', () => {
    const c = ctx();
    const items = buildEmptyMenuItems(c);
    byKey(items, 'newFolder').onClick();
    byKey(items, 'selectAll').onClick();
    byKey(items, 'expandAll').onClick();
    byKey(items, 'refresh').onClick();
    expect(c.onNewFolder).toHaveBeenCalled();
    expect(c.onSelectAll).toHaveBeenCalled();
    expect(c.onExpandAll).toHaveBeenCalled();
    expect(c.onRefresh).toHaveBeenCalled();
  });

  it('differs from the Server tab by exactly the New Folder item', () => {
    const workspace = labels(buildEmptyMenuItems(ctx({ tab: 'workspace' })));
    const repo = labels(buildEmptyMenuItems(ctx({ tab: 'repo' })));
    expect(workspace.filter((l) => l !== 'New Folder…')).toEqual(repo);
  });
});
