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

  SPDX-License-Identifier: GPL-2.0-or-later
*/

#pragma once
#include "textautogeneratetext_export.h"
#include <KConfigGroup>
#include <QJsonArray>
#include <QObject>
#include <TextAutoGenerateText/TextAutoGenerateAttachmentUtils>
#include <TextAutoGenerateText/TextAutoGenerateReply>
#include <TextAutoGenerateText/TextAutoGenerateTextRequest>
#include <memory>
class QDebug;
class QAction;
class QJsonObject;
namespace TextAutoGenerateText
{
class TextAutoGenerateTextPluginPrivate;
class TextAutoGenerateManager;
class TextAutoGenerateTextInstance;
/*!
 * \class TextAutoGenerateText::TextAutoGenerateTextPlugin
 * \brief The TextAutoGenerateTextPlugin class
 * \author Laurent Montel <montel@kde.org>
 * \inmodule TextAutoGenerateText
 * \inheaderfile TextAutoGenerateText/TextAutoGenerateTextPlugin
 */
class TEXTAUTOGENERATETEXT_EXPORT TextAutoGenerateTextPlugin : public QObject
{
    Q_OBJECT
public:
    enum class EngineType : uint8_t {
        Local,
        Network,
    };
    struct TEXTAUTOGENERATETEXT_EXPORT ModelInfoNameAndIdentifier {
        QString modelName;
        QString identifier;
        [[nodiscard]] bool isValid() const;
    };

    struct TEXTAUTOGENERATETEXT_EXPORT SendToAssistantInfo {
        QString message;
        QByteArray messageUuid;
        QByteArray chatId;
        QJsonArray messagesArray;
        QList<QByteArray> tools;
    };

    struct TEXTAUTOGENERATETEXT_EXPORT EditSendInfo {
        QString message;
        QByteArray messageUuid;
        QByteArray chatId;
        QList<QByteArray> tools;
        QList<TextAutoGenerateText::TextAutoGenerateAttachmentUtils::AttachmentElementInfo> attachmentInfoList;
    };

    /*!
     */
    explicit TextAutoGenerateTextPlugin(TextAutoGenerateText::TextAutoGenerateManager *manager,
                                        TextAutoGenerateText::TextAutoGenerateTextInstance *instance,
                                        QObject *parent = nullptr);
    /*!
     */
    ~TextAutoGenerateTextPlugin() override;

    /*!
     */
    virtual void showConfigureDialog(QWidget *parentWidget) = 0;

    struct ActivateInstanceActionInfo {
        QAction *action = nullptr;
        QString text;
    };

    /*!
     * \brief activateInstanceAction
     * \return widget as button or other for activate
     */
    [[nodiscard]] virtual ActivateInstanceActionInfo activateInstanceAction();

    /*!
     */
    virtual void clear();
    /*!
     */
    [[nodiscard]] virtual QString translatedPluginName() const = 0;

    /*!
     */
    void setHasError(bool error);

    /*!
     */
    [[nodiscard]] bool ready() const;
    /*!
     */
    void setReady(bool newReady);

    /*!
     */
    virtual void cancelRequest(const QByteArray &uuid);
    /*!
     */
    void sendMessage(const EditSendInfo &info);
    /*!
     */
    void editMessage(const EditSendInfo &info);

    /*!
     */
    [[nodiscard]] virtual QString engineName() const = 0;

    /*!
     */
    [[nodiscard]] virtual QString currentModel() const = 0;
    /*!
     */
    virtual void setCurrentModel(const QString &) = 0;

    /*!
     */
    [[nodiscard]] TextAutoGenerateText::TextAutoGenerateManager *manager() const;
    /*!
     */
    virtual void askToAssistant(const QString &msg) = 0;

    /*!
     */
    virtual void load(const KConfigGroup &config);
    /*!
     */
    virtual void save(KConfigGroup &config);
    /*!
     */
    virtual void remove();

    /*!
     */
    [[nodiscard]] virtual QString displayName() const = 0;
    /*!
     */
    virtual void setDisplayName(const QString &newName) = 0;

    /*!
     */
    [[nodiscard]] QList<TextAutoGenerateText::TextAutoGenerateTextPlugin::ModelInfoNameAndIdentifier> models() const;

