import {createRef} from 'react';
import {getAbsoluteSrc} from './absolute-src.js';
import {AudioForPreview} from './audio/AudioForPreview.js';
import type {ScheduleAudioNodeResult} from './audio/shared-audio-tags.js';
import {
	SharedAudioContext,
	SharedAudioContextProvider,
	type ScheduleAudioNodeOptions,
} from './audio/shared-audio-tags.js';
import {
	useFrameForVolumeProp,
	useMediaStartsAt,
} from './audio/use-audio-frame.js';
import {
	BufferingContextReact,
	BufferingProvider,
	useIsPlayerBuffering,
} from './buffering.js';
import {calculateMediaDuration} from './calculate-media-duration.js';
import {
	CanUseRemotionHooks,
	CanUseRemotionHooksProvider,
} from './CanUseRemotionHooks.js';
import {type CompProps} from './Composition.js';
import type {
	TCompMetadata,
	TComposition,
	TRenderAsset,
	TSequence,
} from './CompositionManager.js';
import {compositionsRef} from './CompositionManager.js';
import type {CompositionManagerContext} from './CompositionManagerContext.js';
import {
	CompositionManager,
	CompositionSetters,
} from './CompositionManagerContext.js';
import {CompositionManagerProvider} from './CompositionManagerProvider.js';
import * as CSSUtils from './default-css.js';
import {OBJECTFIT_CONTAIN_CLASS_NAME} from './default-css.js';
import {
	EditorPropsContext,
	EditorPropsProvider,
	timeValueRef,
} from './EditorProps.js';
import {
	addSequenceStackTraces,
	getComponentsToAddStacksTo,
} from './enable-sequence-stack-traces.js';
import {getEffectiveVisualModeValue} from './get-effective-visual-mode-value.js';
import {
	getPreviewDomElement,
	REMOTION_STUDIO_CONTAINER_ELEMENT,
} from './get-preview-dom-element.js';
import {getRemotionEnvironment} from './get-remotion-environment.js';
import {
	getInputPropsOverride,
	setInputPropsOverride,
} from './input-props-override.js';
import type {SerializedJSONWithCustomFields} from './input-props-serialization.js';
import {IsPlayerContextProvider, useIsPlayer} from './is-player.js';
import type {LoggingContextValue} from './log-level-context.js';
import {LogLevelContext, useLogLevel} from './log-level-context.js';
import {Log} from './log.js';
import {MaxMediaCacheSizeContext} from './max-video-cache-size.js';
import type {NonceHistory} from './nonce.js';
import {NonceContext} from './nonce.js';
import {playbackLogging} from './playback-logging.js';
import {portalNode} from './portal-node.js';
import {PrefetchProvider} from './prefetch-state.js';
import {usePreload} from './prefetch.js';
import {PremountContext} from './PremountContext.js';
import {getRoot, waitForRoot} from './register-root.js';
import type {RemotionEnvironment} from './remotion-environment-context.js';
import {RemotionEnvironmentContext} from './remotion-environment-context.js';
import {RemotionRootContexts} from './RemotionRoot.js';
import {
	RenderAssetManager,
	RenderAssetManagerProvider,
} from './RenderAssetManager.js';
import {
	resolveVideoConfig,
	resolveVideoConfigOrCatch,
} from './resolve-video-config.js';
import {
	ResolveCompositionContext,
	resolveCompositionsRef,
	useResolvedVideoConfig,
} from './ResolveCompositionConfig.js';
import type {
	SequenceFieldSchema,
	SequenceSchema,
} from './sequence-field-schema.js';
import type {ResolvedStackLocation} from './sequence-stack-traces.js';
import {SequenceStackTracesUpdateContext} from './sequence-stack-traces.js';
import {SequenceContext} from './SequenceContext.js';
import {
	VisualModeOverridesContext,
	SequenceManager,
	SequenceVisibilityToggleContext,
} from './SequenceManager.js';
import {setupEnvVariables} from './setup-env-variables.js';
import * as TimelinePosition from './timeline-position-state.js';
import {
	persistCurrentFrame,
	useTimelineContext,
	useTimelineSetFrame,
} from './timeline-position-state.js';
import {
	AbsoluteTimeContext,
	SetTimelineContext,
	TimelineContext,
	type SetTimelineContextValue,
	type TimelineContextValue,
} from './TimelineContext.js';
import {truthy} from './truthy.js';
import {
	calculateScale,
	CurrentScaleContext,
	PreviewSizeContext,
} from './use-current-scale.js';
import {DelayRenderContextType} from './use-delay-render.js';
import {useLazyComponent} from './use-lazy-component.js';
import {useAudioEnabled, useVideoEnabled} from './use-media-enabled.js';
import {
	useBasicMediaInTimeline,
	useMediaInTimeline,
} from './use-media-in-timeline.js';
import type {CanUpdateSequencePropStatus} from './use-schema.js';
import {useSchema} from './use-schema.js';
import {useSequenceControlOverride} from './use-sequence-control-override.js';
import {useUnsafeVideoConfig} from './use-unsafe-video-config.js';
import {useVideo} from './use-video.js';
import {validateMediaProps} from './validate-media-props.js';
import {
	resolveTrimProps,
	validateMediaTrimProps,
} from './validate-start-from-props.js';
import {validateRenderAsset} from './validation/validate-artifact.js';
import {
	invalidCompositionErrorMessage,
	isCompositionIdValid,
} from './validation/validate-composition-id.js';
import {DurationsContextProvider} from './video/duration-state.js';
import {InnerOffthreadVideo} from './video/OffthreadVideo.js';
import {isIosSafari} from './video/video-fragment.js';
import {VideoForPreview} from './video/VideoForPreview.js';
import type {
	MediaVolumeContextValue,
	SetMediaVolumeContextValue,
} from './volume-position-state.js';
import {
	MediaVolumeContext,
	SetMediaVolumeContext,
	useMediaMutedState,
	useMediaVolumeState,
} from './volume-position-state.js';
import {evaluateVolume} from './volume-prop.js';
import {warnAboutTooHighVolume} from './volume-safeguard.js';
import type {WatchRemotionStaticFilesPayload} from './watch-static-file.js';
import {WATCH_REMOTION_STATIC_FILES} from './watch-static-file.js';
import {wrapInSchema} from './wrap-in-schema.js';
import {
	RemotionContextProvider,
	useRemotionContexts,
} from './wrap-remotion-context.js';

