import 'package:fis_common/env/env.dart';
import 'package:fis_common/js_plateform/js_platform.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_ui/index.dart';
import 'package:fis_ui/interface/interactive_container.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/global.dart';
import 'package:flyinsono/js_platform/handlers/license_data_handler.dart';
import 'package:flyinsono/js_platform/handlers/reset_token_handlers.dart';
import 'package:flyinsono/js_platform/handlers/second_window_state_handler.dart';
import 'package:flyinsono/js_platform/handlers/selected_filePath_handler.dart';
import 'package:flyinsono/js_platform/handlers/update_camera_preview.dart';
import 'package:get/get.dart';

import 'handlers/audio_to_text_handler.dart';
import 'handlers/base.dart';
import 'handlers/carotid_handlers.dart';
import 'handlers/close_live_consultation.dart';
import 'handlers/close_live_page_confirm.dart';
import 'handlers/exit_desktop_sharing_handler.dart';
import 'handlers/install_printer_driver_change_handler.dart';
import 'handlers/reload_settings.dart';
import 'handlers/language_change_handlers.dart';
import 'handlers/open_device_live_handler.dart';
import 'handlers/open_live_consultation.dart';
import 'handlers/open_live_course.dart';
import 'handlers/open_second_window_loading.dart';
import 'handlers/print_driver_state_change.dart';
import 'handlers/pull_url_notification_handler.dart';
import 'handlers/remedical_handlers.dart';
import 'handlers/report_handlers.dart';
import 'handlers/measure_handlers.dart';
import 'handlers/save_recording_notification.dart';
import 'handlers/single_frame_received_handler.dart';
import 'handlers/slave_window_statue_change_handler.dart';
import 'handlers/submit_reportHandler.dart';
import 'handlers/system_handlers.dart';
import 'handlers/thesaurus_change_handler.dart';
import 'handlers/update_local_USSettingUrl_handler.dart';
import 'methods.dart';

class JsPlatformListener {
  final Map<TargetMethodName, MethodHandlerBase> _handlers = {};
  final _needConfirmPages = [
    RouteNames.Remedical.ReportEdit,
  ];
  final _targetRouterPages = [
    TargetMethodName.OpenMeasurePage,
    TargetMethodName.OpenReportDesignerPage,
    TargetMethodName.OpenReportEditPage,
    TargetMethodName.OpenReportPreviewPage,
    TargetMethodName.OpenDeviceLivePage,
    TargetMethodName.OpenLiveCoursePage,
  ];
  bool _waitToConfirm = false;

  JsPlatformListener() {
    _init();
  }

  void run() {
    JSPlateForm.setJsPlatForm(_handleMessage);
  }

  void _init() {
    //System
    _register(LogoutHandler());
    _register(WindowStateChangeHandler());

    //Report
    _register(SaveReportTemplateHandler());
    _register(RefershReportsHandler());
    _register(OpenReportEditPageHandler());
    _register(OpenReportPreviewPageHandler());
    _register(OpenReportDesignerPageHandler());

    //Remedical
    _register(UpdateExportProgessHandler());

    //Measure
    _register(OpenMeasurePageHandler());
    _register(OpenLiveConsultationHandler());
    _register(OpenLiveCourseHandler());
    _register(VidChunkReceiveHandler());
    //Measure - Carotid 3d
    _register(MdlFileLoadedHandler());
    _register(AdjustPlaneImageHandler());
    _register(ThesaurusChangeHandler());
    _register(OnSubmitReportHandler());
    _register(SlaveWindowStatusChangeHandler());
    _register(OnRouterToDefaultPageReportHandler());
    _register(OnReloadConfigHandler());
    _register(OnChangeLanguageHandler());
    _register(OnHotKeyDownHandler());
    _register(ResetTokenHandler());
    _register(AudioToTextHandler());
    _register(CloseLivePageConfirmHandler());
    _register(SaveRecordingNotificationHandler());
    _register(CheckPrintDriverStateChangeHandler());
    _register(PullUrlNotificationHandler());
    _register(SingleFrameReceivedHandler());
    _register(ScreenshotHandler());
    _register(RecordHandler());
    _register(ExitDesktopSharing());
    _register(SelectedFilePathHandler());
    _register(UpdateCameraPreview());
    _register(UpdateLocalUSSettingUrlHandler());
    _register(InstallPrinterDriverChangeHandler());
    _register(CloseLiveConsultationHandler());

    // Live
    _register(OpenDeviceLiveHandler());
    // 硬件设置同步
    _register(ReloadSettingsHandler());
    // 第二窗口开启状态
    _register(SecondWindowStatusHandler());
    _register(OpenSecondWindowLoading());
    _register(LicenseDataHandler());
  }

  void _handleMessage(String method, String arguments) {
    try {
      final enumIdx = int.parse(method);
      final enumVal = TargetMethodName.values[enumIdx];

      if (!_handlers.containsKey(enumVal)) return;

      final curRouterAddress = router.currentName!.split("?").first;
      final args = arguments.split('&');
      bool isNeedShowConfirmAlert =
          _needConfirmPages.contains(curRouterAddress) &&
              _targetRouterPages.contains(enumVal);
      if (isNeedShowConfirmAlert) {
        //_waitToConfirm是用来去重多次弹窗的
        if (_waitToConfirm) {
          router.back();
        }
        _waitToConfirm = true;
        var container = JsListener();
        FConfirmAlert.show(
          context: Get.context!,
          title: i18nBook.common.tip.t,
          subTitle: i18nBook.common.leaveCurrentPage.t,
          businessParent: container,
          confrimLabel: i18nBook.common.confirm.t,
          cancelLabel: i18nBook.common.cancel.t,
          onConfirm: () {
            _handlers[enumVal]!.execute(args);
            _waitToConfirm = false;
          },
          onCancel: () {
            router.back();
            _waitToConfirm = false;
          },
        );
      } else {
        _handlers[enumVal]!.execute(args);
      }
    } catch (e) {
      logger.e(
        "[PlatformListener] handle message error: method-$method not found.",
        e,
      );
    }
  }

  void _register<T extends MethodHandlerBase>(T handler) {
    _handlers[handler.methodName] = handler;
  }
}

class JsListener extends FStatelessWidget implements FInteractiveContainer {
  @override
  FWidget build(BuildContext context) {
    return FSizedBox();
  }

  @override
  String get pageName => 'JsListener';
}

class OnHotKeyDownHandler extends MethodHandlerBase {
  OnHotKeyDownHandler() : super(TargetMethodName.OnHotKeyDown);

  @override
  void execute(List<String> args) {
    if (FPlatform.isWindows) {
      Store.app.isOpenDebugBox = true;
    }
  }
}

class OnReloadConfigHandler extends MethodHandlerBase {
  OnReloadConfigHandler() : super(TargetMethodName.ReloadConfig);

  @override
  void execute(List<String> args) {
    Global.reloadConfigService();
  }
}

class OnRouterToDefaultPageReportHandler extends MethodHandlerBase {
  OnRouterToDefaultPageReportHandler()
      : super(TargetMethodName.RouterToDefaultPage);

  @override
  Future<void> execute(List<String> args) async {
    print('router to SecondSplash');
    router.offAll(RouteNames.App.SecondSplash);
    print('router to SecondSplash end');
  }
}
