// SPDX-License-Identifier: GPL-3.0-or-later

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (C) 2013 - 2024, nymea GmbH
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
*
* This file is part of nymea-energy-plugin-nymea.
*
* nymea-energy-plugin-nymea.s free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* nymea-energy-plugin-nymea.s distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with nymea-energy-plugin-nymea. If not, see <https://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef CHARGINGSTATE_H
#define CHARGINGSTATE_H

#include <QDebug>
#include <QObject>
#include <QUuid>
#include <QVariant>

#include <typeutils.h>

class ChargingState
{
    Q_GADGET
    Q_PROPERTY(QUuid evChargerId READ evChargerId WRITE setEvChargerId)
    Q_PROPERTY(Mode mode READ mode WRITE setMode USER true)
    Q_PROPERTY(bool overloadProtectionActive READ overloadProtectionActive WRITE setOverloadProtectionActive USER true)
    Q_PROPERTY(int targetTimeOvershot READ targetTimeOvershot WRITE setTargetTimeOvershot NOTIFY targetTimeOvershotChanged FINAL)
    Q_PROPERTY(bool chargingTargetUnreachable READ chargingTargetUnreachable WRITE setChargingTargetUnreachable USER true)
    Q_PROPERTY(bool targetPercentageReached READ targetPercentageReached WRITE setTargetPercentageReached USER true)
    Q_PROPERTY(int powerLockSeconds READ powerLockSeconds WRITE setPowerLockSeconds USER true)
    Q_PROPERTY(int powerLockDuration READ powerLockDuration WRITE setPowerLockDuration)
    Q_PROPERTY(bool batteryLevelConsiderationActive READ batteryLevelConsiderationActive WRITE setBatteryLevelConsiderationActive)

public:
    enum Mode {
        ModeIdle,
        ModeSurplusCharging,
        ModeSpotMarketCharging,
        ModeTimeRequirement
    };
    Q_ENUM(Mode)

    ChargingState(const ThingId &evChargerId = ThingId());

    ThingId evChargerId() const;
    void setEvChargerId(const ThingId &evChargerId);

    Mode mode() const;
    void setMode(Mode mode);

    bool overloadProtectionActive() const;
    void setOverloadProtectionActive(bool overloadProtectionActive);

    int targetTimeOvershot() const;
    void setTargetTimeOvershot(int targetTimeOvershot);

    bool chargingTargetUnreachable() const;
    void setChargingTargetUnreachable(bool chargingTargetUnreachable);

    // Note: this flag is true if we reached the target percentage and
    // stopOnTargetPercentage is enabled in the configuration
    bool targetPercentageReached() const;
    void setTargetPercentageReached(bool targetPercentageReached);

    int powerLockSeconds() const;
    void setPowerLockSeconds(int powerLockSeconds);

    int powerLockDuration() const;
    void setPowerLockDuration(int powerLockDuration);

    bool batteryLevelConsiderationActive() const;
    void setBatteryLevelConsiderationActive(bool batteryLevelConsiderationActive);

    bool operator==(const ChargingState &other) const;
    bool operator!=(const ChargingState &other) const;

private:
    ThingId m_evChargerId;
    Mode m_mode = ModeIdle;
    bool m_overloadProtectionActive = false;
    int m_targetTimeOvershot = 0;
    bool m_chargingTargetUnreachable = false;
    bool m_targetPercentageReached = false;
    int m_powerLockSeconds = -1;
    int m_powerLockDuration = 300;
    bool m_batteryLevelConsiderationActive = false;
};

QDebug operator<<(QDebug debug, const ChargingState &chargingState);

class ChargingStates : public QList<ChargingState>
{
    Q_GADGET
    Q_PROPERTY(int count READ count)
public:
    ChargingStates();
    ChargingStates(const QList<ChargingState> &other);
    ChargingStates(std::initializer_list<ChargingState> args);
    Q_INVOKABLE QVariant get(int index) const;
    Q_INVOKABLE void put(const QVariant &variant);
};

inline ChargingStates::ChargingStates(std::initializer_list<ChargingState> args)
    : QList(args)
{}
Q_DECLARE_METATYPE(ChargingStates)

#endif // CHARGINGSTATE_H
