#include "WgcCapturer.h"
#include "qdebug.h"
#include "qwidget.h"
#ifdef _WIN32
#include "wgc/winrt.h"
#include <capturer/finder.h>
#include <winrt/base.h>
#endif
namespace {
QWidget* g_widget = nullptr;
winrt::Windows::System::DispatcherQueueController g_controller{nullptr};
winrt::Windows::UI::Composition::Compositor g_compositor{nullptr};
winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget g_target{nullptr};
winrt::Windows::UI::Composition::ContainerVisual g_root{nullptr};
} // namespace
namespace avrecorder {
namespace video {
WgcCapturer::WgcCapturer()
    : _app(nullptr)
{
    // _app = new App;
}
WgcCapturer::~WgcCapturer() { close(); if (_app) { delete _app; _app = nullptr; } }

#ifdef _WIN32
void InitWinRTCapture()
{
    // 初始化 COM/WinRT
    winrt::init_apartment(winrt::apartment_type::single_threaded);
    // 初始化 DispatcherQueue
    // 创建调度队列
    g_controller = CreateDispatcherQueueController();

    // 初始化合成器
    g_compositor = winrt::Windows::UI::Composition::Compositor();
    g_widget = new QWidget;

    g_target = CreateDesktopWindowTarget(g_compositor, (HWND) g_widget->winId());
    g_root = g_compositor.CreateContainerVisual();
    g_root.RelativeSizeAdjustment({1.0f, 1.0f});
    g_target.Root(g_root);
}
#endif

bool WgcCapturer::open(const CaptureTarget& target, int width, int height) {
#ifdef PLATFORM_WINDOWS
    close();
    if (!_app) {
        _app = new App;
        _app->Initialize(g_root);
    }
    if (target.type == CaptureTargetType::Window) {
        qDebug() << "WgcCapturer::open: Starting window capture for HWND:" << target.hwnd;
        bool result = _app->StartCaptureWindow(target.hwnd, width, height);
        if (!result) {
            qDebug() << "WgcCapturer::open: StartCaptureWindow failed for HWND:" << target.hwnd;
        }
        return result;
    } else if (target.type == CaptureTargetType::Monitor) {
        auto monitors = MonitorFinder::GetList();
        if (target.monitorIdx < 0 || target.monitorIdx >= (int)monitors.size()) return false;
        auto monitorInfo = MonitorFinder::GetList()[target.monitorIdx];
        if (!monitorInfo.monitor) {
            qDebug() << "monitorInfo.monitor is nullptr!";
            return false;
        }
        if (width <= 0 || height <= 0) {
            qDebug() << "Invalid width/height:" << width << height;
            return false;
        }
        try {
            return _app->StartCaptureMonitor(monitorInfo.monitor, width, height);
        } catch (const winrt::hresult_error& e) {
            qDebug() << "WGC StartCaptureMonitor exception:"
                     << QString::fromStdString(winrt::to_string(e.message()));
            return false;
        }
    }
    return false;
#else
    return false;
#endif
}

void WgcCapturer::close() {
#ifdef PLATFORM_WINDOWS
    qDebug() << "WgcCapturer::close() - 开始关闭WGC捕获器";
    if (_app) {
        qDebug() << "WgcCapturer::close() - 调用App::Close()";
        _app->Close();
        qDebug() << "WgcCapturer::close() - App::Close()完成";
    }
    qDebug() << "WgcCapturer::close() - WGC捕获器关闭完成";
#endif
}

AVFrame* WgcCapturer::getFrame() {
#ifdef PLATFORM_WINDOWS
    return _app ? _app->GetFrame() : nullptr;
#else
    return nullptr;
#endif
}

void WgcCapturer::setDrawCursor(bool enable) {
#ifdef PLATFORM_WINDOWS
    if (_app) _app->SetDrawCursor(enable);
#endif
}

} // namespace video
} // namespace avrecorder
