pub use rong_core::err_data;
pub use rong_core::{
    Class as CoreClass, ClassSetup, FromJSValue, HostError, IntoJSAsyncIteratorExt,
    IntoJSIteratorExt, IntoJSValue, JSArray as CoreJSArray, JSArrayBuffer as CoreJSArrayBuffer,
    JSAsyncIterator, JSClass, JSContext as CoreJSContext, JSContextService, JSDate as CoreJSDate,
    JSEngine, JSException as CoreJSException, JSFunc as CoreJSFunc, JSIterator,
    JSObject as CoreJSObject, JSResult, JSRuntime as CoreJSRuntime, JSRuntimeService,
    JSSymbol as CoreJSSymbol, JSTypedArray as CoreJSTypedArray, JSTypedArrayKind,
    JSValue as CoreJSValue, JSValueType, JsonToJSValue, Promise as CorePromise,
    PropertyDescriptor as CorePropertyDescriptor, RongJSError, Source, SourceKind, error,
};
// Re-export selected runtime API from rong_core::rong so downstream crates use `rong::...`
pub use rong_core::rong::{Rong, Worker, WorkerMessage, spawn};

// Re-export background runtime and user-agent helpers.
pub use rong_core::bg;
pub use rong_core::user_agent::{DEFAULT_USER_AGENT, get_user_agent, set_user_agent};
// Re-export selected scheduler APIs (module remains internal to core)
pub use rong_core::{JsInvokePriority, enqueue_js_invoke};

pub mod function {
    pub use rong_core::function::{
        Constructor, FromParams, IntoJSCallable, IntoOnceJSCallable, JSParameterType, KAsyncFnMut,
        KAsyncFnOnce, KFnMut, KFnOnce, Optional, ParamsAccessor, Rest, This,
    };

    pub type ThisMut<T> = rong_core::function::ThisMut<T, crate::JSEngineValue>;
}

#[cfg(feature = "quickjs")]
mod engine {
    use rong_quickjs::QuickJS;
    pub type RongJS = QuickJS;
}

#[cfg(all(feature = "jscore", not(feature = "quickjs"), not(feature = "arkjs")))]
mod engine {
    use rong_jscore::JavaScriptCore;
    pub type RongJS = JavaScriptCore;
}

#[cfg(all(feature = "arkjs", not(feature = "quickjs"), not(feature = "jscore")))]
mod engine {
    use rong_arkjs::HarmonyArkJS;
    pub type RongJS = HarmonyArkJS;
}

#[cfg(not(any(feature = "quickjs", feature = "jscore", feature = "arkjs")))]
compile_error!("`rong` requires an engine feature: enable one of `quickjs`, `jscore`, or `arkjs`.");

pub use engine::*;

pub type JSEngineValue = <RongJS as JSEngine>::Value;
pub type JSEngineContext = <RongJS as JSEngine>::Context;

pub type JSContext = CoreJSContext<<RongJS as JSEngine>::Context>;
pub type JSRuntime = CoreJSRuntime<<RongJS as JSEngine>::Runtime>;

pub type JSValue = CoreJSValue<JSEngineValue>;
pub type JSObject = CoreJSObject<JSEngineValue>;
pub type JSSymbol = CoreJSSymbol<JSEngineValue>;
pub type JSFunc = CoreJSFunc<JSEngineValue>;
pub type JSDate = CoreJSDate<JSEngineValue>;
pub type Class = CoreClass<JSEngineValue>;
pub type Promise = CorePromise<JSEngineValue>;
pub type JSException = CoreJSException<JSEngineValue>;
pub type JSArray = CoreJSArray<JSEngineValue>;
pub type JSArrayBuffer<T> = CoreJSArrayBuffer<JSEngineValue, T>;
pub type JSTypedArray = CoreJSTypedArray<JSEngineValue>;
pub type PropertyDescriptor = CorePropertyDescriptor<JSEngineValue>;

// re-export macro public symbols to rong
pub use rong_macro::{FromJSObj, FromJSValue, IntoJSObj, js_class, js_export, js_method};

/// A Trait for conversion from JavaScript values.
pub trait TryFromJSValue: Sized {
    fn try_from_js(_value: JSValue) -> JSResult<Self>;
}
