// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
#pragma once

#include <QObject>
#include <QDateTime>
#include "iloadadapter.h"

class EvCharger;
class EnergyArbitrator;

/*!
 * \brief Adaptateur pour une borne de recharge VE (interface evcharger nymea).
 *
 * Traduit les LoadAction(Setpoint) en appels matériels via
 * EnergyArbitrator::doExecuteChargingAction() — le seul chemin d'exécution.
 *
 * \invariant applyAction() rejette silencieusement toute LoadAction dont \c reason est vide.
 * \invariant currentA est écrêté à [maxChargingCurrentMinValue, maxChargingCurrentMaxValue].
 * \invariant phaseCount est écrêté selon canSetPhaseCount() et phaseCount() du EvCharger.
 * \invariant Les kinds autres que Setpoint sont retournés sans effet.
 */
class EvAdapter : public QObject, public ILoadAdapter
{
    Q_OBJECT
public:
    /*!
     * \brief Constructeur.
     * \param evCharger Borne VE à piloter (doit rester valide tant que l'adaptateur existe).
     * \param parent    EnergyArbitrator propriétaire — utilisé pour l'exécution matérielle.
     */
    explicit EvAdapter(EvCharger *evCharger, EnergyArbitrator *parent);

    /*!
     * \brief Retourne la description statique de la charge.
     * \return LoadDescriptor construit depuis les capacités actuelles du EvCharger.
     * \note Recalculé à chaque appel depuis l'état nymea du Thing.
     */
    LoadDescriptor descriptor() const override;

    /*!
     * \brief Retourne la télémétrie runtime (puissance mesurée, disponibilité).
     * \return LoadTelemetry avec currentPowerW, available et lastActionAt.
     */
    LoadTelemetry telemetry() const override;

    /*!
     * \brief Construit l'entrée loads[] §5 du SurplusContext.
     * \return LoadContext incluant declared, limits, needs et télémétrie EV.
     */
    LoadContext toLoadContext(const QDateTime &now) const override;

    /*!
     * \brief Applique une consigne Setpoint sur la borne VE.
     *
     * **Inactif jusqu'à 3g** : non appelée par \c EnergyArbitrator::update() en beta.
     * Le dispatch EV passe par \c adjustEvChargers() amont (hérité). Cette méthode
     * sera câblée lors de la transplantation EV dans \c RuleBasedScheduler (phase 3g).
     * \c descriptor() et \c telemetry() sont eux actifs dès maintenant pour le SurplusContext.
     *
     * \param action LoadAction de kind Setpoint. Autres kinds : retour sans effet.
     * \return L'action après écrêtage matériel (currentA, phaseCount bornés).
     *
     * \invariant action.reason non vide requis — log warning et retour sans effet sinon.
     * \invariant currentA écrêté à [minValue, maxValue] avant envoi à executeChargingAction.
     * \invariant phaseCount ajusté selon canSetPhaseCount() du EvCharger.
     */
    LoadAction applyAction(const LoadAction &action, const QDateTime &now) override;

    /*! \brief Borne VE sous-jacente (lecture). */
    EvCharger *evCharger() const { return m_charger; }

private:
    EvCharger        *m_charger;
    EnergyArbitrator *m_parent;
    QDateTime         m_lastActionAt;
};
