// ============================================================
// nymeaenergyjsonhandler_extension.cpp
//
// DIFF — Méthodes à AJOUTER dans NymeaEnergyJsonHandler
// pour exposer la PAC, l'ECS et la gestion de priorité.
//
// Ces blocs sont à intégrer dans nymeaenergyjsonhandler.h/.cpp
// ============================================================

// ─────────────────────────────────────────────────────────────
// [1] Dans nymeaenergyjsonhandler.h — Nouvelles déclarations
// ─────────────────────────────────────────────────────────────

/*
À AJOUTER dans le bloc public de NymeaEnergyJsonHandler :

    // ─── Heat Pump ───────────────────────────────────────────
    Q_INVOKABLE JsonReply *GetHeatPumps(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetHeatPumpPower(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetHeatPumpMode(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetHeatPumpTargetTemperature(const QVariantMap &params);

    // ─── DHW (ECS) ───────────────────────────────────────────
    Q_INVOKABLE JsonReply *GetDHWDevices(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetDHWPower(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetDHWTargetTemperature(const QVariantMap &params);
    Q_INVOKABLE JsonReply *TriggerDHWBoost(const QVariantMap &params);

    // ─── Energy Priority ─────────────────────────────────────
    Q_INVOKABLE JsonReply *GetManagedLoads(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetLoadPriority(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetAllocatedPower(const QVariantMap &params);
    Q_INVOKABLE JsonReply *SetTotalAvailablePower(const QVariantMap &params);
    Q_INVOKABLE JsonReply *GetTotalAvailablePower(const QVariantMap &params);

À AJOUTER dans le bloc signals :

    void HeatPumpStateChanged(const QVariantMap &params);
    void DHWStateChanged(const QVariantMap &params);
    void ManagedLoadChanged(const QVariantMap &params);
    void TotalAvailablePowerChanged(const QVariantMap &params);

À AJOUTER dans les membres privés :

    HeatPumpManager *m_heatPumpManager = nullptr;
    EnergyPriorityManager *m_priorityManager = nullptr;
*/

// ─────────────────────────────────────────────────────────────
// [2] Dans le constructeur NymeaEnergyJsonHandler()
//     Enregistrement des nouvelles méthodes JSON-RPC
// ─────────────────────────────────────────────────────────────

