#include "doctemplatemanager.h"
#include <QDebug>
#include <QStandardPaths>
#include <QApplication>

// 静态成员初始化
DocTemplateManager* DocTemplateManager::m_instance = nullptr;

DocTemplateManager::DocTemplateManager(QObject* parent)
    : QObject(parent)
{
    // 设置默认文件路径
    QString appDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/kylin-aiassistant/template";
    m_dataFilePath = appDir + "/templates.json";
    m_outlinesDir = appDir + "/outlines";

    // 创建大纲目录
    QDir dir(m_outlinesDir);
    if (!dir.exists()) {
        dir.mkpath(".");
    }

    // 从文件加载数据
    loadFromFile();
}

DocTemplateManager::~DocTemplateManager()
{
    // 保存数据到文件
    saveToFile();
}

void DocTemplateManager::loadInitialTemplates()
{
    QFile file("://template/defaultDocs.json");
    if (!file.exists())
    {
        return;
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        return;
    }

    QByteArray jsonData = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(jsonData);
    if (doc.isNull() || !doc.isObject())
    {
        qWarning() << "Invalid JSON format in defaultTemplate data file";
        return;
    }

    QJsonObject root = doc.object();
    QJsonArray templatesArray = root["templates"].toArray();

    for (const QJsonValue& value : templatesArray)
    {
        if (value.isObject())
        {
            DocTemplate templateData;
            templateData.fromJson(value.toObject());
            addTemplate(templateData);
        }
    }
}

DocTemplateManager* DocTemplateManager::getInstance()
{
    if (!m_instance) {
        m_instance = new DocTemplateManager();
    }
    return m_instance;
}

QString DocTemplateManager::generateUUID() const
{
    return QUuid::createUuid().toString(QUuid::WithoutBraces);
}

QString DocTemplateManager::getOutlineFilePath(const QString& uuid) const
{
    return m_outlinesDir + "/" + uuid + ".txt";
}

bool DocTemplateManager::saveOutlineToFile(const QString& uuid, const QString& outlineContent)
{
    if (uuid.isEmpty() || outlineContent.isEmpty()) {
        return false;
    }

    QString filePath = getOutlineFilePath(uuid);
    QFile file(filePath);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning() << "Failed to open outline file for writing:" << filePath;
        return false;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << outlineContent;
    file.close();

    return true;
}

QString DocTemplateManager::loadOutlineFromFile(const QString& filePath) const
{
    if (filePath.isEmpty()) {
        return "";
    }

    QFile file(filePath);
    if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open outline file for reading:" << filePath;
        return "";
    }

    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString content = in.readAll();
    file.close();

    return content;
}

bool DocTemplateManager::removeOutlineFile(const QString& filePath)
{
    if (filePath.isEmpty()) {
        return false;
    }

    QFile file(filePath);
    if (file.exists()) {
        return file.remove();
    }
    return true; // 文件不存在也算删除成功
}

bool DocTemplateManager::addTemplate(const DocTemplate& templateData)
{
    // 检查UUID是否已存在
    QString uuid = templateData.uuid.isEmpty() ? generateUUID() : templateData.uuid;
    if (templateExists(uuid)) {
        qWarning() << "Template with UUID" << uuid << "already exists";
        return false;
    }

    DocTemplate newTemplate = templateData;
    newTemplate.uuid = uuid;

    // 如果提供了大纲内容，保存到单独的文件
    if (!templateData.templateOutline.isEmpty() &&
        !templateData.templateOutline.startsWith(m_outlinesDir)) {
        // 假设templateOutline字段包含的是大纲内容，而不是文件路径
        QString outlineContent = templateData.templateOutline;
        QString outlineFilePath = getOutlineFilePath(uuid);

        if (saveOutlineToFile(uuid, outlineContent)) {
            newTemplate.templateOutline = outlineFilePath;
        } else {
            qWarning() << "Failed to save outline to file for template:" << uuid;
            return false;
        }
    }

    m_templates.append(newTemplate);

    // 保存到文件
    if (saveToFile()) {
        emit templateAdded(newTemplate);
        return true;
    } else {
        // 如果保存失败，回滚
        // 使用索引查找并删除
        int index = -1;
        for (int i = 0; i < m_templates.size(); ++i) {
            if (m_templates[i].uuid == uuid) {
                index = i;
                break;
            }
        }
        if (index != -1) {
            m_templates.removeAt(index);
        }
        // 删除已创建的大纲文件
        if (!templateData.templateOutline.isEmpty()) {
            removeOutlineFile(getOutlineFilePath(uuid));
        }
        return false;
    }
}

