// 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/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "charginginfo.h"

ChargingInfo::ChargingInfo(const ThingId &evChargerId):
    m_evChargerId(evChargerId)
{

}

ThingId ChargingInfo::evChargerId() const
{
    return m_evChargerId;
}

void ChargingInfo::setEvChargerId(const ThingId &evChargerId)
{
    m_evChargerId = evChargerId;
}

ThingId ChargingInfo::assignedCarId() const
{
    return m_assignedCarId;
}

void ChargingInfo::setAssignedCarId(const ThingId &assignedCarId)
{
    m_assignedCarId = assignedCarId;
}

ChargingInfo::ChargingMode ChargingInfo::chargingMode() const
{
    return m_chargingMode;
}

void ChargingInfo::setChargingMode(ChargingMode chargingMode)
{
    m_chargingMode = chargingMode;
}

QDateTime ChargingInfo::endDateTime() const
{
    return m_endDateTime;
}

void ChargingInfo::setEndDateTime(const QDateTime &endDateTime)
{
    m_endDateTime = endDateTime;
}

QList<int> ChargingInfo::repeatDays() const
{
    return m_repeatDays;
}

void ChargingInfo::setRepeatDays(const QList<int> &repeatDays)
{
    m_repeatDays = repeatDays;
}

uint ChargingInfo::targetPercentage() const
{
    return m_targetPercentage;
}

void ChargingInfo::setTargetPercentage(uint targetPercentage)
{
    m_targetPercentage = targetPercentage;
}

QLocale ChargingInfo::locale() const
{
    return m_locale;
}

void ChargingInfo::setLocale(const QLocale &locale)
{
    m_locale = locale;
}

ChargingInfo::ChargingState ChargingInfo::chargingState() const
{
    return m_chargingState;
}

void ChargingInfo::setChargingState(ChargingState chargingState)
{
    m_chargingState = chargingState;
}

bool ChargingInfo::spotMarketChargingEnabled() const
{
    return m_spotMarketChargingEnabled;
}

void ChargingInfo::setSpotMarketChargingEnabled(bool spotMarketChargingEnabled)
{
    m_spotMarketChargingEnabled = spotMarketChargingEnabled;
}

uint ChargingInfo::dailySpotMarketPercentage() const
{
    return m_dailySpotMarketPercentage;
}

void ChargingInfo::setDailySpotMarketPercentage(uint dailySpotMarketPercentage)
{
    m_dailySpotMarketPercentage = dailySpotMarketPercentage;
}

bool ChargingInfo::operator==(const ChargingInfo &other) const
{
    return m_evChargerId == other.evChargerId() &&
            m_assignedCarId == other.assignedCarId() &&
            m_chargingMode == other.chargingMode() &&
            m_endDateTime == other.endDateTime() &&
            m_repeatDays == other.repeatDays() &&
            m_targetPercentage == other.targetPercentage() &&
            m_locale == other.locale() &&
            m_chargingState == other.chargingState() &&
            m_spotMarketChargingEnabled == other.spotMarketChargingEnabled() &&
            m_dailySpotMarketPercentage == other.dailySpotMarketPercentage();
}

bool ChargingInfo::operator!=(const ChargingInfo &other) const
{
    return !(*this == other);
}

QDateTime ChargingInfo::nextEndTime(const QDateTime &currentDateTime) const
{
    if (!m_endDateTime.isValid())
        return m_endDateTime;


    if (m_repeatDays.isEmpty()) {
        if (m_endDateTime < currentDateTime) {
            return QDateTime();
        } else {
            return m_endDateTime;
        }
    }

    QDate currentDate = currentDateTime.date();
    while (true) {
        if (m_repeatDays.contains(currentDate.dayOfWeek())) {
            QDateTime nextCandidate(currentDate, m_endDateTime.time());
            if (nextCandidate >= currentDateTime) {
                return nextCandidate;
            }
        }
        currentDate = currentDate.addDays(1);
    }

    return QDateTime();
}

QDebug operator<<(QDebug dbg, const ChargingInfo &chargingInfo)
{
    dbg << "Charging Info: Charger:" << chargingInfo.evChargerId() << "\n";
    dbg << "- Assigned car:" << chargingInfo.assignedCarId() << "\n";
    dbg << "- Current mode:" << chargingInfo.chargingMode() << "\n";
    dbg << "- ECO settings: End time:" << chargingInfo.endDateTime() << "Repeated on:" << chargingInfo.repeatDays() << "Target percentage:" << chargingInfo.targetPercentage() << "Locale:" << chargingInfo.locale().name() << "\n";
    dbg << "- Target percentage:" << chargingInfo.targetPercentage() << "\n";
    dbg << "- Spot market:" << (chargingInfo.spotMarketChargingEnabled() ? "enabled" : "disabled") << "\n";
    dbg << "- Charge daily from spot market:" << chargingInfo.dailySpotMarketPercentage() << "%\n";
    return dbg;
}

ChargingInfos::ChargingInfos()
{

}

ChargingInfos::ChargingInfos(const QList<ChargingInfo> &other): QList<ChargingInfo>(other)
{

}

QVariant ChargingInfos::get(int index) const
{
    return QVariant::fromValue(at(index));
}

void ChargingInfos::put(const QVariant &variant)
{
    append(variant.value<ChargingInfo>());
}
