// ============================================================
// vqt6/_bridge_core.cpp — QtCore C 桥接层实现
// ============================================================

#include "_bridge.h"
#include <QString>
#include <QByteArray>
#include <QObject>
#include <QCoreApplication>
#include <QTimer>
#include <QVariant>
#include <QEvent>
#include <QStringList>
#include <QList>
#include <QHash>
#include <QMutex>
#include <cstring>

// 全局回调表（线程安全）
namespace {
    QMutex g_slot_mutex;
    QHash<int, QPair<vqt6_slot_callback_t, void*>> g_slots;
}

// ============================================================
// QString
// ============================================================
extern "C" VQT6_API void* vqt6_qstring_create(const char* utf8) {
    if (utf8 == nullptr) return nullptr;
    return new QString(QString::fromUtf8(utf8));
}

extern "C" VQT6_API size_t vqt6_qstring_to_utf8(void* qstr, char* buf, size_t buf_size) {
    if (qstr == nullptr || buf == nullptr || buf_size == 0) return 0;
    QString* s = static_cast<QString*>(qstr);
    QByteArray ba = s->toUtf8();
    size_t len = static_cast<size_t>(ba.size());
    if (len >= buf_size) len = buf_size - 1;
    std::memcpy(buf, ba.constData(), len);
    buf[len] = '\0';
    return len;
}

extern "C" VQT6_API void vqt6_qstring_free(void* qstr) {
    delete static_cast<QString*>(qstr);
}

extern "C" VQT6_API int vqt6_qstring_length(void* qstr) {
    if (qstr == nullptr) return 0;
    return static_cast<QString*>(qstr)->length();
}

extern "C" VQT6_API int vqt6_qstring_is_empty(void* qstr) {
    if (qstr == nullptr) return 1;
    return static_cast<QString*>(qstr)->isEmpty() ? 1 : 0;
}

extern "C" VQT6_API int vqt6_qstring_equals(void* qstr, void* other) {
    if (qstr == nullptr || other == nullptr) return 0;
    return *static_cast<QString*>(qstr) == *static_cast<QString*>(other) ? 1 : 0;
}

extern "C" VQT6_API void* vqt6_qstring_append(void* qstr, void* other) {
    if (qstr == nullptr || other == nullptr) return nullptr;
    return new QString(*static_cast<QString*>(qstr) + *static_cast<QString*>(other));
}

// ============================================================
// QByteArray
// ============================================================
extern "C" VQT6_API void* vqt6_qbytearray_create(const void* data, size_t size) {
    if (data == nullptr) return new QByteArray();
    return new QByteArray(static_cast<const char*>(data), static_cast<int>(size));
}

extern "C" VQT6_API void* vqt6_qbytearray_data(void* qba, size_t* out_size) {
    if (qba == nullptr) return nullptr;
    QByteArray* ba = static_cast<QByteArray*>(qba);
    if (out_size != nullptr) *out_size = static_cast<size_t>(ba->size());
    return ba->data();
}

extern "C" VQT6_API size_t vqt6_qbytearray_size(void* qba) {
    if (qba == nullptr) return 0;
    return static_cast<size_t>(static_cast<QByteArray*>(qba)->size());
}

extern "C" VQT6_API void vqt6_qbytearray_free(void* qba) {
    delete static_cast<QByteArray*>(qba);
}

// ============================================================
// QObject
// ============================================================
extern "C" VQT6_API void vqt6_qobject_delete(void* obj) {
    if (obj == nullptr) return;
    delete static_cast<QObject*>(obj);
}

extern "C" VQT6_API void vqt6_qobject_delete_later(void* obj) {
    if (obj == nullptr) return;
    static_cast<QObject*>(obj)->deleteLater();
}

extern "C" VQT6_API void vqt6_qobject_set_object_name(void* obj, void* name) {
    if (obj == nullptr || name == nullptr) return;
    static_cast<QObject*>(obj)->setObjectName(*static_cast<QString*>(name));
}

extern "C" VQT6_API void* vqt6_qobject_object_name(void* obj) {
    if (obj == nullptr) return nullptr;
    return new QString(static_cast<QObject*>(obj)->objectName());
}