bool DocTemplateManager::removeTemplate(const QString& uuid)
{
    for (int i = 0; i < m_templates.size(); ++i) {
        if (m_templates[i].uuid == uuid) {
            DocTemplate removedTemplate = m_templates[i];

            // 删除对应的大纲文件
            if (!removedTemplate.templateOutline.isEmpty()) {
                removeOutlineFile(removedTemplate.templateOutline);
            }

            m_templates.removeAt(i);

            // 保存到文件
            if (saveToFile()) {
                emit templateRemoved(uuid);
                return true;
            } else {
                // 如果保存失败，回滚（但大纲文件已删除，无法恢复）
                m_templates.insert(i, removedTemplate);
                return false;
            }
        }
    }

    qWarning() << "Template with UUID" << uuid << "not found";
    return false;
}

bool DocTemplateManager::updateTemplate(const QString& uuid, const DocTemplate& newData)
{
    for (int i = 0; i < m_templates.size(); ++i) {
        if (m_templates[i].uuid == uuid) {
            DocTemplate oldTemplate = m_templates[i];
            DocTemplate updatedTemplate = newData;
            updatedTemplate.uuid = uuid; // 确保UUID不变

            // 处理大纲内容
            if (!newData.templateOutline.isEmpty() &&
                !newData.templateOutline.startsWith(m_outlinesDir)) {
                // 新的大纲内容，需要保存到文件
                QString outlineFilePath = getOutlineFilePath(uuid);
                if (saveOutlineToFile(uuid, newData.templateOutline)) {
                    updatedTemplate.templateOutline = outlineFilePath;
                } else {
                    qWarning() << "Failed to save outline to file for template:" << uuid;
                    return false;
                }

                // 删除旧的大纲文件（如果路径不同）
                if (oldTemplate.templateOutline != outlineFilePath) {
                    removeOutlineFile(oldTemplate.templateOutline);
                }
            } else if (newData.templateOutline.isEmpty()) {
                // 清空大纲，删除文件
                removeOutlineFile(oldTemplate.templateOutline);
                updatedTemplate.templateOutline = "";
            }
            // 如果templateOutline已经是文件路径，则保持不变

            m_templates[i] = updatedTemplate;

            // 保存到文件
            if (saveToFile()) {
                emit templateUpdated(updatedTemplate);
                return true;
            } else {
                // 如果保存失败，回滚
                m_templates[i] = oldTemplate;
                return false;
            }
        }
    }

    qWarning() << "Template with UUID" << uuid << "not found for update";
    return false;
}

DocTemplate DocTemplateManager::getTemplate(const QString& uuid) const
{
    for (const DocTemplate& templateData : m_templates) {
        if (templateData.uuid == uuid) {
            return templateData;
        }
    }

    return DocTemplate(); // 返回空结构体
}

QList<DocTemplate> DocTemplateManager::getAllTemplates() const
{
    return m_templates;
}

QList<DocTemplate> DocTemplateManager::findTemplatesByName(const QString& name) const
{
    QList<DocTemplate> result;

    for (const DocTemplate& templateData : m_templates) {
        if (templateData.templateName.contains(name, Qt::CaseInsensitive)) {
            result.append(templateData);
        }
    }

    return result;
}

bool DocTemplateManager::templateExists(const QString& uuid) const
{
    for (const DocTemplate& templateData : m_templates) {
        if (templateData.uuid == uuid) {
            return true;
        }
    }
    return false;
}

bool DocTemplateManager::loadFromFile(const QString& filePath)
{
    QString loadPath = filePath.isEmpty() ? m_dataFilePath : filePath;

    QFile file(loadPath);
    if (!file.exists()) {
        qInfo() << "Template data file does not exist, will create new one:" << loadPath;
        loadInitialTemplates();
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open template data file for reading:" << loadPath;
        return false;
    }

    QByteArray jsonData = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(jsonData);
    if (doc.isNull() || !doc.isObject()) {
        qWarning() << "Invalid JSON format in template data file:" << loadPath;
        return false;
    }

    QJsonObject root = doc.object();
    QJsonArray templatesArray = root["templates"].toArray();

    m_templates.clear();
    for (const QJsonValue& value : templatesArray) {
        if (value.isObject()) {
            DocTemplate templateData;
            templateData.fromJson(value.toObject());
            m_templates.append(templateData);
        }
    }

    m_dataFilePath = loadPath;
    emit dataLoaded();

    qInfo() << "Loaded" << m_templates.size() << "templates from" << loadPath;
    return true;
}

bool DocTemplateManager::saveToFile(const QString& filePath)
{
    QString savePath = filePath.isEmpty() ? m_dataFilePath : filePath;

    QJsonArray templatesArray;
    for (const DocTemplate& templateData : m_templates) {
        templatesArray.append(templateData.toJson());
    }

    QJsonObject root;
    root["templates"] = templatesArray;

    QJsonDocument doc(root);
    QByteArray jsonData = doc.toJson(QJsonDocument::Indented);

    QFile file(savePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning() << "Failed to open template data file for writing:" << savePath;
        return false;
    }

    file.write(jsonData);
    file.close();

    if (!filePath.isEmpty()) {
        m_dataFilePath = savePath;
    }

    emit dataSaved();
    qInfo() << "Saved" << m_templates.size() << "templates to" << savePath;
    return true;
}
