#include "playbookmanager.h"
#include <QFile>
#include <QTextStream>
#include <QRegularExpression>
#include <QFileInfo>
#include <QDebug>

PlaybookManager::PlaybookManager(QObject *parent)
    : QObject(parent)
{
}

QList<PlaybookInfo> PlaybookManager::getPlaybooks() const
{
    return m_playbooks;
}

bool PlaybookManager::addPlaybook(const QString &path)
{
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        emit errorOccurred(tr("Failed to open playbook file: %1").arg(path));
        return false;
    }

    QString content = file.readAll();
    file.close();

    PlaybookInfo info = parsePlaybook(content);
    info.name = QFileInfo(path).fileName();

    m_playbooks.append(info);
    emit playbooksChanged();
    return true;
}

bool PlaybookManager::removePlaybook(const QString &name)
{
    auto it = std::find_if(m_playbooks.begin(), m_playbooks.end(),
                           [&name](const PlaybookInfo &info) { return info.name == name; });
    if (it != m_playbooks.end()) {
        m_playbooks.erase(it);
        emit playbooksChanged();
        return true;
    }
    return false;
}

bool PlaybookManager::editPlaybook(const QString &name, const QString &content)
{
    auto it = std::find_if(m_playbooks.begin(), m_playbooks.end(),
                           [&name](const PlaybookInfo &info) { return info.name == name; });
    if (it != m_playbooks.end()) {
        PlaybookInfo newInfo = parsePlaybook(content);
        newInfo.name = name;
        *it = newInfo;

        // Save the edited content to file
        QFile file(name);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            emit errorOccurred(tr("Failed to open playbook file for writing: %1").arg(name));
            return false;
        }

        QTextStream out(&file);
        out << content;
        file.close();

        emit playbooksChanged();
        return true;
    }
    emit errorOccurred(tr("Playbook not found: %1").arg(name));
    return false;
}

QString PlaybookManager::getPlaybookContent(const QString &name) const
{
    auto it = std::find_if(m_playbooks.begin(), m_playbooks.end(),
                           [&name](const PlaybookInfo &info) { return info.name == name; });
    if (it != m_playbooks.end()) {
        QFile file(name);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qWarning() << tr("Failed to open playbook file: %1").arg(name);
            return QString();
        }

        QString content = file.readAll();
        file.close();
        return content;
    }
    return QString();
}

PlaybookInfo PlaybookManager::parsePlaybook(const QString &content) const
{
    PlaybookInfo info;

    // Parse purpose (name declared at the top of the playbook file)
    QRegularExpression nameRegex(R"(^-\s*name:\s*(.+)$)", QRegularExpression::MultilineOption);
    auto nameMatch = nameRegex.match(content);
    if (nameMatch.hasMatch()) {
        info.purpose = nameMatch.captured(1).trimmed();
    }

    // Parse tags
    QRegularExpression tagsRegex(R"(^\s*tags:\s*\[(.*)\])", QRegularExpression::MultilineOption);
    auto tagsMatch = tagsRegex.match(content);
    if (tagsMatch.hasMatch()) {
        QString tagsStr = tagsMatch.captured(1);
        info.tags = tagsStr.split(',', Qt::SkipEmptyParts);
        for (auto &tag : info.tags) {
            tag = tag.trimmed();
        }
    }

    return info;
}

