import assert from 'node:assert/strict';
import test from 'node:test';
import { composeIpcRuntimeHandlers } from './ipc-runtime-composer';

test('composeIpcRuntimeHandlers returns callable IPC handlers and registration bridge', async () => {
  let registered = false;
  let receivedReferenceTrackId: number | null | undefined;

  const composed = composeIpcRuntimeHandlers({
    mpvCommandMainDeps: {
      triggerSubsyncFromConfig: async () => {},
      openRuntimeOptionsPalette: () => {},
      openJimaku: () => {},
      openTsukihime: () => {},
      openYoutubeTrackPicker: () => {},
      openPlaylistBrowser: () => {},
      cycleRuntimeOption: () => ({ ok: true }),
      showMpvOsd: () => {},
      replayCurrentSubtitle: () => {},
      playNextSubtitle: () => {},
      sendMpvCommand: () => {},
      getMpvClient: () => null,
      isMpvConnected: () => false,
      hasRuntimeOptionsManager: () => true,
    },
    handleMpvCommandFromIpcRuntime: () => {},
    runSubsyncManualFromIpc: async (request) => {
      receivedReferenceTrackId = request.referenceTrackId;
      return {
        ok: true,
        message: 'ok',
      };
    },
    registration: {
      runtimeOptions: {
        getRuntimeOptionsManager: () => null,
        showMpvOsd: () => {},
      },
      mainDeps: {
        getMainWindow: () => null,
        getVisibleOverlayVisibility: () => false,
        focusMainWindow: () => {},
        onOverlayModalClosed: () => {},
        openYomitanSettings: () => {},
        quitApp: () => {},
        toggleVisibleOverlay: () => {},
        tokenizeCurrentSubtitle: async () => null,
        getCurrentSubtitleRaw: () => '',
        getCurrentSubtitleAss: () => '',
        getPlaybackPaused: () => null,
        getSubtitlePosition: () => ({}) as never,
        getSubtitleStyle: () => ({}) as never,
        saveSubtitlePosition: () => {},
        getMecabTokenizer: () => null,
        getKeybindings: () => [],
        getSessionBindings: () => [],
        getConfiguredShortcuts: () => ({}) as never,
        dispatchSessionAction: async () => {},
        getStatsToggleKey: () => 'Backquote',
        getMarkWatchedKey: () => 'KeyW',
        getOverlayNotificationPosition: () => 'top-right',
        getControllerConfig: () => ({}) as never,
        saveControllerConfig: () => {},
        saveControllerPreference: () => {},
        getSecondarySubMode: () => 'hover' as never,
        getMpvClient: () => null,
        getAnkiConnectStatus: () => false,
        getRuntimeOptions: () => [],
        reportOverlayContentBounds: () => {},
        getAnilistStatus: () => ({}) as never,
        clearAnilistToken: () => {},
        openAnilistSetup: () => {},
        getAnilistQueueStatus: () => ({}) as never,
        retryAnilistQueueNow: async () => ({ ok: true, message: 'ok' }),
        appendClipboardVideoToQueue: () => ({ ok: true, message: 'ok' }),
        getPlaylistBrowserSnapshot: async () =>
          ({
            directoryPath: null,
            directoryAvailable: false,
            directoryStatus: '',
            directoryItems: [],
            playlistItems: [],
            playingIndex: null,
            currentFilePath: null,
          }) as never,
        appendPlaylistBrowserFile: async () => ({ ok: true, message: 'ok' }),
        playPlaylistBrowserIndex: async () => ({ ok: true, message: 'ok' }),
        removePlaylistBrowserIndex: async () => ({ ok: true, message: 'ok' }),
        movePlaylistBrowserIndex: async () => ({ ok: true, message: 'ok' }),
        onYoutubePickerResolve: async () => ({ ok: true, message: 'ok' }),
      },
      ankiJimakuDeps: {
        patchAnkiConnectEnabled: () => {},
        getResolvedConfig: () => ({}) as never,
        getRuntimeOptionsManager: () => null,
        getSubtitleTimingTracker: () => null,
        getMpvClient: () => null,
        getAnkiIntegration: () => null,
        setAnkiIntegration: () => {},
        getKnownWordCacheStatePath: () => '',
        showDesktopNotification: () => {},
        createFieldGroupingCallback: () => (() => {}) as never,
        broadcastRuntimeOptionsChanged: () => {},
        getFieldGroupingResolver: () => null,
        setFieldGroupingResolver: () => {},
        parseMediaInfo: () => ({}) as never,
        getCurrentMediaPath: () => null,
        jimakuFetchJson: async () => ({ data: null }) as never,
        getJimakuMaxEntryResults: () => 0,
        getJimakuLanguagePreference: () => 'ja' as never,
        resolveJimakuApiKey: async () => null,
        isRemoteMediaPath: () => false,
        downloadToFile: async () => ({ ok: true, path: '/tmp/file' }),
      },
      registerIpcRuntimeServices: () => {
        registered = true;
      },
    },
  });

  assert.equal(typeof composed.handleMpvCommandFromIpc, 'function');
  assert.equal(typeof composed.runSubsyncManualFromIpc, 'function');
  assert.equal(typeof composed.registerIpcRuntimeHandlers, 'function');

  const result = await composed.runSubsyncManualFromIpc({
    engine: 'alass',
    referenceTrackId: 7,
  });
  assert.deepEqual(result, { ok: true, message: 'ok' });
  assert.equal(receivedReferenceTrackId, 7);

  composed.registerIpcRuntimeHandlers();
  assert.equal(registered, true);
});
