#include "predictquestion.h"
#include "global_key_define.h"
#include "research_key_define.h"

#include <QLocale>
#include <QRegularExpression>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QLoggingCategory>

Q_DECLARE_LOGGING_CATEGORY(logResearch)

using namespace uos_ai;

PredictQuestion::PredictQuestion(QObject *parent)
    : LlmAgent(parent)
{
    m_name = "PredictQuestionAgent";
    m_description = "Generate questions users might ask next.";
    m_systemPrompt = R"(# Role
You are an expert in "User Intent Prediction and Content Optimization." You serve a DeepResearch system. Your task is to read the user's initial [Research Topic] and the system-generated [Final Report], and predict the 3-5 most likely follow-up modification instructions or follow-up questions the user might ask after reading the report.

# Context
The user has just read a deep research report generated by AI. The user may have further requirements regarding the report's length, depth, focus, or specific details. Your goal is to generate "Quick Replies" (suggested next steps) to help the user quickly refine the report or initiate the next round of conversation.

# Analysis Framework (Think Step-by-Step)
Before generating suggestions, analyze the content quickly across these dimensions:
1. **Completeness Check**: Did the report miss a key sub-field or aspect of the topic?
2. **Depth Assessment**: Are certain parts too superficial? Does the user need more specific data or case studies?
3. **Style & Format**: Is the report too long/short? Is the tone too academic/casual?
4. **Extended Exploration**: Based on the report's conclusions, what is the user's most logical next action?

# Guideline for Suggestions
Generated suggestions must fit the following categories to ensure diversity:
1. **Content Drill-down**: Dig deeper into a specific point mentioned in the report.
2. **Style/Format Refinement**: Adjust word count, tone.
3. **Critical View**: Ask for counter-arguments, potential risks, or competitor comparisons.
4. **Actionable Implementation**: Ask for specific execution steps or a summary of key takeaways.

# Constraints
* **First-Person Perspective**: Suggestions must be written in the user's voice (e.g., "Help me expand on..." instead of "The user might want...").
* **Concise & Clear**: Keep each suggestion under 20 words, suitable for UI buttons.
* **Diversity**: Do not generate similar suggestions; they must cover different dimensions defined in the guidelines.

# Output Format
Please output ONLY a JSON formatted list. Do not include any conversational text or markdown code block markers outside of the JSON.

Format Example:
```json
[
"Expand and enrich the content of Chapter 3",
"Refine the tone of Chapter 5 to be more professional and business-oriented",
"Rewrite this article in a style suitable for a social media platform"
]
```)";

    QString language = QLocale::system().language() == QLocale::Chinese ? "Chinese" : "English";
    m_systemPrompt += QString("\n\nPlease respond in %1.").arg(language);
}

QVariantHash PredictQuestion::processRequest(const ModelMessage &question, const QList<ModelMessage> &history, const QVariantHash &params)
{
    // Disable streaming for JSON output
    m_modelParams[STR_KEY_STREAM] = false;

    QString userTask = question.content.value(0).data.toString();
    QString articleContent = params.value(STR_RESEARCH_ARTICLE_CONTENT).toString();

    ModelMessage ques = question;
    if (!articleContent.isEmpty()) {
        ques.role = STR_KEY_USER;
        ques.content = {{ContentType::CntText,
                         QString("User Original Task:%1\nFinal Content:\n%2").arg(userTask, articleContent)}};
    }

    QVariantHash res = LlmAgent::processRequest(ques, history, params);

    QString content = res.value(STR_KEY_CONTENT).value<ModelMessage>().content.value(0).data.toString();

    QJsonArray questionArray;
    QRegularExpression regex("```json\\s*([\\s\\S]*?)\\s*```", QRegularExpression::DotMatchesEverythingOption);
    QRegularExpressionMatch match = regex.match(content);
    QJsonParseError parseError;
    if (match.hasMatch()) {
        questionArray = QJsonDocument::fromJson(match.captured(1).trimmed().toUtf8(), &parseError).array();
    } else {
        questionArray = QJsonDocument::fromJson(content.trimmed().toUtf8(), &parseError).array();
    }
    if (questionArray.isEmpty()) {
        qCWarning(logResearch) << "PredictQuestion: failed to parse questions JSON:"
                               << parseError.errorString() << "raw:" << content.left(200);
    }

    QStringList questions;
    for (const QJsonValue &val : questionArray)
        questions.append(val.toString());

    emitGuessYouWant(questions);

    return res;
}

void PredictQuestion::emitGuessYouWant(const QStringList &questions)
{
    QVariantHash data;
    data[STR_KEY_CONTENT] = questions;

    RenderMessage rmsg;
    rmsg.type = ContentType::CntGuessYouWant;
    rmsg.data = data;
    emit messageReceived(RenderMessageList{rmsg});
}