// needs to be in core package so gets deduplicated in studio
const compositionSelectorRef = createRef<{
	expandComposition: (compName: string) => void;
	selectComposition: (compName: string) => void;
	toggleFolder: (folderName: string, parentName: string | null) => void;
}>();

// Mark them as Internals so use don't assume this is public
// API and are less likely to use it
export const Internals = {
	MaxMediaCacheSizeContext,
	useUnsafeVideoConfig,
	useFrameForVolumeProp,
	useTimelinePosition: TimelinePosition.useTimelinePosition,
	useAbsoluteTimelinePosition: TimelinePosition.useAbsoluteTimelinePosition,
	evaluateVolume,
	getAbsoluteSrc,
	Timeline: TimelinePosition,
	validateMediaTrimProps,
	validateMediaProps,
	resolveTrimProps,
	VideoForPreview,
	CompositionManager,
	CompositionSetters,
	VisualModeOverridesContext,
	SequenceManager,
	SequenceStackTracesUpdateContext,
	SequenceVisibilityToggleContext,
	useSchema,
	wrapInSchema,
	useSequenceControlOverride,
	RemotionRootContexts,
	CompositionManagerProvider,
	useVideo,
	getRoot,
	useMediaVolumeState,
	useMediaMutedState,
	useMediaInTimeline,
	useLazyComponent,
	truthy,
	SequenceContext,
	PremountContext,
	useRemotionContexts,
	RemotionContextProvider,
	CSSUtils,
	setupEnvVariables,
	MediaVolumeContext,
	SetMediaVolumeContext,
	getRemotionEnvironment,
	SharedAudioContext,
	SharedAudioContextProvider,
	invalidCompositionErrorMessage,
	calculateMediaDuration,
	isCompositionIdValid,
	getPreviewDomElement,
	compositionsRef,
	portalNode,
	waitForRoot,
	SetTimelineContext,
	CanUseRemotionHooksProvider,
	CanUseRemotionHooks,
	PrefetchProvider,
	DurationsContextProvider,
	IsPlayerContextProvider,
	useIsPlayer,
	EditorPropsProvider,
	EditorPropsContext,
	usePreload,
	NonceContext,
	resolveVideoConfig,
	resolveVideoConfigOrCatch,
	ResolveCompositionContext,
	useResolvedVideoConfig,
	resolveCompositionsRef,
	REMOTION_STUDIO_CONTAINER_ELEMENT,
	RenderAssetManager,
	persistCurrentFrame,
	useTimelineContext,
	useTimelineSetFrame,
	isIosSafari,
	WATCH_REMOTION_STATIC_FILES,
	addSequenceStackTraces,
	useMediaStartsAt,
	BufferingProvider,
	BufferingContextReact,
	getComponentsToAddStacksTo,
	CurrentScaleContext,
	PreviewSizeContext,
	calculateScale,
	validateRenderAsset,
	Log,
	LogLevelContext,
	useLogLevel,
	playbackLogging,
	timeValueRef,
	compositionSelectorRef,
	RemotionEnvironmentContext,
	warnAboutTooHighVolume,
	AudioForPreview,
	OBJECTFIT_CONTAIN_CLASS_NAME,
	InnerOffthreadVideo,
	useBasicMediaInTimeline,
	getInputPropsOverride,
	setInputPropsOverride,
	useVideoEnabled,
	useAudioEnabled,
	useIsPlayerBuffering,
	TimelinePosition,
	DelayRenderContextType,
	TimelineContext,
	AbsoluteTimeContext,
	RenderAssetManagerProvider,
	getEffectiveVisualModeValue,
} as const;

export type {
	CompositionManagerContext,
	ResolvedStackLocation,
	CompProps,
	LoggingContextValue,
	MediaVolumeContextValue,
	RemotionEnvironment,
	SequenceFieldSchema,
	SequenceSchema,
	SerializedJSONWithCustomFields,
	SetMediaVolumeContextValue,
	SetTimelineContextValue,
	TCompMetadata,
	TComposition,
	TimelineContextValue,
	TRenderAsset,
	TSequence,
	WatchRemotionStaticFilesPayload,
	ScheduleAudioNodeOptions,
	CanUpdateSequencePropStatus,
	ScheduleAudioNodeResult,
	NonceHistory,
};