extern "C" VQT6_API void vqt6_qobject_set_parent(void* child, void* parent) {
    if (child == nullptr) return;
    static_cast<QObject*>(child)->setParent(static_cast<QObject*>(parent));
}

extern "C" VQT6_API void* vqt6_qobject_parent(void* obj) {
    if (obj == nullptr) return nullptr;
    return static_cast<QObject*>(obj)->parent();
}

extern "C" VQT6_API int vqt6_qobject_connect(void* sender, const char* signal_name,
                                             void* receiver, const char* slot_name) {
    if (sender == nullptr || receiver == nullptr || signal_name == nullptr || slot_name == nullptr)
        return 0;
    return QObject::connect(
        static_cast<QObject*>(sender), signal_name,
        static_cast<QObject*>(receiver), slot_name
    ) ? 1 : 0;
}

extern "C" VQT6_API int vqt6_qobject_disconnect(void* sender, const char* signal_name,
                                                void* receiver, const char* slot_name) {
    if (sender == nullptr || receiver == nullptr) return 0;
    return QObject::disconnect(
        static_cast<QObject*>(sender), signal_name,
        static_cast<QObject*>(receiver), slot_name
    ) ? 1 : 0;
}

extern "C" VQT6_API void vqt6_qobject_install_event_filter(void* watched, void* filter) {
    if (watched == nullptr || filter == nullptr) return;
    static_cast<QObject*>(watched)->installEventFilter(static_cast<QObject*>(filter));
}

extern "C" VQT6_API void vqt6_qobject_remove_event_filter(void* watched, void* filter) {
    if (watched == nullptr || filter == nullptr) return;
    static_cast<QObject*>(watched)->removeEventFilter(static_cast<QObject*>(filter));
}

// ============================================================
// QCoreApplication
// ============================================================
extern "C" VQT6_API void* vqt6_qcoreapp_create(const char* app_name) {
    if (app_name == nullptr) return nullptr;
    int argc = 1;
    static char app_name_copy[1024];
    std::strncpy(app_name_copy, app_name, sizeof(app_name_copy) - 1);
    app_name_copy[sizeof(app_name_copy) - 1] = '\0';
    char* argv[] = { app_name_copy, nullptr };
    return new QCoreApplication(argc, argv);
}

extern "C" VQT6_API void* vqt6_qcoreapp_instance(void) {
    return QCoreApplication::instance();
}

extern "C" VQT6_API int vqt6_qcoreapp_exec(void* app) {
    if (app == nullptr) return -1;
    return static_cast<QCoreApplication*>(app)->exec();
}

extern "C" VQT6_API void vqt6_qcoreapp_quit(void* app, int exit_code) {
    if (app == nullptr) return;
    // 优先使用 exit_code 重载
    QCoreApplication* a = static_cast<QCoreApplication*>(app);
    if (a == QCoreApplication::instance()) {
        a->exit(exit_code);
    }
}

extern "C" VQT6_API void vqt6_qcoreapp_exit(void* app, int exit_code) {
    if (app == nullptr) return;
    static_cast<QCoreApplication*>(app)->exit(exit_code);
}

extern "C" VQT6_API void vqt6_qcoreapp_process_events(void* app, int flags) {
    if (app == nullptr) return;
    static_cast<QCoreApplication*>(app)->processEvents(static_cast<QEventLoop::ProcessEventsFlag>(flags));
}

extern "C" VQT6_API void vqt6_qcoreapp_post_event(void* receiver, void* event) {
    if (receiver == nullptr || event == nullptr) return;
    QCoreApplication::postEvent(static_cast<QObject*>(receiver), static_cast<QEvent*>(event));
}

extern "C" VQT6_API int vqt6_qcoreapp_send_event(void* receiver, void* event) {
    if (receiver == nullptr || event == nullptr) return 0;
    return QCoreApplication::sendEvent(static_cast<QObject*>(receiver), static_cast<QEvent*>(event)) ? 1 : 0;
}

extern "C" VQT6_API void* vqt6_qcoreapp_organization_name(void* app) {
    if (app == nullptr) return nullptr;
    return new QString(QCoreApplication::organizationName());
}

