//
//  Switchboard.hpp
//  SwitchboardSDK
//
//  Copyright © 2026 Synervoz. All rights reserved.
//

#pragma once

#include "export.h"
#include "Result.hpp"
#include "Event.hpp"

#include <any>
#include <functional>
#include <map>
#include <string>

namespace switchboard {

/**
 * @brief The main Switchboard SDK interface.
 */
class SWITCHBOARDSDK_EXPORT Switchboard {
public:
    using ObjectID = std::string;
    using ObjectURI = std::string;

    /**
     * @brief Initializes the Switchboard SDK.
     *
     * @param config Configuration map.
     *
     * @return The URI of the initialized Switchboard SDK.
     */
    static Result<ObjectURI> initialize(const SBAnyMap& config);

    /**
     * @brief Deinitializes the Switchboard SDK.
     *
     * @return A successful result if the SDK was deinitialized successfully, an error result otherwise.
     */
    static Result<void> deinitialize();

    /**
     * @brief Creates a new Switchboard engine.
     *
     * @details This method calls "createEngine" action on the SDK Instance (object URI: "switchboard").
     *
     * @param config Configuration map.
     *
     * @return The URI of the created engine.
     */
    static Result<ObjectURI> createEngine(const SBAnyMap& config);

    /**
     * @brief Destroys a Switchboard engine.
     *
     * @details This method calls "destroyEngine" action on the SDK Instance (object URI: "switchboard").
     * 
     * @param engineURI The URI of the engine object.
     * 
     * @return A successful result if the object was destroyed successfully, an error result otherwise.
     */
    static Result<void> destroyEngine(const ObjectURI& engineURI);

    /**
     * @brief Calls an action on a Switchboard object.
     *
     * @param objectURI The URI of the object.
     * @param actionName The name of the action.
     * @param params The parameters of the action.
     *
     * @return The result of the action.
     */
    static Result<SBAny>
        callAction(const ObjectURI& objectURI, const std::string& actionName, const SBAnyMap& params = {});

    /**
     * @brief Sets a value of a property on a Switchboard object.
     *
     * @param objectURI The URI of the object.
     * @param key The name of the property.
     * @param value The value to set.
     *
     * @return A successful result if the value was set successfully, an error result otherwise.
     */
    static Result<void> setValue(const ObjectURI& objectURI, const std::string& key, const SBAny& value);

    /**
     * @brief Gets a value of a property from a Switchboard object.
     *
     * @param objectURI The URI of the object.
     * @param key The name of the property.
     *
     * @return The value.
     */
    static Result<SBAny> getValue(const ObjectURI& objectURI, const std::string& key);

    /**
     * @brief Adds a new event listener to a Switchboard object.
     * 
     * @param objectURI The URI of the object.
     * @param eventName The name of the event to listen to.
     * @param callback The callback function to call when the event is fired.
     * 
     * @return The ID of the listener.
     */
    static Result<unsigned int> addEventListener(const ObjectURI& objectURI, const std::string& eventName, const std::function<void(const Event&)>& callback);

    /**
     * @brief Removes an event listener from a Switchboard object.
     * 
     * @param objectURI The URI of the object.
     * @param listenerID The ID of the listener to remove.
     * 
     * @return A successful result if the listener was removed successfully, an error result otherwise.
     */
    static Result<void> removeEventListener(const ObjectURI& objectURI, unsigned int listenerID);

private:
    class Impl;
    static Impl* pImpl;
};

}
