//
// Created by Balazs Kiss on 2025. 02. 23..
//

#pragma once

#include <switchboard/export.h>
#include <switchboard_core/SwitchboardObject.hpp>

#include <map>
#include <any>

namespace switchboard {

class SWITCHBOARDSDK_EXPORT Node : public SwitchboardObject {
public:

    /**
     * @brief Static type-info fragment for the abstract Node base.
     *        Concrete node subtypes should merge this with their own info so the
     *        exported schema includes the inherited properties.
     *        Omits OBJECT_TYPE_FIELD_TYPE / OBJECT_TYPE_FIELD_SUBTYPE — those belong to concrete types.
     */
    static SBAnyMap getObjectTypeInfo() {
        return SBAnyMap({
            { OBJECT_TYPE_FIELD_PROPERTIES,
              SBAnyMap({
                  { "numberOfInputs",
                    SBAnyMap({
                        { PROPERTY_FIELD_TYPE, PROPERTY_TYPE_INT },
                        { PROPERTY_FIELD_READ_ONLY, true },
                        { PROPERTY_FIELD_DESCRIPTION, "The number of inputs of the node." },
                    }) },
                  { "numberOfOutputs",
                    SBAnyMap({
                        { PROPERTY_FIELD_TYPE, PROPERTY_TYPE_INT },
                        { PROPERTY_FIELD_READ_ONLY, true },
                        { PROPERTY_FIELD_DESCRIPTION, "The number of outputs of the node." },
                    }) },
                  { "title",
                    SBAnyMap({
                        { PROPERTY_FIELD_TYPE, PROPERTY_TYPE_STRING },
                        { PROPERTY_FIELD_READ_ONLY, false },
                        { PROPERTY_FIELD_DESCRIPTION, "The title of the node." },
                        { PROPERTY_FIELD_DEFAULT_VALUE, std::string("") },
                    }) },
              }) },
        });
    }

    /**
     * @brief Node constructor.
     *
     * @param numberOfInputs The number of inputs for the node.
     * @param numberOfOutputs The number of outputs for the node.
     */
    Node(uint numberOfInputs, uint numberOfOutputs);

    /**
     * @brief Gets the type of the node.
     * @details Equivalent to SwitchboardObject::getObjectSubtype(); returns the fully-qualified
     *          node type (e.g. "Switchboard.Gain"), or an empty string if no subtype is set.
     *
     * @returns The type of the node.
     */
    std::string getType() const;

    /**
     * @brief Gets the number of inputs for the node.
     *
     * @returns The number of inputs for the node.
     */
    unsigned int getNumberOfInputs() const;

    /**
     * @brief Gets the number of outputs for the node.
     *
     * @returns The number of outputs for the node.
     */
    unsigned int getNumberOfOutputs() const;

    // MARK: Overridden methods

    Result<SBAny> getValue(const std::string &key) override;
    Result<SBAny> callAction(const std::string& actionName, const SBAnyMap& params) override;

protected:
    /// @brief The number of inputs (audio buses) for the node.
    unsigned int numberOfInputs;

    /// @brief The number of outputs (audio buses) for the node.
    unsigned int numberOfOutputs;

    /// @brief The title of the node that can be displayed in the UI.
    std::string title;
};

}
