#include "odinclient.h"
#include "odinroom.h"
#include "utilities.h" // Added include

Napi::Object OdinClient::Init(Napi::Env env, Napi::Object exports) {
    Napi::Function func = DefineClass(env, "OdinClient", {
            InstanceMethod<&OdinClient::GenerateAccessToken>("generateToken", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
            InstanceMethod<&OdinClient::CreateRoom>("createRoom", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
            InstanceMethod<&OdinClient::CreateRoomWithAccessToken>("createRoomWithToken", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
            InstanceMethod<&OdinClient::GenerateAccessToken>("generateAccessToken", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
            InstanceMethod<&OdinClient::CreateRoomWithAccessToken>("createRoomWithAccessToken", static_cast<napi_property_attributes>(napi_writable | napi_configurable))
    });

    Napi::FunctionReference* constructor = new Napi::FunctionReference();
    *constructor = Napi::Persistent(func);
    exports.Set("OdinClient", func);
    // env.SetInstanceData<Napi::FunctionReference>(constructor);
    return exports;
}

// Extern declaration of shared SDK initialization flag (defined in odinroom.cpp)
extern bool g_odinSdkInitialized;

OdinClient::OdinClient(const Napi::CallbackInfo& info) : Napi::ObjectWrap<OdinClient>(info)  {
    // SDK lifecycle is now managed by OdinRoomWrapper via reference counting.
    // The SDK is initialized when the first room is created and shut down
    // when the last room is destroyed. This avoids issues with GC timing.
}

void OdinClient::Finalize(Napi::Env env) {
    // Note: SDK lifecycle is managed by OdinRoomWrapper via reference counting.
    // Do NOT call odin_shutdown() here as it would invalidate encoders/decoders
    // that may still be in use by other rooms.
}

Napi::Value OdinClient::GenerateAccessToken(const Napi::CallbackInfo &info) {
    Napi::TypeError::New(info.Env(), "Native token generation is removed in SDK 1.8.2. Use 'jsonwebtoken' or similar to generate JWTs.").ThrowAsJavaScriptException();
    return info.Env().Undefined();
}

Napi::Value OdinClient::CreateRoom(const Napi::CallbackInfo &info) {
    Napi::Env env = info.Env();
    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "Token expected").ThrowAsJavaScriptException();
        return env.Undefined();
    }
    std::string token = info[0].ToString().Utf8Value();
    return OdinRoomWrapper::NewInstance(Napi::String::New(env, token));
}

Napi::Value OdinClient::CreateRoomWithAccessToken(const Napi::CallbackInfo &info) {
    Napi::Env env = info.Env();
    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "Access token expected").ThrowAsJavaScriptException();
        return env.Undefined();
    }
    std::string token = info[0].ToString().Utf8Value();
    return OdinRoomWrapper::NewInstance(Napi::String::New(env, token));
}
