/* @vitest-environment jsdom */

import { act, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, test, vi } from 'vitest';

import App from './App';
import { AuthUiContext } from './components/auth/AuthUiContext';
import type { PlatformEntryFlowShellProps } from './components/platform-entry';

const appTitleMock = vi.hoisted(() => ({
  syncAppTitle: vi.fn(),
}));

vi.mock('./services/appTitle', async (importOriginal) => {
  const actual = await importOriginal<typeof import('./services/appTitle')>();
  return {
    ...actual,
    syncAppTitle: appTitleMock.syncAppTitle,
  };
});

vi.mock('./components/platform-entry/PlatformEntryFlowShell', () => ({
  PlatformEntryFlowShell: ({
    handleCustomWorldSelect,
    setSelectionStage,
  }: PlatformEntryFlowShellProps) => (
    <div>
      <button
        type="button"
        onClick={() => setSelectionStage('puzzle-agent-workspace')}
      >
        打开拼图创作
      </button>
      <button
        type="button"
        onClick={() =>
          handleCustomWorldSelect(
            {
              id: 'profile-1',
              name: '潮雾列岛',
            } as Parameters<
              PlatformEntryFlowShellProps['handleCustomWorldSelect']
            >[0],
          )
        }
      >
        进入 RPG
      </button>
    </div>
  ),
}));

vi.mock('./RpgRuntimeApp', () => ({
  RpgRuntimeApp: ({ onExitRuntime }: { onExitRuntime: () => void }) => (
    <button type="button" onClick={onExitRuntime}>
      退出 RPG
    </button>
  ),
}));

function renderApp() {
  return render(
    <AuthUiContext.Provider
      value={{
        canAccessProtectedData: false,
        isHydratingSettings: false,
        isPersistingSettings: false,
        logout: vi.fn(async () => undefined),
        musicVolume: 0.6,
        openAccountModal: vi.fn(),
        openLoginModal: vi.fn(),
        openSettingsModal: vi.fn(),
        platformTheme: 'light',
        requireAuth: vi.fn(),
        setCurrentUser: vi.fn(),
        setMusicVolume: vi.fn(),
        setPlatformTheme: vi.fn(),
        settingsError: null,
        user: null,
      }}
    >
      <App />
    </AuthUiContext.Provider>,
  );
}

afterEach(() => {
  appTitleMock.syncAppTitle.mockReset();
  window.history.replaceState(null, '', '/');
  vi.restoreAllMocks();
});

describe('App title sync', () => {
  test('主站阶段变化会同步浏览器与宿主标题', () => {
    renderApp();

    expect(appTitleMock.syncAppTitle).toHaveBeenLastCalledWith('陶泥儿');

    act(() => {
      fireEvent.click(screen.getByRole('button', { name: '打开拼图创作' }));
    });

    expect(appTitleMock.syncAppTitle).toHaveBeenLastCalledWith(
      '拼图创作 - 陶泥儿',
    );
  });

  test('RPG runtime 进入和退出时同步窗口标题', async () => {
    renderApp();

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: '进入 RPG' }));
    });

    expect(appTitleMock.syncAppTitle).toHaveBeenLastCalledWith(
      'RPG 运行中 - 陶泥儿',
    );

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: '退出 RPG' }));
    });

    expect(appTitleMock.syncAppTitle).toHaveBeenLastCalledWith('陶泥儿');
  });
});
