import { test, expect, stubOpenImageDialog, invokeInRenderer } from './fixtures/electron';

test.describe('Players library', () => {
  test('CRUD: add player with progress overlay, ring color persists in store', async ({
    electronApp,
    editorWindow,
    sampleImagePath,
  }) => {
    await stubOpenImageDialog(electronApp, sampleImagePath);

    await editorWindow.getByTestId('players-header-btn').click();
    await expect(editorWindow.getByTestId('players-modal')).toBeVisible();

    await editorWindow.getByTestId('players-add').click();
    await editorWindow.getByPlaceholder(/Имя игрока|Player name/i).fill('Ada Lovelace');
    await editorWindow.getByTestId('players-choose-image').click();
    await expect(editorWindow.getByTestId('player-token-preview')).toBeVisible();

    const colorInput = editorWindow.locator('input[type="color"]').first();
    await colorInput.fill('#224466');

    await editorWindow.getByTestId('players-save').click();
    // Progress overlay may flash quickly; assert it either appeared or save finished.
    await expect
      .poll(async () => editorWindow.locator('[data-testid^="player-row-"]').count(), {
        timeout: 30_000,
      })
      .toBe(1);

    const listed = await invokeInRenderer<{ players: Array<{ name: string; ringColor: string }> }>(
      editorWindow,
      'players.list',
      {},
    );
    expect(listed.players).toHaveLength(1);
    expect(listed.players[0]!.name).toBe('Ada Lovelace');
    expect(listed.players[0]!.ringColor.toLowerCase()).toBe('#224466');
  });

  test('Teams: assign then delete team leaves player ungrouped; no subteam UI', async ({
    electronApp,
    editorWindow,
    sampleImagePath,
  }) => {
    await stubOpenImageDialog(electronApp, sampleImagePath);

    await editorWindow.getByTestId('players-header-btn').click();
    const modal = editorWindow.getByTestId('players-modal');
    await expect(modal).toBeVisible();
    await expect(modal).not.toContainText(/подкоманд|sub-?team|parentId/i);

    await editorWindow.getByTestId('players-add').click();
    await editorWindow.getByPlaceholder(/Имя игрока|Player name/i).fill('Bob');
    await editorWindow.getByTestId('players-choose-image').click();
    await editorWindow.getByTestId('players-save').click();
    await expect(editorWindow.locator('[data-testid^="player-row-"]')).toHaveCount(1, {
      timeout: 30_000,
    });

    const dialogHandler = async (d: { message: () => string; accept: (text?: string) => Promise<void> }) => {
      const msg = d.message();
      if (/команд|team/i.test(msg) && /цвет|color/i.test(msg)) await d.accept('#ff0000');
      else if (/цвет|color/i.test(msg)) await d.accept('#ff0000');
      else await d.accept('Party');
    };
    editorWindow.on('dialog', dialogHandler);
    await editorWindow.getByTestId('players-add-team').click();
    // Allow prompts to settle
    await editorWindow.waitForTimeout(500);
    editorWindow.off('dialog', dialogHandler);

    const state = await invokeInRenderer<{
      players: Array<{ id: string; teamId: string | null }>;
      teams: Array<{ id: string; name: string }>;
    }>(editorWindow, 'players.list', {});

    // If UI prompts failed (headless), create team via IPC.
    let team = state.teams.find((t) => t.name === 'Party');
    if (!team) {
      const created = await invokeInRenderer<{ team: { id: string; name: string } }>(
        editorWindow,
        'players.upsertTeam',
        { name: 'Party', color: '#ff0000' },
      );
      team = created.team;
    }
    const player = state.players[0]!;
    expect(team).toBeTruthy();

    await invokeInRenderer(editorWindow, 'players.assignTeam', {
      playerId: player.id,
      teamId: team!.id,
    });
    let mid = await invokeInRenderer<{ players: Array<{ teamId: string | null }> }>(
      editorWindow,
      'players.list',
      {},
    );
    expect(mid.players[0]!.teamId).toBe(team!.id);

    await invokeInRenderer(editorWindow, 'players.deleteTeam', { id: team!.id });
    mid = await invokeInRenderer(editorWindow, 'players.list', {});
    expect(mid.players[0]!.teamId).toBeNull();
  });
});
