#include "App.h"
// D3D
#include <d2d1_3.h>
#include <d3d11_4.h>
#include <dxgi1_6.h>
#include <wincodec.h>

#include "pch.h"

#include "basic/frame.h"

#include <QDebug>

using namespace winrt;
using namespace Windows::System;
using namespace Windows::Foundation;
using namespace Windows::UI;
using namespace Windows::UI::Composition;
using namespace Windows::Graphics::Capture;

void App::Initialize(ContainerVisual const& root)
{
    auto queue = DispatcherQueue::GetForCurrentThread();

    m_compositor = root.Compositor();
    m_root = m_compositor.CreateContainerVisual();
    m_content = m_compositor.CreateSpriteVisual();
    m_brush = m_compositor.CreateSurfaceBrush();

    m_root.RelativeSizeAdjustment({1, 1});
    root.Children().InsertAtTop(m_root);

    m_content.AnchorPoint({0.5f, 0.5f});
    m_content.RelativeOffsetAdjustment({0.5f, 0.5f, 0});
    m_content.RelativeSizeAdjustment({1, 1});
    m_content.Size({-80, -80});
    m_content.Brush(m_brush);
    m_brush.HorizontalAlignmentRatio(0.5f);
    m_brush.VerticalAlignmentRatio(0.5f);
    m_brush.Stretch(CompositionStretch::Uniform);
    auto shadow = m_compositor.CreateDropShadow();
    shadow.Mask(m_brush);
    m_content.Shadow(shadow);
    m_root.Children().InsertAtTop(m_content);

    auto d3dDevice = CreateD3DDevice();
    auto dxgiDevice = d3dDevice.as<IDXGIDevice>();
    m_device = CreateDirect3DDevice(dxgiDevice.get());
}

void App::Close()
{
    qDebug() << "App::Close() - 开始关闭App";
    if (m_capture) {
        qDebug() << "App::Close() - 调用SimpleCapture::Close()";
        m_capture->Close();
        qDebug() << "App::Close() - 删除SimpleCapture对象";
        delete m_capture;
        m_capture = nullptr;
        qDebug() << "App::Close() - SimpleCapture对象已删除";
    }
    qDebug() << "App::Close() - App关闭完成";
}

bool App::StartCaptureWindow(HWND hwnd, int width, int height)
{
    __DebugPrint("App::StartCaptureWindow: Starting window capture (HWND=0x%p, %dx%d)", hwnd, width, height);
    
    // 验证输入参数
    if (!hwnd) {
        __DebugPrint("App::StartCaptureWindow: Invalid HWND (null)");
        return false;
    }
    
    if (width <= 0 || height <= 0) {
        __DebugPrint("App::StartCaptureWindow: Invalid dimensions (%dx%d)", width, height);
        return false;
    }
    
    if (!m_device) {
        __DebugPrint("App::StartCaptureWindow: D3D device is null");
        return false;
    }
    
    if (!m_compositor) {
        __DebugPrint("App::StartCaptureWindow: Compositor is null");
        return false;
    }
    
    // 获取窗口信息用于调试
    RECT windowRect;
    if (::GetWindowRect(hwnd, &windowRect)) {
        __DebugPrint("App::StartCaptureWindow: Window rect (%ld,%ld,%ld,%ld)", 
            windowRect.left, windowRect.top, windowRect.right, windowRect.bottom);
    }
    
    wchar_t windowTitle[256] = {0};
    ::GetWindowTextW(hwnd, windowTitle, sizeof(windowTitle)/sizeof(wchar_t));
    __DebugPrint("App::StartCaptureWindow: Window title: %ls", windowTitle);
    
    try {
        Close();
        
        __DebugPrint("App::StartCaptureWindow: Creating capture item...");
        auto item = CreateCaptureItemForWindow(hwnd);
        if (!item) {
            __DebugPrint("App::StartCaptureWindow: CreateCaptureItemForWindow returned null");
            return false;
        }
        
        __DebugPrint("App::StartCaptureWindow: Creating SimpleCapture...");
        m_capture = new SimpleCapture(m_device, item, width, height);
        if (!m_capture) {
            __DebugPrint("App::StartCaptureWindow: Failed to create SimpleCapture");
            return false;
        }
        
        __DebugPrint("App::StartCaptureWindow: Creating surface...");
        auto surface = m_capture->CreateSurface(m_compositor);
        if (!surface) {
            __DebugPrint("App::StartCaptureWindow: Failed to create surface");
            delete m_capture;
            m_capture = nullptr;
            return false;
        }
        
        __DebugPrint("App::StartCaptureWindow: Setting surface to brush...");
        m_brush.Surface(surface);
        
        __DebugPrint("App::StartCaptureWindow: Starting capture...");
        m_capture->StartCapture();
        
        __DebugPrint("App::StartCaptureWindow: Window capture started successfully");
        return true;
        
    } catch (const winrt::hresult_error& e) {
        __DebugPrint("App::StartCaptureWindow: WinRT exception - HRESULT=0x%08lx, Message=%s", 
            static_cast<unsigned long>(e.code()), 
            winrt::to_string(e.message()).c_str());
        
        if (m_capture) {
            delete m_capture;
            m_capture = nullptr;
        }
        return false;
        
    } catch (const std::exception& e) {
        __DebugPrint("App::StartCaptureWindow: Standard exception - %s", e.what());
        
        if (m_capture) {
            delete m_capture;
            m_capture = nullptr;
        }
        return false;
        
    } catch (...) {
        __DebugPrint("App::StartCaptureWindow: Unknown exception");
        
        if (m_capture) {
            delete m_capture;
            m_capture = nullptr;
        }
        return false;
    }
}

void App::SetDrawCursor(bool isDrawCursor)
{
    if (m_capture == nullptr) {
        return;
    }
    m_capture->SetDrawCursor(isDrawCursor);
}

bool App::StartCaptureMonitor(HMONITOR monitor, int width, int height)
{
    Close();
    auto item = CreateCaptureItemForMonitor(monitor);
    if (!item) {
        __DebugPrint("CreateCaptureItemForMonitor returned null");
        return false;
    }
    m_capture = new SimpleCapture(m_device, item, width, height);
    auto surface = m_capture->CreateSurface(m_compositor);
    m_brush.Surface(surface);
    m_capture->StartCapture();
    return true;
}
