content: import 'dart:convert';
  import 'dart:ffi';
  
  import 'package:ffi/ffi.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter_hbb/plugin/ui_manager.dart';
  import 'package:flutter_hbb/plugin/utils/dialogs.dart';
  
  abstract class NativeHandler {
    bool onEvent(Map<String, dynamic> evt);
  }
  
  typedef OnSelectPeersCallback = Bool Function(Int returnCode,
      Pointer<Void> data, Uint64 dataLength, Pointer<Void> userData);
  typedef OnSelectPeersCallbackDart = bool Function(
      int returnCode, Pointer<Void> data, int dataLength, Pointer<Void> userData);
  
  class NativeUiHandler extends NativeHandler {
    NativeUiHandler._();
  
    static NativeUiHandler instance = NativeUiHandler._();
  
    @override
    bool onEvent(Map<String, dynamic> evt) {
      final name = evt['name'];
      final action = evt['action'];
      if (name != "native_ui") {
        return false;
      }
      switch (action) {
        case "select_peers":
          int cb = evt['cb'];
          int userData = evt['user_data'] ?? 0;
          final cbFuncNative = Pointer.fromAddress(cb)
              .cast<NativeFunction<OnSelectPeersCallback>>();
          final cbFuncDart = cbFuncNative.asFunction<OnSelectPeersCallbackDart>();
          onSelectPeers(cbFuncDart, userData);
          break;
        case "register_ui_entry":
          int cb = evt['on_tap_cb'];
          int userData = evt['user_data'] ?? 0;
          String title = evt['title'] ?? "";
          final cbFuncNative = Pointer.fromAddress(cb)
              .cast<NativeFunction<OnSelectPeersCallback>>();
          final cbFuncDart = cbFuncNative.asFunction<OnSelectPeersCallbackDart>();
          onRegisterUiEntry(title, cbFuncDart, userData);
          break;
        default:
          return false;
      }
      return true;
    }
  
    void onSelectPeers(OnSelectPeersCallbackDart cb, int userData) async {
      showPeerSelectionDialog(onPeersCallback: (peers) {
        String json = jsonEncode(<String, dynamic> {
          "peers": peers
        });
        final native = json.toNativeUtf8();
        cb(0, native.cast(), native.length, Pointer.fromAddress(userData));
        malloc.free(native);
      });
    }
    
    void onRegisterUiEntry(String title, OnSelectPeersCallbackDart cbFuncDart, int userData) {
      Widget widget = InkWell(
        child: Container(
          height: 25.0,
          child: Row(
            children: [
              Expanded(child: Text(title)),
              Icon(Icons.chevron_right_rounded, size: 12.0,)
            ],
          ),
        ),
      );
      PluginUiManager.instance.registerEntry(title, widget);
    }
  }
  