import 'dart:convert';
import 'dart:io';

import 'package:app_settings/app_settings.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:get/get.dart' as my_get;
import 'package:get/get.dart';
import 'package:o2oa_all_platform/common/extension/index.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../pages/apps/process/process_picker/index.dart';
import '../../pages/common/create_form/index.dart';
import '../../pages/common/inner_webview/index.dart';
import '../../pages/common/portal/index.dart';
import '../../pages/common/scan/index.dart';
import '../../pages/home/contact/contact_picker/index.dart';
import '../../pages/home/contact/org_person_list/index.dart';
import '../../pages/home/contact/person/index.dart';
import '../../pages/home/im/im_chat/index.dart';
import '../../pages/home/im/instant_chat/index.dart';
import '../../pages/home/im/speech_assistant_chat/index.dart';
import '../api/index.dart';
import '../models/index.dart';
import '../routers/index.dart';
import '../services/index.dart';
import '../values/o2.dart';
import '../widgets/index.dart';
import 'geolocator_helper.dart';
import 'javascript_navigation_interface.dart';
import 'loading.dart';
import 'log_util.dart';
import 'o2_api_manager.dart';
import 'o2_contact_permission_manager.dart';
import 'o2_file_path_util.dart';
import 'o2_utils.dart';

typedef O2ScanCallback = void Function(String result);

///
/// webview js api 注入
///
class O2JavascriptHandler {
  // webview 的 controller 必须注入
  InAppWebViewController? webviewController;
  // 操作窗口相关的接口 必须注入
  JsNavigationInterface? jsNavigationInterface;

  // 输入的 controller
  TextEditingController? _inputController;

  O2JavascriptHandlerData o2mNotification() {
    return O2JavascriptHandlerData(
        key: "o2mNotification",
        callback: (arguments) {
          if (arguments.isNotEmpty) {
            _notification((arguments[0] as String?) ?? "");
          }
          return true;
        });
  }

  O2JavascriptHandlerData o2mUtil() {
    return O2JavascriptHandlerData(
        key: "o2mUtil",
        callback: (arguments) {
          if (arguments.isNotEmpty) {
            _util((arguments[0] as String?) ?? '');
          }
          return true;
        });
  }

  O2JavascriptHandlerData o2mBiz() {
    return O2JavascriptHandlerData(
        key: "o2mBiz",
        callback: (arguments) {
          if (arguments.isNotEmpty) {
            _biz((arguments[0] as String?) ?? '');
          }
          return true;
        });
  }

  /// o2mBiz 模块处理
  _biz(String msg) {
    OLogger.d("执行 Biz , 命令：$msg");
    if (msg.isEmpty == true) {
      return;
    }
    final jsMessage = JsMessage.fromJson(O2Utils.parseStringToJson(msg));
    switch (jsMessage.type) {
      case 'contact.departmentPicker':
        _departmentPicker(jsMessage);
        break;
      case 'contact.identityPicker':
        _identityPicker(jsMessage);
        break;
      case 'contact.groupPicker':
        _groupPicker(jsMessage);
        break;
      case 'contact.personPicker':
        _personPicker(jsMessage);
        break;
      case 'contact.complexPicker':
        _complexPicker(jsMessage);
        break;
      case 'contact.searchPage':
        _searchPage(jsMessage);
        break;
      case 'contact.personInfoPage':
        _personInfoPage(jsMessage);
      case 'contact.orgInfoPage':
        _orgInfoPage(jsMessage);
        break;
      case 'settings.openMyProfile':
        _settingOpenMyProfile(jsMessage);
        break;
      case 'settings.safeAndAccount':
        _settingOpenSafeAndAccount(jsMessage);
        break;
      case 'settings.skin':
        _settingOpenAppSkin(jsMessage);
        break;
      case 'settings.notice':
        _settingOpenAppNotice(jsMessage);
        break;
      case 'settings.common':
        _settingOpenAppCommon(jsMessage);
        break;
      case 'settings.about':
        _settingOpenAppAbout(jsMessage);
        break;
      case 'settings.logout':
        _settingLogout(jsMessage);
        break;
      case 'im.openConversation':
        _openImConversation(jsMessage);
        break;
      case 'im.openChatWithPerson':
        _openImChatWithSomeone(jsMessage);
        break;
      case 'im.openInstantChat':
        _openImInstantChat(jsMessage);
        break;
      case 'im.startSingleChat':
        _startSingleChat(jsMessage);
        break;
      case 'im.startGroupChat':
        _startGroupChat(jsMessage);
        break;
      default:
        OLogger.e('错误的类型 ${jsMessage.type}');
        break;
    }
  }