    /*!
     */
    [[nodiscard]] QByteArray instanceUuid() const;

    /*!
     */
    [[nodiscard]] virtual TextAutoGenerateText::TextAutoGenerateTextPlugin::EngineType engineType() const = 0;

    /*!
     */
    [[nodiscard]] static QString convertEngineType(TextAutoGenerateText::TextAutoGenerateTextPlugin::EngineType type);

    /*!
     */
    [[nodiscard]] virtual bool hasVisionSupport() const = 0;
    /*!
     */
    [[nodiscard]] virtual bool hasToolsSupport() const = 0;
    /*!
     */
    [[nodiscard]] virtual bool hasOcrSupport() const = 0;
    /*!
     */
    [[nodiscard]] virtual bool hasAudioSupport() const = 0;

    /*!
     */
    [[nodiscard]] virtual bool hasThinkSupport() const = 0;

    /*!
     * \brief shareNamePrompt
     * \return
     */
    [[nodiscard]] virtual QString shareNamePrompt() const;

    /*!
     * \brief hasSystemMessageSupport
     * \return true if instance has system message support
     */
    [[nodiscard]] virtual bool hasSystemMessageSupport() const;

    /*!
     * \brief hasTextOnlySupport
     * \return true if we just have text only support
     */
    [[nodiscard]] virtual bool hasTextOnlySupport() const;
Q_SIGNALS:
    /*!
     */
    void downloadErrorOccurred(const QString &message);
    /*!
     */
    void initializedDone();
    /*!
     */
    void askToAssistantAnswer(const TextAutoGenerateText::TextAutoGenerateReply::Response &message);
    /*!
     */
    void askToAssistantDone();
    /*!
     */
    void configChanged();
    /*!
     */
    void downloadModelFinished(const QString &modelName);
    /*!
     */
    void callTools(const QList<TextAutoGenerateText::TextAutoGenerateReply::ToolCallArgumentInfo> &info);
    /*!
     */
    void currentModelChanged();

    /*!
     */
    void errorOccurred(QNetworkReply::NetworkError e, const QString &errorString);

    /*!
     */
    void processStartSuccessed();

    /*!
     */
    void processStartFailed(const QString &errorStr);

protected:
    /*!
     */
    virtual void sendToAssistant(const SendToAssistantInfo &info) = 0;
    /*!
     */
    [[nodiscard]] QString fallBackModel() const;
    /*!
     */
    [[nodiscard]] TextAutoGenerateText::TextAutoGenerateTextRequest convertSendToAssistantInfoToTextRequest(const SendToAssistantInfo &info) const;
    QMultiHash<TextAutoGenerateText::TextAutoGenerateReply *, QPair<QByteArray, QMetaObject::Connection>> mConnections;
    QList<ModelInfoNameAndIdentifier> mModels;

private:
    TEXTAUTOGENERATETEXT_NO_EXPORT void initializeProgress(const SendToAssistantInfo &info);
    [[nodiscard]] TEXTAUTOGENERATETEXT_NO_EXPORT QJsonObject createPromptMessage() const;
    [[nodiscard]] TEXTAUTOGENERATETEXT_NO_EXPORT QJsonArray createListMessages(const QList<QJsonObject> &objs) const;
    std::unique_ptr<TextAutoGenerateTextPluginPrivate> const d;
};
}
Q_DECLARE_TYPEINFO(TextAutoGenerateText::TextAutoGenerateTextPlugin::SendToAssistantInfo, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(TextAutoGenerateText::TextAutoGenerateTextPlugin::ModelInfoNameAndIdentifier, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(TextAutoGenerateText::TextAutoGenerateTextPlugin::EditSendInfo, Q_RELOCATABLE_TYPE);
TEXTAUTOGENERATETEXT_EXPORT QDebug operator<<(QDebug d, const TextAutoGenerateText::TextAutoGenerateTextPlugin::SendToAssistantInfo &t);
TEXTAUTOGENERATETEXT_EXPORT QDebug operator<<(QDebug d, const TextAutoGenerateText::TextAutoGenerateTextPlugin::ModelInfoNameAndIdentifier &t);
TEXTAUTOGENERATETEXT_EXPORT QDebug operator<<(QDebug d, const TextAutoGenerateText::TextAutoGenerateTextPlugin::EditSendInfo &t);