void registerHeatPumpAndDHWMethods(NymeaEnergyJsonHandler *handler)
{
    QVariantMap params, returns;
    QString description;

    // ─── Enum registration ──────────────────────────────────

    handler->registerEnum<EnergyPriorityManager::LoadPriority>();
    handler->registerEnum<EnergyPriorityManager::LoadType>();

    // ─── Heat Pump Methods ──────────────────────────────────

    params.clear(); returns.clear();
    description = "Récupère la liste de toutes les pompes à chaleur gérées.";
    returns.insert("heatPumps", QVariantList() << QVariantMap{
        {"thingId", handler->enumValueName(JsonHandler::Uuid)},
        {"name", handler->enumValueName(JsonHandler::String)},
        {"power", handler->enumValueName(JsonHandler::Bool)},
        {"mode", handler->enumValueName(JsonHandler::String)},
        {"targetTemperature", handler->enumValueName(JsonHandler::Double)},
        {"currentTemperature", handler->enumValueName(JsonHandler::Double)},
        {"currentPower", handler->enumValueName(JsonHandler::Double)},
        {"cop", handler->enumValueName(JsonHandler::Double)},
        {"defrostActive", handler->enumValueName(JsonHandler::Bool)}
    });
    handler->registerMethod("GetHeatPumps", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Allume ou éteint une pompe à chaleur.";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("power", handler->enumValueName(JsonHandler::Bool));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetHeatPumpPower", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Définit le mode de fonctionnement d'une PAC (heating/cooling/auto/standby).";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("mode", handler->enumValueName(JsonHandler::String));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetHeatPumpMode", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Définit la température cible d'une pompe à chaleur [15–65 °C].";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("targetTemperature", handler->enumValueName(JsonHandler::Double));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetHeatPumpTargetTemperature", description, params, returns,
                            Types::PermissionScopeControlThings);

    // ─── DHW Methods ────────────────────────────────────────

    params.clear(); returns.clear();
    description = "Récupère la liste de tous les systèmes ECS gérés.";
    returns.insert("dhwDevices", QVariantList() << QVariantMap{
        {"thingId", handler->enumValueName(JsonHandler::Uuid)},
        {"name", handler->enumValueName(JsonHandler::String)},
        {"power", handler->enumValueName(JsonHandler::Bool)},
        {"targetTemperature", handler->enumValueName(JsonHandler::Double)},
        {"currentTemperature", handler->enumValueName(JsonHandler::Double)},
        {"boostMode", handler->enumValueName(JsonHandler::Bool)},
        {"currentPower", handler->enumValueName(JsonHandler::Double)}
    });
    handler->registerMethod("GetDHWDevices", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Active ou désactive le système ECS.";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("power", handler->enumValueName(JsonHandler::Bool));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetDHWPower", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Définit la température cible de l'ECS [40–75 °C].";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("targetTemperature", handler->enumValueName(JsonHandler::Double));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetDHWTargetTemperature", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Déclenche le mode boost ECS. Durée entre 15 et 120 minutes.";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("duration", handler->enumValueName(JsonHandler::Uint));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("TriggerDHWBoost", description, params, returns,
                            Types::PermissionScopeControlThings);

    // ─── Energy Priority Methods ────────────────────────────

    params.clear(); returns.clear();
    description = "Récupère toutes les charges gérées avec leur priorité et puissance allouée.";
    returns.insert("managedLoads", QVariantList() << QVariantMap{
        {"thingId", handler->enumValueName(JsonHandler::Uuid)},
        {"name", handler->enumValueName(JsonHandler::String)},
        {"type", handler->enumRef<EnergyPriorityManager::LoadType>()},
        {"priority", handler->enumRef<EnergyPriorityManager::LoadPriority>()},
        {"allocatedPower", handler->enumValueName(JsonHandler::Double)},
        {"requestedPower", handler->enumValueName(JsonHandler::Double)},
        {"currentPower", handler->enumValueName(JsonHandler::Double)},
        {"active", handler->enumValueName(JsonHandler::Bool)}
    });
    handler->registerMethod("GetManagedLoads", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Modifie la priorité d'une charge. "
                  "Critical=0, High=1, Normal=2, Low=3, Optional=4.";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("priority", handler->enumRef<EnergyPriorityManager::LoadPriority>());
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetLoadPriority", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Force la puissance allouée à une charge spécifique (en Watts).";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("allocatedPower", handler->enumValueName(JsonHandler::Double));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetAllocatedPower", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Définit la puissance totale disponible pour la distribution (en Watts).";
    params.insert("totalAvailablePower", handler->enumValueName(JsonHandler::Double));
    returns.insert("energyError", handler->enumRef<EnergyManager::EnergyError>());
    handler->registerMethod("SetTotalAvailablePower", description, params, returns,
                            Types::PermissionScopeControlThings);

    params.clear(); returns.clear();
    description = "Retourne la puissance totale disponible pour la distribution (en Watts).";
    returns.insert("totalAvailablePower", handler->enumValueName(JsonHandler::Double));
    handler->registerMethod("GetTotalAvailablePower", description, params, returns,
                            Types::PermissionScopeControlThings);

    // ─── Notifications ──────────────────────────────────────

    params.clear();
    description = "Émis quand l'état d'une PAC change (température, mode, puissance...).";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("stateName", handler->enumValueName(JsonHandler::String));
    params.insert("value", handler->enumValueName(JsonHandler::Variant));
    handler->registerNotification("HeatPumpStateChanged", description, params);

    params.clear();
    description = "Émis quand l'état d'un système ECS change.";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("stateName", handler->enumValueName(JsonHandler::String));
    params.insert("value", handler->enumValueName(JsonHandler::Variant));
    handler->registerNotification("DHWStateChanged", description, params);

    params.clear();
    description = "Émis quand la priorité ou la puissance allouée d'une charge change.";
    params.insert("thingId", handler->enumValueName(JsonHandler::Uuid));
    params.insert("priority", handler->enumRef<EnergyPriorityManager::LoadPriority>());
    params.insert("allocatedPower", handler->enumValueName(JsonHandler::Double));
    params.insert("active", handler->enumValueName(JsonHandler::Bool));
    handler->registerNotification("ManagedLoadChanged", description, params);

    params.clear();
    description = "Émis quand la puissance totale disponible change.";
    params.insert("totalAvailablePower", handler->enumValueName(JsonHandler::Double));
    handler->registerNotification("TotalAvailablePowerChanged", description, params);
}

// ─────────────────────────────────────────────────────────────
// [3] Implémentation des nouvelles méthodes JSON-RPC
// ─────────────────────────────────────────────────────────────

JsonReply *NymeaEnergyJsonHandler::GetHeatPumps(const QVariantMap &params)
{
    Q_UNUSED(params)
    QVariantList list;
    for (const HeatPumpDevice *hp : m_heatPumpManager->heatPumps()) {
        list << QVariantMap{
            {"thingId",            hp->id().toString()},
            {"name",               hp->name()},
            {"power",              hp->power()},
            {"mode",               hp->mode()},
            {"targetTemperature",  hp->targetTemperature()},
            {"currentTemperature", hp->currentTemperature()},
            {"currentPower",       hp->currentPower()},
            {"cop",                hp->cop()},
            {"defrostActive",      hp->defrostActive()}
        };
    }
    return createReply({{"heatPumps", list}});
}

JsonReply *NymeaEnergyJsonHandler::SetHeatPumpPower(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    bool power = params.value("power").toBool();
    auto error = m_heatPumpManager->setPower(thingId, power);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::SetHeatPumpMode(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    QString mode = params.value("mode").toString();
    auto error = m_heatPumpManager->setMode(thingId, mode);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::SetHeatPumpTargetTemperature(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    double temp = params.value("targetTemperature").toDouble();
    auto error = m_heatPumpManager->setTargetTemperature(thingId, temp);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::GetDHWDevices(const QVariantMap &params)
{
    Q_UNUSED(params)
    QVariantList list;
    for (const DomesticHotWaterDevice *dhw : m_heatPumpManager->dhwDevices()) {
        list << QVariantMap{
            {"thingId",            dhw->id().toString()},
            {"name",               dhw->name()},
            {"power",              dhw->power()},
            {"targetTemperature",  dhw->targetTemperature()},
            {"currentTemperature", dhw->currentTemperature()},
            {"boostMode",          dhw->boostMode()},
            {"currentPower",       dhw->currentPower()}
        };
    }
    return createReply({{"dhwDevices", list}});
}

JsonReply *NymeaEnergyJsonHandler::SetDHWPower(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    bool power = params.value("power").toBool();
    auto error = m_heatPumpManager->setDHWPower(thingId, power);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::SetDHWTargetTemperature(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    double temp = params.value("targetTemperature").toDouble();
    auto error = m_heatPumpManager->setDHWTargetTemperature(thingId, temp);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::TriggerDHWBoost(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    uint duration = params.value("duration").toUInt();
    auto error = m_heatPumpManager->triggerDHWBoost(thingId, duration);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::GetManagedLoads(const QVariantMap &params)
{
    Q_UNUSED(params)
    QVariantList list;
    for (const auto &load : m_priorityManager->managedLoads()) {
        list << QVariantMap{
            {"thingId",       load.thingId.toString()},
            {"name",          load.name},
            {"type",          enumValueName(load.type)},
            {"priority",      enumValueName(load.priority)},
            {"allocatedPower",load.allocatedPower},
            {"requestedPower",load.requestedPower},
            {"currentPower",  load.currentPower},
            {"active",        load.active}
        };
    }
    return createReply({{"managedLoads", list}});
}

JsonReply *NymeaEnergyJsonHandler::SetLoadPriority(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    auto priority = static_cast<EnergyPriorityManager::LoadPriority>(
                        params.value("priority").toInt());
    auto error = m_priorityManager->setLoadPriority(thingId, priority);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::SetAllocatedPower(const QVariantMap &params)
{
    ThingId thingId = ThingId(params.value("thingId").toUuid());
    double watts = params.value("allocatedPower").toDouble();
    auto error = m_priorityManager->setAllocatedPower(thingId, watts);
    return createReply({{"energyError", enumValueName(error)}});
}

JsonReply *NymeaEnergyJsonHandler::SetTotalAvailablePower(const QVariantMap &params)
{
    double watts = params.value("totalAvailablePower").toDouble();
    if (watts < 0)
        return createReply({{"energyError", enumValueName(EnergyManager::EnergyErrorInvalidParameter)}});
    m_priorityManager->setTotalAvailablePower(watts);
    return createReply({{"energyError", enumValueName(EnergyManager::EnergyErrorNoError)}});
}

JsonReply *NymeaEnergyJsonHandler::GetTotalAvailablePower(const QVariantMap &params)
{
    Q_UNUSED(params)
    return createReply({{"totalAvailablePower", m_priorityManager->totalAvailablePower()}});
}