  /// o2mUtil 模块处理
  _util(String msg) {
    OLogger.d("执行 Util , 命令：$msg");
    if (msg.isEmpty == true) {
      return;
    }
    final jsMessage = JsMessage.fromJson(O2Utils.parseStringToJson(msg));
    switch (jsMessage.type) {
      case 'date.datePicker':
        _datePicker(jsMessage);
        break;
      case 'date.timePicker':
        _timePicker(jsMessage);
        break;
      case 'calendar.chooseOneDay':
        _datePicker(jsMessage);
        break;
      case 'calendar.chooseDateTime':
        _dateTimePicker(jsMessage);
        break;
      case 'date.dateTimePicker':
        _dateTimePicker(jsMessage);
        break;
      case 'calendar.chooseInterval':
        _chooseInterval(jsMessage);
        break;
      case 'device.rotate':
        _rotate(jsMessage);
        break;
      case 'device.getPhoneInfo':
        _getPhoneInfo(jsMessage);
        break;
      case 'device.scan':
        _scan(jsMessage);
        break;
      case 'device.location':
        _location(jsMessage);
        break;
      case 'device.localAuth':
        _localAuth(jsMessage);
        break;
      case 'navigation.setTitle':
        _navigationSetTitle(jsMessage);
        break;
      case 'navigation.close':
        _navigationClose(jsMessage);
        break;
      case 'navigation.goBack':
        _navigationGoBack(jsMessage);
        break;
      case 'navigation.openInnerApp':
        _openInnerApp(jsMessage);
        break;
      case 'navigation.openOtherApp':
        _openOtherApp(jsMessage);
        break;
      case 'navigation.openWindow':
        _openWindow(jsMessage);
        break;
      case 'navigation.openInBrowser':
        _openCurrentPageInBrowser(jsMessage);
        break;
      case 'navigation.clearCache':
        _clearCache(jsMessage);
        break;
      case 'navigation.share':
        _share(jsMessage);
        break;
      case 'settings.openMyProfile':
        _settingOpenMyProfile(jsMessage);
        break;
      case 'settings.safeAndAccount':
        _settingOpenSafeAndAccount(jsMessage);
        break;
      case 'settings.skin':
        _settingOpenAppSkin(jsMessage);
        break;
      case 'settings.notice':
        _settingOpenAppNotice(jsMessage);
        break;
      case 'settings.common':
        _settingOpenAppCommon(jsMessage);
        break;
      case 'settings.about':
        _settingOpenAppAbout(jsMessage);
        break;
      case 'settings.logout':
        _settingLogout(jsMessage);
        break;
      default:
        OLogger.e('错误的类型 ${jsMessage.type}');
        break;
    }
  }

  /// o2mNotification 模块处理
  _notification(String msg) {
    OLogger.d("执行 Notification , 命令：$msg");
    if (msg.isEmpty == true) {
      return;
    }
    final jsMessage = JsMessage.fromJson(O2Utils.parseStringToJson(msg));
    switch (jsMessage.type) {
      case 'alert':
        _alert(jsMessage);
        break;
      case 'confirm':
        _confirm(jsMessage);
        break;
      case 'prompt':
        _prompt(jsMessage);
        break;
      case 'vibrate':
        _vibrate(jsMessage);
        break;
      case 'toast':
        _toast(jsMessage);
        break;
      case 'actionSheet':
        _actionSheet(jsMessage);
        break;
      case 'showLoading':
        _showLoading(jsMessage);
        break;
      case 'hideLoading':
        _hideLoading(jsMessage);
        break;
      default:
        OLogger.e('错误的类型 ${jsMessage.type}');
        break;
    }
  }

