#include "flutter_window.h"


#include <optional>

#include "flutter/generated_plugin_registrant.h"

#include "flutter/method_channel.h"

#include "flutter/standard_method_codec.h"


 


void myMethodChannel(flutter::FlutterEngine*);

FlutterWindow::FlutterWindow(const flutter::DartProject& project)
    : project_(project) {}

FlutterWindow::~FlutterWindow() {}

bool FlutterWindow::OnCreate() {
    if (!Win32Window::OnCreate()) {
        return false;
    }

    RECT frame = GetClientArea();

    // The size here must match the window dimensions to avoid unnecessary surface
    // creation / destruction in the startup path.
    flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
        frame.right - frame.left, frame.bottom - frame.top, project_);
    // Ensure that basic setup of the controller was successful.
    if (!flutter_controller_->engine() || !flutter_controller_->view()) {
        return false;
    }
    RegisterPlugins(flutter_controller_->engine());
    SetChildContent(flutter_controller_->view()->GetNativeWindow());

    myMethodChannel(flutter_controller_->engine());
   
    return true;
}

// flutter method register
void myMethodChannel(flutter::FlutterEngine* engine) {
    
    std::string channelName = "pulgin.pc.o2oa.net/notify";
    
    const flutter::StandardMethodCodec& codec = flutter::StandardMethodCodec::GetInstance();
     
    flutter::MethodChannel method_channel_(engine->messenger(), channelName, &codec);
    method_channel_.SetMethodCallHandler([](const flutter::MethodCall<>& call,
        std::unique_ptr<flutter::MethodResult<>> result) {
        
        if (call.method_name().compare("sendNotify") == 0) {
            const auto* arguments = std::get_if<flutter::EncodableMap>(call.arguments());
            std::string msgId;
            auto msgId_it = arguments->find(flutter::EncodableValue("msgId"));
            if (msgId_it != arguments->end()) {
                msgId = std::get<std::string>(msgId_it->second);
            }
            std::string msgTitle;
            auto msgTitle_it = arguments->find(flutter::EncodableValue("title"));
            if (msgTitle_it != arguments->end()) {
                msgTitle = std::get<std::string>(msgTitle_it->second);
            }
            std::string msgBody;
            auto msgBody_it = arguments->find(flutter::EncodableValue("msgBody"));
            if (msgBody_it != arguments->end()) {
                msgBody = std::get<std::string>(msgBody_it->second);
            }
            std::cout << "Native:Halo!" << std::endl;
            std::cout << "receive msg content : " << msgId << msgTitle << msgBody << std::endl;
            
            result->Success(flutter::EncodableValue("Call Native Successfully!"));
            //result->Error(flutter::EncodableValue("Call Native Failed!"));
        }
        });

}


  

void FlutterWindow::OnDestroy() {
    if (flutter_controller_) {
        flutter_controller_ = nullptr;
    }

    Win32Window::OnDestroy();
}

LRESULT
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
    WPARAM const wparam,
    LPARAM const lparam) noexcept {
    // Give Flutter, including plugins, an opportunity to handle window messages.
    if (flutter_controller_) {
        std::optional<LRESULT> result =
            flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
                lparam);
        if (result) {
            return *result;
        }
    }

    switch (message) {
    case WM_FONTCHANGE:
        flutter_controller_->engine()->ReloadSystemFonts();
        break;
    }

    return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}
