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

  SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "ollamamodelavailablewidget.h"

#include "autogeneratetext_ollama_debug.h"
#include "modelsmanager/ollamamodeldownloadfromnamedialog.h"
#include "ollamacommonmodelavailableinfosdelegate.h"
#include "ollamacommonmodelavailableinfosmodel.h"
#include "ollamamodelavailableinfowidget.h"
#include "ollamamodelavailablesearchwidget.h"
#include "ollamamodeldownloadprogresswidget.h"
#include "plugincommonmodelinstalledinfossortproxymodel.h"
#include "widgets/availablemodel/textautogeneratemodelavailablelistview.h"
#include <KMessageBox>
#include <QScrollArea>
#include <QSplitter>
#include <QStackedWidget>
#include <QVBoxLayout>

using namespace Qt::Literals::StringLiterals;
OllamaModelAvailableWidget::OllamaModelAvailableWidget(OllamaManager *manager, QWidget *parent)
    : QWidget{parent}
    , mSearchWidget(new OllamaModelAvailableSearchWidget(this))
    , mListView(new TextAutoGenerateText::TextAutoGenerateModelAvailableListView(this))
    , mInfoWidget(new OllamaModelAvailableInfoWidget(manager, this))
    , mProxyModel(new PluginCommonModelInstalledInfosSortProxyModel(this))
    , mOllamaModelDownloadProgressWidget(new OllamaModelDownloadProgressWidget(manager, this))
    , mStackedWidget(new QStackedWidget(this))
    , mAvailableInfosModel(new OllamaCommonModelAvailableInfosModel(this))
    , mScrollArea(new QScrollArea(this))
{
    mListView->setItemDelegate(new OllamaCommonModelAvailableInfosDelegate(mListView));
    auto splitter = new QSplitter(this);
    splitter->setOrientation(Qt::Horizontal);
    splitter->setObjectName(u"splitter"_s);
    splitter->setChildrenCollapsible(false);
    auto mainLayout = new QVBoxLayout(this);
    mainLayout->setObjectName(u"mainlayout"_s);
    mainLayout->setContentsMargins({});
    mainLayout->setSpacing(0);

    mSearchWidget->setObjectName(u"mSearchWidget"_s);
    mainLayout->addWidget(mSearchWidget);
    mainLayout->addWidget(splitter, 1);

    mListView->setObjectName(u"mListView"_s);
    splitter->addWidget(mListView);

    mScrollArea->setObjectName(u"mScrollArea"_s);
    mScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    mScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mScrollArea->setWidgetResizable(true);
    mScrollArea->setWidget(mInfoWidget);
    mInfoWidget->setObjectName(u"mInfoWidget"_s);
    splitter->addWidget(mStackedWidget);
    mStackedWidget->hide();

    mOllamaModelDownloadProgressWidget->setObjectName(u"mOllamaModelDownloadProgressWidget"_s);
    mStackedWidget->setObjectName(u"mStackedWidget"_s);
    mStackedWidget->addWidget(mScrollArea);
    mStackedWidget->addWidget(mOllamaModelDownloadProgressWidget);
    mStackedWidget->setCurrentWidget(mScrollArea);
    connect(mInfoWidget, &OllamaModelAvailableInfoWidget::downloadModel, this, &OllamaModelAvailableWidget::slotDownloadModel);

    mProxyModel->setSourceModel(mAvailableInfosModel);
    mListView->setModel(mProxyModel);
    connect(mSearchWidget, &OllamaModelAvailableSearchWidget::searchText, mProxyModel, &PluginCommonModelInstalledInfosSortProxyModel::setFilterFixedString);
    connect(mSearchWidget, &OllamaModelAvailableSearchWidget::categoriesChanged, mProxyModel, &PluginCommonModelInstalledInfosSortProxyModel::setCategories);
    connect(mListView, &TextAutoGenerateText::TextAutoGenerateModelAvailableListView::pressed, this, &OllamaModelAvailableWidget::slotClicked);
    connect(mSearchWidget, &OllamaModelAvailableSearchWidget::addModel, this, &OllamaModelAvailableWidget::slotAddModel);
}

OllamaModelAvailableWidget::~OllamaModelAvailableWidget() = default;

void OllamaModelAvailableWidget::setAvailableInfos(const QList<OllamaCommonModelAvailableInfo> &infos)
{
    mAvailableInfosModel->setModelInfos(infos);
}

void OllamaModelAvailableWidget::slotAddModel()
{
    OllamaModelDownloadFromNameDialog d(this);
    if (d.exec()) {
        const QString modelName = d.modelName().trimmed();
        if (!modelName.isEmpty() && modelName.contains(u':')) {
            slotDownloadModel(modelName);
        } else {
            qCWarning(AUTOGENERATETEXT_OLLAMA_LOG) << "Invalid modelname " << modelName;
            KMessageBox::error(this, i18n("Model name must be as \"name:tag\""), i18n("Invalid Model Name"));
        }
    }
}

void OllamaModelAvailableWidget::slotClicked(const QModelIndex &index)
{
    if (!index.isValid()) {
        return;
    }
    mStackedWidget->setVisible(true);
    mStackedWidget->setCurrentWidget(mScrollArea);
    mInfoWidget->generateWidget(index);
}

void OllamaModelAvailableWidget::slotDownloadModel(const QString &url)
{
    mStackedWidget->setCurrentWidget(mOllamaModelDownloadProgressWidget);
    mOllamaModelDownloadProgressWidget->downloadModel(url);
}

#include "moc_ollamamodelavailablewidget.cpp"