  /// alert 提示框
  _alert(JsMessage jsMessage) {
    final context = my_get.Get.context;
    JsNotificationAlertMessage alertMessage =
        JsNotificationAlertMessage.fromJson(jsMessage.data ?? {});
    String callback = jsMessage.callback ?? '';
    if (alertMessage.message == null || alertMessage.message?.isEmpty == true) {
      Loading.showError('没有传入内容！');
      return;
    }
    O2UI.showAlert(context, alertMessage.message!,
        title: alertMessage.title, okText: alertMessage.buttonName);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: "$callback()");
    }
  }

  /// confirm  确认框
  _confirm(JsMessage jsMessage) {
    final context = my_get.Get.context;
    JsNotificationConfirmMessage confirmMessage =
        JsNotificationConfirmMessage.fromJson(jsMessage.data ?? {});
    String callback = jsMessage.callback ?? '';
    if (confirmMessage.message == null ||
        confirmMessage.message?.isEmpty == true) {
      Loading.showError('args_error'.tr);
      return;
    }
    var buttons = confirmMessage.buttonLabels ?? [];
    if (buttons.length != 2) {
      buttons = ['confirm'.tr, 'cancel'.tr];
    }
    O2UI.showConfirm(context, confirmMessage.message!,
        title: confirmMessage.title,
        okText: buttons[0],
        cancelText: buttons[1], okPressed: () {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: "$callback(0)");
      }
    }, cancelPressed: () {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: "$callback(1)");
      }
    });
  }

  /// sheet 底部按钮选择器
  _actionSheet(JsMessage jsMessage) {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 actionSheet');
      return;
    }
    JsNotificationActionSheetMessage sheetMsg =
        JsNotificationActionSheetMessage.fromJson(jsMessage.data ?? {});
    String callback = jsMessage.callback ?? '';
    if (sheetMsg.otherButtons == null ||
        sheetMsg.otherButtons?.isEmpty == true) {
      Loading.showError('args_error'.tr);
      return;
    }
    final buttons = sheetMsg.otherButtons ?? [];
    final title = sheetMsg.title ?? '';
    bool tooManyButtons = sheetMsg.tooManyButtons ?? false;
    List<Widget> widgets = buttons.mapWithIndex((e, i) {
      return ListTile(
        onTap: () {
          Navigator.pop(context);
          if (callback.isNotEmpty) {
            webviewController?.evaluateJavascript(source: "$callback($i)");
          }
        },
        title: Align(
          alignment: Alignment.center,
          child: Text(e, style: Theme.of(context).textTheme.bodyMedium),
        ),
      );
    }).toList();
    if (widgets.length > 6 ) {
      tooManyButtons = true;
    }
    if (tooManyButtons) {
      O2UI.showBottomSheetLongList(context, widgets,
          title: title, cancelText: sheetMsg.cancelButton, cancelPressed: () {
        if (callback.isNotEmpty) {
          webviewController?.evaluateJavascript(source: "$callback(-1)");
        }
      });
    } else {
      O2UI.showBottomSheetWithCancel(context, widgets,
          title: title, cancelText: sheetMsg.cancelButton, cancelPressed: () {
        if (callback.isNotEmpty) {
          webviewController?.evaluateJavascript(source: "$callback(-1)");
        }
      });
    }
  }

  /// prompt 输入框
  _prompt(JsMessage jsMessage) async {
    JsNotificationConfirmMessage confirmMessage =
        JsNotificationConfirmMessage.fromJson(jsMessage.data ?? {});
    String callback = jsMessage.callback ?? '';
    var buttons = confirmMessage.buttonLabels ?? [];
    if (buttons.length != 2) {
      buttons = ['confirm'.tr, 'cancel'.tr];
    }
    String content = confirmMessage.message ?? '';
    String title = confirmMessage.title ?? 'alert'.tr;
    _inputController = TextEditingController(text: content);
    var result = await O2UI.showCustomDialog(
        my_get.Get.context,
        title,
        TextField(
          controller: _inputController,
          maxLines: 1,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.done,
        ),
        positiveBtnText: buttons[0],
        cancelBtnText: buttons[1]);
    if (result == O2DialogAction.positive) {
      var jsonBack =
          '{buttonIndex: 0, value: "${_inputController?.text ?? ''}"}';
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: "$callback('$jsonBack')");
      }
    } else if (result == O2DialogAction.cancel) {
      var jsonBack =
          '{buttonIndex: 1, value: "${_inputController?.text ?? ''}"}';
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: "$callback('$jsonBack')");
      }
    }
  }

  /// 震动
  _vibrate(JsMessage jsMessage) async {
    String callback = jsMessage.callback ?? '';
    HapticFeedback.mediumImpact();
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: "$callback()");
    }
  }

  /// toast  消息
  _toast(JsMessage jsMessage) async {
    String callback = jsMessage.callback ?? '';
    JsNotificationToastMessage toastMessage =
        JsNotificationToastMessage.fromJson(jsMessage.data ?? {});
    if (toastMessage.message != null &&
        toastMessage.message?.isNotEmpty == true) {
      Loading.toast(toastMessage.message!);
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: "$callback()");
    }
  }

  /// loading 层显示
  _showLoading(JsMessage jsMessage) async {
    String callback = jsMessage.callback ?? '';
    JsNotificationLoadingMessage loadingMessage =
        JsNotificationLoadingMessage.fromJson(jsMessage.data ?? {});
    Loading.show(text: loadingMessage.text);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: "$callback()");
    }
  }

  /// 关闭 loading 层
  _hideLoading(JsMessage jsMessage) async {
    String callback = jsMessage.callback ?? '';
    Loading.dismiss();
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: "$callback()");
    }
  }

  /// 日期选择器
  _datePicker(JsMessage jsMessage) async {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 _datePicker');
      return;
    }
    String callback = jsMessage.callback ?? '';
    JsUtilDatePickerMessage message =
        JsUtilDatePickerMessage.fromJson(jsMessage.data ?? {});
    DateTime? initDate;
    if (message.value != null && message.value?.isNotEmpty == true) {
      initDate = DateTime.tryParse(message.value!);
    }
    initDate ??= DateTime.now();
    final result = await showDatePicker(
        context: context,
        initialDate: initDate,
        firstDate: initDate.addYears(-100),
        lastDate: initDate.addYears(100));
    if (result != null) {
      final date = result.ymd();
      OLogger.d('选择日期 $date');
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'{"value": "$date"}\')');
      }
    }
  }

  /// 时间选择器
  _timePicker(JsMessage jsMessage) async {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 _timePicker');
      return;
    }
    String callback = jsMessage.callback ?? '';
    JsUtilTimePickerMessage message =
        JsUtilTimePickerMessage.fromJson(jsMessage.data ?? {});
    DateTime? initDate;
    if (message.value != null && message.value?.isNotEmpty == true) {
      initDate = DateTime.tryParse(message.value!);
    }
    initDate ??= DateTime.now();
    TimeOfDay initTime =
        TimeOfDay(hour: initDate.hour, minute: initDate.minute);
    final startTime =
        await showTimePicker(context: context, initialTime: initTime);
    if (startTime != null) {
      final startHour =
          startTime.hour > 9 ? '${startTime.hour}' : '0${startTime.hour}';
      final startMinute =
          startTime.minute > 9 ? '${startTime.minute}' : '0${startTime.minute}';
      final time = '$startHour:$startMinute';
      OLogger.d('选择时间 $time');
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'{"value": "$time"}\')');
      }
    }
  }

  /// 日期时间选择器
  _dateTimePicker(JsMessage jsMessage) async {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 _timePicker');
      return;
    }
    String callback = jsMessage.callback ?? '';
    JsUtilTimePickerMessage message =
        JsUtilTimePickerMessage.fromJson(jsMessage.data ?? {});
    DateTime? initDate;
    if (message.value != null && message.value?.isNotEmpty == true) {
      initDate = DateTime.tryParse(message.value!);
    }
    initDate ??= DateTime.now();
    TimeOfDay initTime =
        TimeOfDay(hour: initDate.hour, minute: initDate.minute);
    final result = await showDatePicker(
        context: context,
        initialDate: initDate,
        firstDate: initDate.addYears(-100),
        lastDate: initDate.addYears(100));
    if (result != null) {
      var date = result.ymd();
      OLogger.d('选择日期 $date');
      // ignore: use_build_context_synchronously
      if (!context.mounted) {
        return;
      }
      final startTime =
          await showTimePicker(context: context, initialTime: initTime);
      if (startTime != null) {
        final startHour =
            startTime.hour > 9 ? '${startTime.hour}' : '0${startTime.hour}';
        final startMinute = startTime.minute > 9
            ? '${startTime.minute}'
            : '0${startTime.minute}';
        date = '$date $startHour:$startMinute';
        OLogger.d('选择时间 $date');
      }
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'{"value": "$date"}\')');
      }
    }
  }

  /// 日期间隔选择器
  _chooseInterval(JsMessage jsMessage) async {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 _timePicker');
      return;
    }
    String callback = jsMessage.callback ?? '';
    JsUtilDateIntervalPickerMessage message =
        JsUtilDateIntervalPickerMessage.fromJson(jsMessage.data ?? {});
    DateTime? startDate;
    DateTime? endDate;
    if (message.startDate != null && message.startDate?.isNotEmpty == true) {
      startDate = DateTime.tryParse(message.startDate!);
    }
    startDate ??= DateTime.now();
    if (message.endDate != null && message.endDate?.isNotEmpty == true) {
      endDate = DateTime.tryParse(message.endDate!);
    }
    endDate ??= DateTime.now();
    final result = await showDatePicker(
        context: context,
        initialDate: startDate,
        firstDate: startDate.addYears(-100),
        lastDate: startDate.addYears(100));
    if (result != null) {
      final start = result.ymd();
      OLogger.d('选择开始日期 $start');
      // ignore: use_build_context_synchronously
      if (!context.mounted) {
        return;
      }
      final resultEnd = await showDatePicker(
          context: context,
          initialDate: endDate,
          firstDate: endDate.addYears(-100),
          lastDate: endDate.addYears(100));
      if (resultEnd != null) {
        final end = resultEnd.ymd();
        OLogger.d('选择结束日期 $end');
        if (callback.isNotEmpty) {
          webviewController?.evaluateJavascript(
              source:
                  '$callback(\'{ "startDate": "$start", "endDate": "$end" }\')');
        }
      }
    }
  }

  /// 屏幕旋转
  _rotate(JsMessage jsMessage) async {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 _rotate');
      return;
    }
    final callback = jsMessage.callback ?? '';
    if (MediaQuery.of(context).orientation == Orientation.landscape) {
      await SystemChrome.setPreferredOrientations(
          [DeviceOrientation.landscapeRight]);
    } else {
      await SystemChrome.setPreferredOrientations(
          [DeviceOrientation.portraitUp]);
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  ///  获取手机信息
  _getPhoneInfo(JsMessage jsMessage) async {
    final context = my_get.Get.context;
    if (context == null) {
      OLogger.e('没有 context, 无法打开 _getPhoneInfo');
      return;
    }
    final callback = jsMessage.callback ?? '';
    var brand = '';
    var model = '';
    var version = '';
    final width = MediaQuery.of(context).size.width;
    final height = MediaQuery.of(context).size.height;
    OLogger.d('屏幕  width $width height $height');
    final deviceInfoPlugin = DeviceInfoPlugin();
    if (Platform.isAndroid) {
      final android = await deviceInfoPlugin.androidInfo;
      brand = android.brand;
      model = android.model;
      version = '${android.version.baseOS ?? ''} ${android.version.sdkInt}';
    } else {
      final ios = await deviceInfoPlugin.iosInfo;
      brand = ios.utsname.machine;
      model = ios.model;
      version = '${ios.systemName} ${ios.systemVersion}';
    }
    if (callback.isNotEmpty) {
      final res = JsDevicePhoneInfoResponse(
          screenWidth: "$width",
          screenHeight: "$height",
          brand: brand,
          model: model,
          version: version,
          netInfo: '',
          operatorType: '');
      webviewController?.evaluateJavascript(
          source: '$callback(\'${json.encode(res.toJson())}\')');
    }
  }

  ///  扫二维码
  _scan(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    ScanPage.o2ScanBiz(callback: (result) {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'${result.o2SimpleString()}\')');
      }
    });
  }

  ///  定位
  _location(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final helper = GeolocatorHelper(
        isSingleLocation: true,
        callback: (position) {
          OLogger.d('定位返回结果 ${position.latitude} ${position.longitude}');
          final res = JsDeviceLocationResponse(
              latitude: '${position.latitude}',
              longitude: '${position.longitude}',
              address: '${position.address}');
          if (callback.isNotEmpty) {
            webviewController?.evaluateJavascript(
                source: '$callback(\'${json.encode(res.toJson())}\')');
          }
        });
    helper.startLocation();
    // final helper = BaiduLocationHelper(
    //     callback: (result) {
    // OLogger.d('定位返回结果 ${result.latitude} ${result.longitude}');
    // final res = JsDeviceLocationResponse(
    //     latitude: '${result.latitude}',
    //     longitude: '${result.longitude}',
    //     address: '${result.address}');
    // if (callback.isNotEmpty) {
    //   webviewController?.evaluateJavascript(
    //       source: '$callback(\'${json.encode(res.toJson())}\')');
    // }
    //     },
    //     isSingleLocation: true);
    // helper.initLocationAndStartRequest();
  }

  /// 手机生物识别认证
  _localAuth(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    if (callback.isNotEmpty) {
      final result = await O2Utils.bioAuth();
      final res = {"value": result};
      webviewController?.evaluateJavascript(
          source: '$callback(\'${json.encode(res)}\')');
    } else {
      OLogger.e('_localAuth， 没有回调函数！');
    }
  }

  /// 设置标题
  _navigationSetTitle(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsUtilNavigationMessage message =
        JsUtilNavigationMessage.fromJson(jsMessage.data ?? {});
    if (message.title?.isNotEmpty == true) {
      jsNavigationInterface?.setNavigationTitle(message.title!);
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: '$callback()');
      }
    } else {
      OLogger.e('传入的标题内容为空！');
    }
  }

  /// 关闭当前窗口
  _navigationClose(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    jsNavigationInterface?.closeWindow();
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 返回上一页
  _navigationGoBack(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    jsNavigationInterface?.goBack();
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 分享图片， 目前只支持 base64
  Future<void> _share(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final base64String = jsMessage.data?['base64'];
    // final subject = jsMessage.data?['subject'];
    // final text = jsMessage.data?['text'];
    if (base64String != null && base64String is String) {
      final filePath = await _base64ToImage(base64String);
      if (filePath != null && filePath.isNotEmpty) {
        _shareImage(filePath);
      }
    } else {
      OLogger.e('错误的参数传入！');
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// baes64 转图片后 分享
  Future<String?> _base64ToImage(String base64) async {
    try {
      final bytes = base64Decode(base64);
      //图片临时存储
      final timeString =
          'share_base64_image_${DateTime.now().millisecondsSinceEpoch}';
      var dir = await O2FilePathUtil.getTempFolderWithUrl(timeString);
      if (dir == null || dir.isEmpty) {
        OLogger.e('本地文件目录生成失败！ url: $timeString');
        Loading.showError('common_image_generate_fail'.tr);
        return null;
      }
      String filePath = '$dir/$timeString.png';
      File file = File(filePath);
      file.writeAsBytesSync(bytes);
      OLogger.i('保存图片完成，path：$filePath');
      return filePath;
    } catch (e) {
      OLogger.e('图片生成失败！', e);
      Loading.showError('common_image_generate_fail'.tr);
      return null;
    }
  }

  /// 分享图片
  Future<void> _shareImage(String filePath) async {
    final context = Get.context;
    if (context == null) {
      OLogger.e('context 为空！');
      return;
    }
    final box = context.findRenderObject() as RenderBox?;
    final result = await Share.shareXFiles([XFile(filePath)],
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
    if (result.status != ShareResultStatus.success) {
      OLogger.i('分享失败，${result.status}');
      return;
    }
    Loading.toast('common_share_success'.tr);
  }

  /// 打开内部原生应用
  _openInnerApp(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsUtilOpenInnerAppMessage message =
        JsUtilOpenInnerAppMessage.fromJson(jsMessage.data ?? {});
    final appKey = message.appKey;
    final appDisplayName = message.appDisplayName;
    final portalFlag = message.portalFlag;
    final portalTitle = message.portalTitle;
    final portalPage = message.portalPage;
    final parameters = message.parameters ?? {};
    if (appKey?.isNotEmpty == true) {
      // 门户处理
      if (appKey == 'portal') {
        if (portalFlag?.isEmpty == true) {
          Loading.showError('args_error'.tr);
          OLogger.e('门户没有传入参数 portalFlag');
          return;
        }
        final portalParameters = parameters['portalParameters'];
        PortalPage.open(portalFlag!,
            title: portalTitle ?? '',
            pageId: portalPage,
            portalParameters: portalParameters);
      } else if (appKey == 'startProcess') {
        //启动流程
        await _startProcess();
      } else if (appKey == 'speechAssistant') {
        // 语音助手
        SpeechAssistantChatPage.open();
      } else {
        String flutterPath = '';
        if (appKey == O2NativeAppEnum.task.key) {
          flutterPath = O2OARoutes.appTask;
        } else if (appKey == O2NativeAppEnum.taskcompleted.key) {
          flutterPath = O2OARoutes.appTaskcompleted;
        } else if (appKey == O2NativeAppEnum.read.key) {
          flutterPath = O2OARoutes.appRead;
        } else if (appKey == O2NativeAppEnum.readcompleted.key) {
          flutterPath = O2OARoutes.appReadcompleted;
        } else if (appKey == O2NativeAppEnum.meeting.key) {
          flutterPath = O2OARoutes.appMeeting;
        } else if (appKey == O2NativeAppEnum.bbs.key) {
          flutterPath = O2OARoutes.appBBS;
        } else if (appKey == O2NativeAppEnum.yunpan.key ||
            appKey == 'clouddisk') {
          flutterPath = FileAssembleService.to.isV3()
              ? O2OARoutes.appCloudDiskV3
              : O2OARoutes.appYunpan;
        } else if (appKey == O2NativeAppEnum.attendance.key) {
          flutterPath = O2OARoutes.appAttendance;
        } else if (appKey == O2NativeAppEnum.attendanceOld.key) {
          flutterPath = O2OARoutes.appAttendanceOld;
        } else if (appKey == O2NativeAppEnum.cms.key) {
          flutterPath = O2OARoutes.appCms;
        } else if (appKey == O2NativeAppEnum.calendar.key) {
          flutterPath = O2OARoutes.appCalendar;
        } else if (appKey == O2NativeAppEnum.mindMap.key) {
          flutterPath = O2OARoutes.appMindMap;
        }
        if (flutterPath.isNotEmpty) {
          if (O2OARoutes.appAttendance == flutterPath ||
              O2OARoutes.appAttendanceOld == flutterPath) {
            FastCheckInService.instance.stop(); // 进入考勤 先关闭极速打卡
          }
          if (appDisplayName?.trim().isNotEmpty == true) {
            if (flutterPath.contains('?')) {
              flutterPath += '&displayName=$appDisplayName';
            } else {
              flutterPath += '?displayName=$appDisplayName';
            }
          }
          my_get.Get.toNamed(flutterPath);
        } else {
          Loading.showError('args_error'.tr);
          OLogger.e('错误的 appkey $appKey');
        }
      }
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: '$callback()');
      }
    } else {
      OLogger.e('没传入 appKey ');
      Loading.showError('args_error'.tr);
    }
  }

  // 选择启动流程
  Future<void> _startProcess() async {
    var result = await ProcessPickerPage.startPicker(ProcessPickerMode.process);
    if (result != null && result is ProcessData) {
      CreateFormPage.startProcess(true, process: result);
    }
  }

  /// 打开外部应用
  _openOtherApp(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsUtilOtherAppMessage message =
        JsUtilOtherAppMessage.fromJson(jsMessage.data ?? {});
    if (message.schema?.isNotEmpty == true) {
      final uri = Uri.parse(message.schema!);
      bool can = await canLaunchUrl(uri);
      if (!can) {
        Loading.showError(
            'common_error_open_other_app'.trArgs([message.schema!]));
        return;
      }
      await launchUrl(uri, mode: LaunchMode.externalApplication);
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: '$callback()');
      }
    } else {
      OLogger.e('没传入 schema ');
    }
  }

  /// 打开新窗口
  _openWindow(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsUtilOpenWindowMessage message =
        JsUtilOpenWindowMessage.fromJson(jsMessage.data ?? {});
    if (message.url?.isNotEmpty == true) {
      InnerWebviewPage.open(message.url!);
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(source: '$callback()');
      }
    } else {
      OLogger.e('没有传入 url');
    }
  }

  /// 当前页面在手机默认浏览器打开
  _openCurrentPageInBrowser(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final uri = await webviewController?.getUrl();
    if (uri != null) {
      if (await canLaunchUrl(uri)) {
        final result = await launchUrl(
          uri,
          mode: LaunchMode.externalApplication,
          webViewConfiguration: WebViewConfiguration(headers: <String, String>{
            O2ApiManager.instance.tokenName:
                O2ApiManager.instance.o2User?.token ?? ''
          }),
        );
        if (!result) {
          OLogger.e('打开 url ${uri.toString()} 失败！');
        }
      } else {
        OLogger.e('uri 不正确，${uri.toString()}');
      }
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  ///  清除缓存并刷新页面
  _clearCache(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    //TODO 清除缓存
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 组织选择器
  _departmentPicker(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsBizPickerMessage message =
        JsBizPickerMessage.fromJson(jsMessage.data ?? {});
    final result = await ContactPickerPage.startPicker(
        [ContactPickMode.departmentPicker],
        topUnitList: message.topList,
        unitType: message.orgType,
        maxNumber: message.maxNumber,
        multiple: message.multiple,
        initDeptList: message.pickedDepartments);
    if (result is ContactPickerResult) {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'${json.encode(result.toJson())}\')');
      }
    }
  }

  /// 身份选择器
  _identityPicker(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsBizPickerMessage message =
        JsBizPickerMessage.fromJson(jsMessage.data ?? {});
    final result = await ContactPickerPage.startPicker(
        [ContactPickMode.identityPicker],
        topUnitList: message.topList,
        maxNumber: message.maxNumber,
        multiple: message.multiple,
        dutyList: message.duty,
        initIdList: message.pickedIdentities);
    if (result is ContactPickerResult) {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'${json.encode(result.toJson())}\')');
      }
    }
  }

  /// 人员选择器
  _personPicker(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsBizPickerMessage message =
        JsBizPickerMessage.fromJson(jsMessage.data ?? {});
    final result = await ContactPickerPage.startPicker(
        [ContactPickMode.personPicker],
        maxNumber: message.maxNumber,
        multiple: message.multiple,
        initUserList: message.pickedUsers);
    if (result is ContactPickerResult) {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'${json.encode(result.toJson())}\')');
      }
    }
  }

  /// 组合选择器
  _complexPicker(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsBizPickerMessage message =
        JsBizPickerMessage.fromJson(jsMessage.data ?? {});
    final pickModes = message.pickMode ?? [];
    if (pickModes.isEmpty) {
      Loading.showError('args_error'.tr);
      OLogger.e('pickMode 不能为空');
      return;
    }
    final result = await ContactPickerPage.startPicker(_pickModeList(pickModes),
        topUnitList: message.topList,
        maxNumber: message.maxNumber,
        multiple: message.multiple,
        unitType: message.orgType,
        dutyList: message.duty,
        initDeptList: message.pickedDepartments,
        initIdList: message.pickedIdentities,
        initGroupList: message.pickedGroups,
        initUserList: message.pickedUsers);
    if (result is ContactPickerResult) {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'${json.encode(result.toJson())}\')');
      }
    }
  }

  ///
  List<ContactPickMode> _pickModeList(List<String> pickModes) {
    return pickModes
        .map((e) {
          switch (e) {
            case 'departmentPicker':
              return ContactPickMode.departmentPicker;
            case 'identityPicker':
              return ContactPickMode.identityPicker;
            case 'groupPicker':
              return ContactPickMode.groupPicker;
            case 'personPicker':
              return ContactPickMode.personPicker;
            default:
              return null;
          }
        })
        .where((element) => element != null)
        .map((e) => e!)
        .toList();
  }

  /// 群组选择器
  _groupPicker(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    JsBizPickerMessage message =
        JsBizPickerMessage.fromJson(jsMessage.data ?? {});
    final result = await ContactPickerPage.startPicker(
        [ContactPickMode.groupPicker],
        maxNumber: message.maxNumber,
        multiple: message.multiple,
        initGroupList: message.pickedGroups);
    if (result is ContactPickerResult) {
      if (callback.isNotEmpty) {
        webviewController?.evaluateJavascript(
            source: '$callback(\'${json.encode(result.toJson())}\')');
      }
    }
  }

  /// 打开我的页面
  _settingOpenMyProfile(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    Get.toNamed(O2OARoutes.homeSettingsMyProfile);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  _settingOpenSafeAndAccount(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    Get.toNamed(O2OARoutes.homeSettingsAccountSafe);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  _settingOpenAppSkin(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    Get.toNamed(O2OARoutes.homeSettingsSkin);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  _settingOpenAppNotice(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    if (GetPlatform.isMobile) {
      AppSettings.openNotificationSettings();
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  _settingOpenAppCommon(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    Get.toNamed(O2OARoutes.homeSettingsCommon);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  _settingOpenAppAbout(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    Get.toNamed(O2OARoutes.homeSettingsAbout);
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  Future<void> _settingLogout(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    O2Utils.logout();
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 人员组织搜索页面
  Future<void> _searchPage(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    if (O2ContactPermissionManager.instance.isCurrentPersonCannotQueryAll() ||
        O2ContactPermissionManager.instance.isCurrentPersonCannotQueryOuter()) {
      OLogger.i('当前用户没有权限搜索通讯录');
      Loading.toast('contact_no_permission'.tr);
    } else {
      Get.toNamed(O2OARoutes.homeContactSearch);
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 人员详情页面
  _personInfoPage(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final personDn = jsMessage.data?['personDn'];
    if (personDn != null && personDn is String) {
      PersonPage.open(personDn);
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 根据组织dn打开 下级组织和人员页面
  Future<void> _orgInfoPage(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final orgDn = jsMessage.data?['orgDn'];
    final orgName = jsMessage.data?['orgName'];
    if (orgDn != null && orgDn is String) {
      OrgPersonListPage.open(
          top: O2Unit(
              distinguishedName: orgDn,
              name: (orgName != null && orgName is String) ? orgName : ''));
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 打开IM会话
  Future<void> _openImConversation(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final conversationId = jsMessage.data?['conversationId'];
    if (conversationId == null || conversationId is String) {
      ImChatPage.open((conversationId as String));
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 跟某人聊天
  Future<void> _openImChatWithSomeone(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    final person = jsMessage.data?['person'];
    if (person == null || person is String) {
      await _createConversation(
          O2.imConversationTypeSingle, [(person as String)]);
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 打开系统消息会话
  Future<void> _openImInstantChat(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    InstantChatPage.open();
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 选择人员创建单聊
  Future<void> _startSingleChat(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    var result =
        await ContactPickerPage.startPicker([ContactPickMode.personPicker]);
    if (result is ContactPickerResult) {
      if (result.users != null && result.users!.isNotEmpty) {
        if (result.users![0].distinguishedName! ==
            O2ApiManager.instance.o2User?.distinguishedName) {
          Loading.toast('im_msg_create_conversation_not_with_self'.tr);
          if (callback.isNotEmpty) {
            webviewController?.evaluateJavascript(source: '$callback()');
          }
          return;
        }
        await _createConversation(
            O2.imConversationTypeSingle, [result.users![0].distinguishedName!]);
      }
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  /// 选择人员创建群聊
  Future<void> _startGroupChat(JsMessage jsMessage) async {
    final callback = jsMessage.callback ?? '';
    var result = await ContactPickerPage.startPicker(
        [ContactPickMode.personPicker],
        multiple: true);
    if (result is ContactPickerResult) {
      List<String> personList = [];
      result.users?.forEach((element) {
        personList.add(element.distinguishedName!);
      });
      await _createConversation(O2.imConversationTypeGroup, personList);
    }
    if (callback.isNotEmpty) {
      webviewController?.evaluateJavascript(source: '$callback()');
    }
  }

  Future<void> _createConversation(String type, List<String> personList) async {
    if (type.isEmpty || personList.isEmpty) {
      return;
    }
    final conv = await MessageCommunicationService.to
        .createConversation(type, personList);
    if (conv != null && conv.id != null) {
      ImChatPage.open(conv.id!);
    }
  }
}
