// Mock react-native BEFORE importing the SDK — `../NamiFlowManager` resolves
// the native module via TurboModuleRegistry at import time, and the
// NativeEventEmitter constructor is called at module top-level.

const registerStepHandoff = jest.fn();
const unregisterStepHandoff = jest.fn();
const registerEventHandler = jest.fn();
const unregisterEventHandler = jest.fn();
const finishMock = jest.fn();
const isFlowOpenMock = jest.fn().mockResolvedValue(false);
const resumeMock = jest.fn();
const pauseMock = jest.fn();

const subRemove = jest.fn();
const addListener = jest.fn(() => ({ remove: subRemove }));

jest.mock('react-native', () => ({
  TurboModuleRegistry: {
    getEnforcing: jest.fn(() => ({
      registerStepHandoff,
      unregisterStepHandoff,
      registerEventHandler,
      unregisterEventHandler,
      finish: finishMock,
      isFlowOpen: isFlowOpenMock,
      resume: resumeMock,
      pause: pauseMock,
    })),
  },
  NativeModules: {
    RNNamiFlowManager: {
      registerStepHandoff,
      unregisterStepHandoff,
      registerEventHandler,
      unregisterEventHandler,
    },
  },
  NativeEventEmitter: jest.fn().mockImplementation(() => ({
    addListener,
  })),
}));

import { NamiFlowManager } from '../NamiFlowManager';

describe('NamiFlowManager (React Native bridge)', () => {
  beforeEach(() => {
    registerStepHandoff.mockClear();
    unregisterStepHandoff.mockClear();
    registerEventHandler.mockClear();
    unregisterEventHandler.mockClear();
    subRemove.mockClear();
    addListener.mockClear();
  });

  describe('registerStepHandoff', () => {
    it('returns a function and triggers native register', () => {
      const unsubscribe = NamiFlowManager.registerStepHandoff(() => {});
      expect(typeof unsubscribe).toBe('function');
      expect(registerStepHandoff).toHaveBeenCalledTimes(1);
      expect(addListener).toHaveBeenCalledTimes(1);
    });

    it('returned unsubscribe removes the JS listener AND calls native unregister', () => {
      const unsubscribe = NamiFlowManager.registerStepHandoff(() => {});
      unsubscribe();

      expect(subRemove).toHaveBeenCalledTimes(1);
      expect(unregisterStepHandoff).toHaveBeenCalledTimes(1);
    });
  });

  describe('registerEventHandler', () => {
    it('returns a function and triggers native register', () => {
      const unsubscribe = NamiFlowManager.registerEventHandler(() => {});
      expect(typeof unsubscribe).toBe('function');
      expect(registerEventHandler).toHaveBeenCalledTimes(1);
      expect(addListener).toHaveBeenCalledTimes(1);
    });

    it('returned unsubscribe removes the JS listener AND calls native unregister', () => {
      const unsubscribe = NamiFlowManager.registerEventHandler(() => {});
      unsubscribe();

      expect(subRemove).toHaveBeenCalledTimes(1);
      expect(unregisterEventHandler).toHaveBeenCalledTimes(1);
    });
  });
});
