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

  SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "textautogeneratelistviewbasedelegate.h"
#include "widgets/view/textautogeneratedelegateutils.h"
#include "widgets/view/textautogeneratelistviewtextselection.h"
#include <QAbstractTextDocumentLayout>
#include <QListView>
#include <QTextFrame>
#include <QTextFrameFormat>

using namespace TextAutoGenerateText;
TextAutoGenerateListViewBaseDelegate::TextAutoGenerateListViewBaseDelegate(QListView *view)
    : QItemDelegate{view}
    , mListView(view)
    , mTextSelection(new TextAutoGenerateListViewTextSelection(this, this))
{
    connect(mTextSelection, &TextAutoGenerateListViewTextSelection::repaintNeeded, this, &TextAutoGenerateListViewBaseDelegate::updateView);
    mSizeHintCache.setMaxEntries(32);
}

TextAutoGenerateListViewBaseDelegate::~TextAutoGenerateListViewBaseDelegate() = default;

void TextAutoGenerateListViewBaseDelegate::clearSelection()
{
    mTextSelection->clear();
}

void TextAutoGenerateListViewBaseDelegate::clearDocumentCache()
{
    mDocumentCache.clear();
}

void TextAutoGenerateListViewBaseDelegate::clearCache()
{
    clearSizeHintCache();
    clearDocumentCache();
}

void TextAutoGenerateListViewBaseDelegate::clearSizeHintCache()
{
    mSizeHintCache.clear();
}

void TextAutoGenerateListViewBaseDelegate::removeMessageCache(const QByteArray &uuid)
{
    mDocumentCache.remove(uuid);
    mSizeHintCache.remove(uuid);
}

std::unique_ptr<QTextDocument> TextAutoGenerateListViewBaseDelegate::createTextDocument(const QString &text, int width) const
{
    std::unique_ptr<QTextDocument> doc(new QTextDocument);
    doc->setHtml(text);
    doc->setTextWidth(width);
    QTextFrame *frame = doc->frameAt(0);
    QTextFrameFormat frameFormat = frame->frameFormat();
    frameFormat.setMargin(0);
    frame->setFrameFormat(frameFormat);
    return doc;
}

bool TextAutoGenerateListViewBaseDelegate::mouseEvent([[maybe_unused]] QEvent *event,
                                                      [[maybe_unused]] const QStyleOptionViewItem &option,
                                                      [[maybe_unused]] const QModelIndex &index)
{
    return false;
}

bool TextAutoGenerateListViewBaseDelegate::maybeStartDrag([[maybe_unused]] QMouseEvent *event,
                                                          [[maybe_unused]] const QStyleOptionViewItem &option,
                                                          [[maybe_unused]] const QModelIndex &index)
{
    return false;
}

QString TextAutoGenerateListViewBaseDelegate::selectedText() const
{
    return mTextSelection->selectedText(TextAutoGenerateListViewTextSelection::Format::Text);
}

bool TextAutoGenerateListViewBaseDelegate::hasSelection() const
{
    return mTextSelection->hasSelection();
}

void TextAutoGenerateListViewBaseDelegate::selectAll([[maybe_unused]] const QStyleOptionViewItem &option, const QModelIndex &index)
{
    mTextSelection->selectMessage(index);
    mListView->update(index);
    TextAutoGenerateDelegateUtils::setClipboardSelection(mTextSelection);
}

QSize TextAutoGenerateListViewBaseDelegate::documentSizeHint(const QModelIndex &index,
                                                             int maxWidth,
                                                             [[maybe_unused]] const QStyleOptionViewItem &option,
                                                             qreal *pBaseLine) const
{
    auto *doc = documentForIndex(index, maxWidth);
    return textSizeHint(doc, pBaseLine);
}

QSize TextAutoGenerateListViewBaseDelegate::textSizeHint(QTextDocument *doc, qreal *pBaseLine) const
{
    if (!doc) {
        return {};
    }
    const QSize size(doc->idealWidth(), doc->size().height()); // do the layouting, required by lineAt(0) below

    const QTextLine &line = doc->firstBlock().layout()->lineAt(0);
    *pBaseLine = line.y() + line.ascent(); // relative
    // qDebug() << " doc->" << doc->toPlainText() << " size " << size;
    return size;
}

QString TextAutoGenerateListViewBaseDelegate::urlAt(const QModelIndex &index, QPoint pos) const
{
    auto document = documentForIndex(index, -1);
    if (!document) {
        return {};
    }
    return document->documentLayout()->anchorAt(pos);
}

#include "moc_textautogeneratelistviewbasedelegate.cpp"
