import {
  NativeEventEmitter,
  NativeModules,
  Platform,
  type EmitterSubscription,
} from 'react-native';

import type { AppRemarkTheme, EventInfo } from './types';

export * from './types';

const LINKING_ERROR =
  `The package 'appsonair-react-native-appremark' doesn't seem to be linked. Make sure: \n\n` +
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
  '- You rebuilt the app after installing the package\n' +
  '- You are not using Expo Go\n';

const AppsonairReactNativeAppremark =
  NativeModules.AppsonairReactNativeAppremark
    ? NativeModules.AppsonairReactNativeAppremark
    : new Proxy(
        {},
        {
          get() {
            throw new Error(LINKING_ERROR);
          },
        }
      );

const emitter = AppsonairReactNativeAppremark
  ? new NativeEventEmitter(AppsonairReactNativeAppremark)
  : null;

/**
 * Submits a bug or feedback to Appsonair.
 */
export const addRemark = () => {
  return AppsonairReactNativeAppremark.addRemark();
};

/**
 * Submits Additional MetaData with a bug or feedback to Appsonair.
 *
 * @param payload - The extra payload to send to Appsonair. Defaults to an empty object.
 */
export const setAdditionalMetaData = (payload?: object) => {
  const extraPayload = payload ?? {};
  return AppsonairReactNativeAppremark.setAdditionalMetaData(extraPayload);
};

/**
 * Initializes App Remark.
 *
 * @param shakeGestureEnable - Whether to enable the shake gesture for App Remark.
 * @param options - The theme options for App Remark.
 */
export const initialize = (
  shakeGestureEnable: boolean,
  options: AppRemarkTheme = {}
) => {
  return AppsonairReactNativeAppremark.initialize(shakeGestureEnable, options);
};

/**
 * Subscribes to remark response events emitted from the native AppRemark service.
 * This listener is triggered whenever the AppRemark SDK sends a response,
 * for example after submitting a remark or when an error occurs.
 *
 * @param callback - A function to handle incoming remark response events.
 */
export const onRemarkResponse = (
  callback: (event: EventInfo) => void
): EmitterSubscription | null => {
  return emitter?.addListener('onRemarkResponse', callback) ?? null;
};
