import reactNativePackageJson from 'react-native/package.json';
import { DxaReactNative } from './DxaReactNative';
import type {
  DxaConfiguration,
  InitializationResult,
  LogErrorResult,
  LogTag,
  SessionCloseResult,
  SessionPauseResult,
  SessionResumeResult,
  SessionStartResult,
} from './NativeDxaReactNative';
import { SDKVersion } from './SDKVersion';
import {
  startNavigationTracking,
  stopNavigationTracking,
} from './navigationTracking/automatic/automaticNavigationTracking';

/**
 * Initializes the SDK.
 *
 * @param {string} brandId - The brand identifier obtained from your project settings.
 * @param {string} projectId - The project identifier obtained from your project settings.
 * @returns {InitializationResult} - An object containing the result of the initialization process.
 */
export function initializeProject(
  brandId: string,
  projectId: string
): InitializationResult {
  const sdkVersion = SDKVersion.value;
  const reactNativeVersion = reactNativePackageJson.version;
  return DxaReactNative.initializeProject(
    brandId,
    projectId,
    sdkVersion,
    reactNativeVersion
  );
}

/**
 * Sets the logging tags used for categorizing logs.
 * This can help filter logs by specific categories in native logging tools.
 *
 * @param {LogTag[]} tags - An array of log tags to be set.
 * @returns {LogTag[]} - An array of the tags that have been successfully set.
 */
export function setLoggingTags(tags: LogTag[]): LogTag[] {
  return DxaReactNative.setLoggingTags(tags);
}

/**
 * Attempts to start a new recording session.
 *
 * @param {DxaConfiguration} [config] - Optional configuration settings for the recording.
 * @returns {Promise<SessionStartResult>} - A promise that resolves with details about the start of the session.
 */
export async function startRecording(
  config?: DxaConfiguration
): Promise<SessionStartResult> {
  const nativeConfig = {
    customViewTypesToMask: config?.customViewTypesToMask,
  };

  const result = await DxaReactNative.startRecording(nativeConfig);
  if (result.result.toLowerCase() === 'success' && config?.navigationRef) {
    startNavigationTracking(config.navigationRef);
  }

  return result;
}

/**
 * Attempts to stop the current recording session.
 *
 * @returns {Promise<SessionCloseResult>} - A promise that resolves with details of the session's closure.
 */
export async function stopRecording(): Promise<SessionCloseResult> {
  stopNavigationTracking();
  return DxaReactNative.stopRecording();
}

/**
 * Attempts to pause the current recording session.
 * This can be useful for temporarily halting recording without ending the session.
 *
 * @returns {SessionPauseResult} - The result of the pause operation.
 */
export async function pauseRecording(): Promise<SessionPauseResult> {
  return await DxaReactNative.pauseRecording();
}

/**
 * Attempts to resume the current recording session.
 *
 * @returns {SessionResumeResult} - The result of the resume operation.
 */
export async function resumeRecording(): Promise<SessionResumeResult> {
  return await DxaReactNative.resumeRecording();
}

/**
 * Attempt to LogError.
 * If a click happened it will be associated with this error to report Error click
 *
 * @param {string} [message] - The error message to log.
 * @returns {LogErrorResult} - The result of the error logging operation.
 */
export function logError(message?: string): LogErrorResult {
  return DxaReactNative.logError(message);
}

export {
  reportScreenAppearance,
  reportScreenChange,
  reportScreenDisappearance,
} from './navigationTracking/manual/manualNavigationTracking';

export { LOG_TAGS } from './NativeDxaReactNative';

export type {
  DxaConfiguration,
  InitializationResult,
  LogErrorResult,
  LogTag,
  SessionCloseResult,
  SessionPauseResult,
  SessionResumeResult,
  SessionStartResult,
};