extern "C" VQT6_API void vqt6_qcoreapp_set_organization_name(void* app, void* name) {
    if (app == nullptr || name == nullptr) return;
    QCoreApplication::setOrganizationName(*static_cast<QString*>(name));
}

extern "C" VQT6_API void* vqt6_qcoreapp_application_name(void* app) {
    if (app == nullptr) return nullptr;
    return new QString(QCoreApplication::applicationName());
}

extern "C" VQT6_API void vqt6_qcoreapp_set_application_name(void* app, void* name) {
    if (app == nullptr || name == nullptr) return;
    QCoreApplication::setApplicationName(*static_cast<QString*>(name));
}

// ============================================================
// QTimer
// ============================================================
extern "C" VQT6_API void* vqt6_qtimer_create(void) {
    return new QTimer();
}

extern "C" VQT6_API void* vqt6_qtimer_create_with_parent(void* parent) {
    if (parent == nullptr) return nullptr;
    return new QTimer(static_cast<QObject*>(parent));
}

extern "C" VQT6_API void vqt6_qtimer_start(void* timer, int interval_ms) {
    if (timer == nullptr) return;
    static_cast<QTimer*>(timer)->start(interval_ms);
}

extern "C" VQT6_API void vqt6_qtimer_stop(void* timer) {
    if (timer == nullptr) return;
    static_cast<QTimer*>(timer)->stop();
}

extern "C" VQT6_API void vqt6_qtimer_set_interval(void* timer, int interval_ms) {
    if (timer == nullptr) return;
    static_cast<QTimer*>(timer)->setInterval(interval_ms);
}

extern "C" VQT6_API int vqt6_qtimer_interval(void* timer) {
    if (timer == nullptr) return 0;
    return static_cast<QTimer*>(timer)->interval();
}

extern "C" VQT6_API int vqt6_qtimer_is_active(void* timer) {
    if (timer == nullptr) return 0;
    return static_cast<QTimer*>(timer)->isActive() ? 1 : 0;
}

extern "C" VQT6_API void vqt6_qtimer_set_single_shot(void* timer, int single_shot) {
    if (timer == nullptr) return;
    static_cast<QTimer*>(timer)->setSingleShot(single_shot != 0);
}

extern "C" VQT6_API int vqt6_qtimer_is_single_shot(void* timer) {
    if (timer == nullptr) return 0;
    return static_cast<QTimer*>(timer)->isSingleShot() ? 1 : 0;
}

// ============================================================
// QVariant
// ============================================================
extern "C" VQT6_API void* vqt6_qvariant_create_int(int value) {
    return new QVariant(value);
}

extern "C" VQT6_API void* vqt6_qvariant_create_double(double value) {
    return new QVariant(value);
}

extern "C" VQT6_API void* vqt6_qvariant_create_bool(int value) {
    return new QVariant(value != 0);
}

extern "C" VQT6_API void* vqt6_qvariant_create_string(void* s) {
    if (s == nullptr) return new QVariant();
    return new QVariant(*static_cast<QString*>(s));
}

extern "C" VQT6_API int vqt6_qvariant_to_int(void* v, int* ok) {
    if (v == nullptr) return 0;
    bool bok = false;
    int val = static_cast<QVariant*>(v)->toInt(&bok);
    if (ok != nullptr) *ok = bok ? 1 : 0;
    return val;
}

extern "C" VQT6_API double vqt6_qvariant_to_double(void* v, int* ok) {
    if (v == nullptr) return 0.0;
    bool bok = false;
    double val = static_cast<QVariant*>(v)->toDouble(&bok);
    if (ok != nullptr) *ok = bok ? 1 : 0;
    return val;
}

extern "C" VQT6_API int vqt6_qvariant_to_bool(void* v, int* ok) {
    if (v == nullptr) return 0;
    bool bok = false;
    bool val = static_cast<QVariant*>(v)->toBool();
    if (ok != nullptr) *ok = 1;
    return val ? 1 : 0;
}

extern "C" VQT6_API void* vqt6_qvariant_to_string(void* v) {
    if (v == nullptr) return nullptr;
    return new QString(static_cast<QVariant*>(v)->toString());
}

