// 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 SCOREENTRY_H
#define SCOREENTRY_H

#include <QDebug>
#include <QDateTime>
#include <QMetaObject>
#include <qhashfunctions.h>

#include "timeframe.h"

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
using qhash_result_t = uint;
#else
using qhash_result_t = size_t;
#endif

class ScoreEntry : public TimeFrame
{
    Q_GADGET
    Q_PROPERTY(QDateTime startDateTime READ startDateTime WRITE setStartDateTime)
    Q_PROPERTY(QDateTime endDateTime READ endDateTime WRITE setEndDateTime)
    Q_PROPERTY(float value READ value WRITE setValue)
    Q_PROPERTY(float weighting READ weighting WRITE setWeighting)

public:
    ScoreEntry();

    // Required for recalculating weighting on new data
    double value() const;
    void setValue(double value);

    // How good is this entry compaired to the others [0, 1]
    // 0 - The worst entry
    // 1 - The best entry
    float weighting() const;
    void setWeighting(float weighting);

    bool isNull() const;

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

private:
    double m_value = 0;
    float m_weighting = 0;

};

qhash_result_t qHash(const ScoreEntry &scoreEntry, qhash_result_t seed = 0);

Q_DECLARE_METATYPE(ScoreEntry)

class ScoreEntries: public QList<ScoreEntry>
{
    Q_GADGET
    Q_PROPERTY(int count READ count)
public:
    ScoreEntries() = default;
    ScoreEntries(const QList<ScoreEntry> &other);
    Q_INVOKABLE QVariant get(int index) const;
    Q_INVOKABLE void put(const QVariant &variant);

    int availableFutureSchedules(const QDateTime &currentDateTime) const;

    // index 0 has the best weighting (1)
    void sortByWeighting();

    // index 0 is the oldest entry
    void sortByStartDateTime();

    ScoreEntry getScoreEntry(const QDateTime &currentDateTime = QDateTime::currentDateTime()) const;

    bool availableUpTo(const QDateTime &dateTime) const;
};

Q_DECLARE_METATYPE(ScoreEntries)

QDebug operator<<(QDebug debug, const ScoreEntry &dataEntry);
QDebug operator<<(QDebug debug, const ScoreEntries &scoreEntries);

#endif // SCOREENTRY_H
