/*
  SPDX-FileCopyrightText: 2025-2026 Laurent Montel <montel@kde.org>

  SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "textautogeneratechat.h"
#include "core/models/textautogeneratemessagesmodel.h"

#include <QJsonDocument>
#include <QJsonObject>

using namespace Qt::Literals::StringLiterals;
using namespace TextAutoGenerateText;
TextAutoGenerateChat::TextAutoGenerateChat()
    : mMessageModel(new TextAutoGenerateMessagesModel())
{
}

TextAutoGenerateChat::TextAutoGenerateChat(const TextAutoGenerateChat &other)
    : mMessageModel(new TextAutoGenerateMessagesModel())
    , mIdentifier(other.mIdentifier)
    , mTitle(other.mTitle)
    , mPrompt(other.mPrompt)
    , mDateTime(other.mDateTime)
    , mFavorite(other.mFavorite)
    , mArchived(other.mArchived)
    , mInitialized(other.mInitialized)
    , mInProgress(other.mInProgress)
{
    if (mMessageModel && other.mMessageModel) {
        mMessageModel->setMessages(other.mMessageModel->messages());
        mMessageModel->setChatId(mIdentifier);
    }
}

TextAutoGenerateChat &TextAutoGenerateChat::operator=(const TextAutoGenerateChat &other)
{
    if (this != &other) {
        mMessageModel = QSharedPointer<TextAutoGenerateMessagesModel>(new TextAutoGenerateMessagesModel());
        if (mMessageModel && other.mMessageModel) {
            mMessageModel->setMessages(other.mMessageModel->messages());
        }
        mIdentifier = other.mIdentifier;
        if (mMessageModel) {
            mMessageModel->setChatId(mIdentifier);
        }
        mDateTime = other.mDateTime;
        mTitle = other.mTitle;
        mFavorite = other.mFavorite;
        mArchived = other.mArchived;
        mInitialized = other.mInitialized;
        mInProgress = other.mInProgress;
        mPrompt = other.mPrompt;
    }
    return *this;
}

TextAutoGenerateChat::~TextAutoGenerateChat() = default;

bool TextAutoGenerateChat::favorite() const
{
    return mFavorite;
}

void TextAutoGenerateChat::setFavorite(bool newFavorite)
{
    mFavorite = newFavorite;
}

bool TextAutoGenerateChat::archived() const
{
    return mArchived;
}

void TextAutoGenerateChat::setArchived(bool newArchived)
{
    mArchived = newArchived;
}

QByteArray TextAutoGenerateChat::identifier() const
{
    return mIdentifier;
}

void TextAutoGenerateChat::setIdentifier(const QByteArray &newIdentifier)
{
    mIdentifier = newIdentifier;
    if (mMessageModel) {
        mMessageModel->setChatId(mIdentifier);
    }
}

bool TextAutoGenerateChat::operator==(const TextAutoGenerateChat &other) const
{
    return other.identifier() == mIdentifier && other.archived() == mArchived && other.favorite() == mFavorite && other.title() == mTitle
        && other.initialized() == mInitialized && other.dateTime() == mDateTime && other.prompt() == mPrompt;
}

QString TextAutoGenerateChat::title() const
{
    if (mMessageModel) {
        if (mTitle.isEmpty() && !mMessageModel->messages().isEmpty()) {
            return mMessageModel->messages().constFirst().content();
        }
    }
    return mTitle;
}

void TextAutoGenerateChat::setTitle(const QString &newTitle)
{
    mTitle = newTitle;
}

qint64 TextAutoGenerateChat::dateTime() const
{
    if (mMessageModel) {
        if (!mMessageModel->messages().isEmpty()) {
            return mMessageModel->messages().constLast().dateTime();
        }
    }
    return mDateTime;
}

void TextAutoGenerateChat::setDateTime(qint64 dt)
{
    mDateTime = dt;
}

QByteArray TextAutoGenerateChat::serialize(const TextAutoGenerateChat &chat, bool toBinary)
{
    QJsonDocument d;
    QJsonObject o;
    o["title"_L1] = chat.title();
    o["favorite"_L1] = chat.mFavorite;
    o["archived"_L1] = chat.mArchived;
    o["identifier"_L1] = QString::fromLatin1(chat.mIdentifier);
    o["datetime"_L1] = chat.dateTime();
    const QString prompt = chat.prompt();
    if (!prompt.isEmpty()) {
        o["prompt"_L1] = prompt;
    }

    if (toBinary) {
        return QCborValue::fromJsonValue(o).toCbor();
    }
    d.setObject(o);
    return d.toJson(QJsonDocument::Indented);
}

TextAutoGenerateChat TextAutoGenerateChat::deserialize(const QJsonObject &o)
{
    TextAutoGenerateChat chat;
    chat.setTitle(o["title"_L1].toString());
    chat.setFavorite(o["favorite"_L1].toBool(false));
    chat.setArchived(o["archived"_L1].toBool(false));
    chat.setIdentifier(o["identifier"_L1].toString().toLatin1());
    chat.setDateTime(o["datetime"_L1].toInteger());
    chat.setPrompt(o["prompt"_L1].toString());
    return chat;
}

TextAutoGenerateMessagesModel *TextAutoGenerateChat::messageModel() const
{
    return mMessageModel.data();
}

bool TextAutoGenerateChat::initialized() const
{
    return mInitialized;
}

void TextAutoGenerateChat::setInitialized(bool newInitialized)
{
    mInitialized = newInitialized;
}

QDebug operator<<(QDebug d, const TextAutoGenerateText::TextAutoGenerateChat &t)
{
    d.space() << "title:" << t.title();
    d.space() << "favorite:" << t.favorite();
    d.space() << "archived:" << t.archived();
    d.space() << "identifier:" << t.identifier();
    d.space() << "initialized:" << t.initialized();
    d.space() << "dateTime:" << t.dateTime();
    d.space() << "inProgress:" << t.inProgress();
    d.space() << "prompt:" << t.prompt();
    return d;
}

TextAutoGenerateChat::SectionHistory TextAutoGenerateChat::section() const
{
    if (favorite()) {
        return TextAutoGenerateChat::SectionHistory::Favorite;
    }
    if (!messageModel()) {
        return TextAutoGenerateChat::SectionHistory::Unknown;
    }
    if (messageModel()->messages().isEmpty()) {
        return mDateTime != -1 ? sectionMessage(mDateTime) : TextAutoGenerateChat::SectionHistory::Today;
    }
    return sectionMessage(messageModel()->messages().constLast().dateTime());
}

TextAutoGenerateChat::SectionHistory TextAutoGenerateChat::sectionMessage(qint64 dt) const
{
    if (dt == -1) {
        return TextAutoGenerateChat::SectionHistory::Unknown;
    }
    // Some persisted data may still contain millisecond timestamps.
    const qint64 dtInSeconds = (qAbs(dt) > 100000000000LL) ? (dt / 1000) : dt;
    const QDate d = QDateTime::fromSecsSinceEpoch(dtInSeconds).date();
    const QDate currentDate = QDate::currentDate();
    if (d == QDate::currentDate()) {
        return TextAutoGenerateChat::SectionHistory::Today;
    }

    const int daysOld = d.daysTo(currentDate);
    if (daysOld >= 1 && daysOld < 7) {
        return TextAutoGenerateChat::SectionHistory::LessThanSevenDays;
    }
    if (daysOld >= 7 && daysOld < 30) {
        return TextAutoGenerateChat::SectionHistory::LessThanThirtyDays;
    }

    return TextAutoGenerateChat::SectionHistory::Later;
}

QString TextAutoGenerateChat::prompt() const
{
    return mPrompt;
}

void TextAutoGenerateChat::setPrompt(const QString &newPrompt)
{
    mPrompt = newPrompt;
}

bool TextAutoGenerateChat::inProgress() const
{
    return mInProgress;
}

void TextAutoGenerateChat::setInProgress(bool newInProgress)
{
    mInProgress = newInProgress;
}

#include "moc_textautogeneratechat.cpp"
