#include "pythonembed.h"
#pragma push_macro("slots")
#undef slots
#include <Python.h>
#pragma pop_macro("slots")
#include <QDebug>

PythonEmbed::PythonEmbed(QTextEdit* outputWidget, QObject* parent)
    : QObject(parent), m_outputWidget(outputWidget) {
    // Initialize Python
    Py_Initialize();

    m_initialized = true;

    // Initialize the output widget with Python prompt
    m_outputWidget->clear();
    m_outputWidget->append("Python 3.11.2 (main, Oct  5 2023, 17:20:59) [GCC 11.4.0] on linux\n");
    m_outputWidget->append("Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\n");
    m_outputWidget->append(">>> ");
}

PythonEmbed::~PythonEmbed() {
    if (m_initialized) {
        Py_Finalize();
    }
}

void PythonEmbed::runScript(const QString& scriptContent) {
    if (!m_initialized) {
        m_outputWidget->append("Python not initialized\n");
        return;
    }

    // Convert QString to const char*
    QByteArray scriptBytes = scriptContent.toUtf8();
    const char* script = scriptBytes.constData();

    // Run the script
    PyRun_SimpleString(script);

    // Check for any errors
    if (PyErr_Occurred()) {
        handlePythonError("Script execution error");
    } else {
        m_outputWidget->append("\n>>> ");
    }
}

void PythonEmbed::stopScript() {
    // In this simple implementation, we don't have a running Python thread
    // to stop, but we could add that functionality later
}

void PythonEmbed::handlePythonError(const char* context) {
    PyObject *type, *value, *traceback;
    PyErr_Fetch(&type, &value, &traceback);
    if (type) {
        PyObject *str = PyObject_Str(value);
        PyObject *bytes = PyUnicode_AsEncodedString(str, "utf-8", "strict");
        const char *error_msg = PyBytes_AS_STRING(bytes);

        QString errorString = QString::fromUtf8(context) + ": " + QString::fromUtf8(error_msg);
        m_outputWidget->append(errorString);

        Py_DecRef(str);
        Py_DecRef(bytes);
        Py_DecRef(type);
        Py_DecRef(value);
        Py_DecRef(traceback);
    } else {
        m_outputWidget->append(QString::fromUtf8(context) + ": No error information available");
    }
}