extern "C" VQT6_API int vqt6_qvariant_type_id(void* v) {
    if (v == nullptr) return 0;
    return static_cast<int>(static_cast<QVariant*>(v)->typeId());
}

extern "C" VQT6_API int vqt6_qvariant_is_valid(void* v) {
    if (v == nullptr) return 0;
    return static_cast<QVariant*>(v)->isValid() ? 1 : 0;
}

extern "C" VQT6_API void vqt6_qvariant_free(void* v) {
    delete static_cast<QVariant*>(v);
}

// ============================================================
// QEvent
// ============================================================
extern "C" VQT6_API int vqt6_qevent_type(void* event) {
    if (event == nullptr) return 0;
    return static_cast<int>(static_cast<QEvent*>(event)->type());
}

extern "C" VQT6_API void vqt6_qevent_accept(void* event) {
    if (event == nullptr) return;
    static_cast<QEvent*>(event)->accept();
}

extern "C" VQT6_API void vqt6_qevent_ignore(void* event) {
    if (event == nullptr) return;
    static_cast<QEvent*>(event)->ignore();
}

extern "C" VQT6_API int vqt6_qevent_is_accepted(void* event) {
    if (event == nullptr) return 0;
    return static_cast<QEvent*>(event)->isAccepted() ? 1 : 0;
}

// ============================================================
// QStringList
// ============================================================
extern "C" VQT6_API void* vqt6_qstringlist_create(void) {
    return new QStringList();
}

extern "C" VQT6_API void vqt6_qstringlist_append(void* list, void* str) {
    if (list == nullptr || str == nullptr) return;
    static_cast<QStringList*>(list)->append(*static_cast<QString*>(str));
}

extern "C" VQT6_API int vqt6_qstringlist_size(void* list) {
    if (list == nullptr) return 0;
    return static_cast<QStringList*>(list)->size();
}

extern "C" VQT6_API void* vqt6_qstringlist_at(void* list, int index) {
    if (list == nullptr) return nullptr;
    QStringList* sl = static_cast<QStringList*>(list);
    if (index < 0 || index >= sl->size()) return nullptr;
    return new QString(sl->at(index));
}

extern "C" VQT6_API void vqt6_qstringlist_free(void* list) {
    delete static_cast<QStringList*>(list);
}

// ============================================================
// QByteArrayList
// ============================================================
extern "C" VQT6_API void* vqt6_qbytearraylist_create(void) {
    return new QList<QByteArray>();
}

extern "C" VQT6_API void vqt6_qbytearraylist_append(void* list, void* qba) {
    if (list == nullptr || qba == nullptr) return;
    static_cast<QList<QByteArray>*>(list)->append(*static_cast<QByteArray*>(qba));
}

extern "C" VQT6_API int vqt6_qbytearraylist_size(void* list) {
    if (list == nullptr) return 0;
    return static_cast<QList<QByteArray>*>(list)->size();
}

extern "C" VQT6_API void* vqt6_qbytearraylist_at(void* list, int index) {
    if (list == nullptr) return nullptr;
    QList<QByteArray>* qbl = static_cast<QList<QByteArray>*>(list);
    if (index < 0 || index >= qbl->size()) return nullptr;
    return new QByteArray(qbl->at(index));
}

extern "C" VQT6_API void vqt6_qbytearraylist_free(void* list) {
    delete static_cast<QList<QByteArray>*>(list);
}

// ============================================================
// 全局回调注册表
// ============================================================
extern "C" VQT6_API void vqt6_register_slot(int slot_id, void* user_data) {
    QMutexLocker locker(&g_slot_mutex);
    g_slots.insert(slot_id, QPair<vqt6_slot_callback_t, void*>(nullptr, user_data));
}

extern "C" VQT6_API void vqt6_unregister_slot(int slot_id) {
    QMutexLocker locker(&g_slot_mutex);
    g_slots.remove(slot_id);
}

extern "C" VQT6_API void vqt6_trigger_slot(int slot_id) {
    QMutexLocker locker(&g_slot_mutex);
    auto it = g_slots.find(slot_id);
    if (it != g_slots.end() && it.value().first != nullptr) {
        it.value().first(slot_id, it.value().second);
    }
}
