// ignore_for_file: non_constant_identifier_names
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/services/notification.m.dart';
import 'package:fis_lib_report/converts/event_type.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/notifications/handlers/schedule/Invitee_reject_apply_handler.dart';
import 'package:flyinsono/notifications/handlers/schedule/applay_handler.dart';
import 'package:flyinsono/notifications/handlers/schedule/approval_apply_handler.dart';
import 'package:flyinsono/notifications/handlers/schedule/invitee_approve_apply_handler.dart';
import 'package:flyinsono/notifications/handlers/schedule/invitee_approve_handler.dart';
import 'package:flyinsono/notifications/handlers/schedule/reject_apply_handler.dart';
import 'package:flyinsono/notifications/handlers/schedule/remind_handler.dart';
import 'package:flyinsono/pages/schedule/calendar/calendar_page/detail_dialog/schedule_detail_dialog.dart';
import 'package:flyinsono/pages/schedule/calendar/utils/calendar_utils.dart';
import 'package:flyinsono/pages/schedule/schedule_notification/schedule_notification_binding.dart';
import 'package:flyinsono/views/desktop/notification_list/controller.dart';
import 'package:get/get.dart';

class ScheduleNotificationController extends GetxController {
  ScheduleNotificationController();

  FEventHandler<ApplicationNotification> onReceiveNotification =
      FEventHandler<ApplicationNotification>();

  void handleReceiveNotification(ApplicationNotification notification) {
    try {
      NotificationListController controller =
          Get.find<NotificationListController>();
      controller.onMessageReceive();
    } on Exception catch (e) {
      print(e);
    }
    onReceiveNotification.emit(this, notification);
  }

  void handleOpenDetailByNotification(String relevanceCode) {
    try {
      NotificationListController controller =
          Get.find<NotificationListController>();
      controller.onOpenDetailByNotification(relevanceCode);
    } on Exception catch (e) {
      print(e);
    }
  }

  /// 消息类型表
  /// RejectApplayNotificationHandler 📅| 6 | 拒绝会诊申请的通知
  /// ConsultationRemindNotificationHandler 📅| 9 | 会诊开始前提醒的通知
  /// ApplyConsultationHandler 📅| 22 | 会诊申请通知
  /// ApprovalApplyConsultationHandler 📅| 23 | 批准申请会诊通知
  /// InviteeConsultationNotificationHandler 📅| 24 | 会诊受邀请人通知
  /// InviteeApproveApplyConsultationNotificationHandler 📅| 25 | 会诊受邀请参与人同意通知
  /// InviteeRejectNotificationHandler 📅| 26 | 会诊受邀请参与人拒绝通知

  late RejectApplayNotificationHandler RANHandler;
  late ConsultationRemindNotificationHandler CRNHandler;
  late ApplyConsultationHandler ACHandler;
  late ApprovalApplyConsultationHandler AAHandler;
  late InviteeConsultationNotificationHandler ICNHandler;
  late InviteeApproveApplyConsultationNotificationHandler IAAHandler;
  late InviteeRejectNotificationHandler IRNHandler;

  @override
  void onInit() {
    super.onInit();
    RANHandler = Get.find<RejectApplayNotificationHandler>();
    RANHandler.subscribe(_onRejectApplay);
    CRNHandler = Get.find<ConsultationRemindNotificationHandler>();
    CRNHandler.subscribe(_onConsultationRemind);
    ACHandler = Get.find<ApplyConsultationHandler>();
    ACHandler.subscribe(_onApplyConsultation);
    AAHandler = Get.find<ApprovalApplyConsultationHandler>();
    AAHandler.subscribe(_onApprovalApplyConsultation);
    ICNHandler = Get.find<InviteeConsultationNotificationHandler>();
    ICNHandler.subscribe(_onInviteeConsultation);
    IAAHandler = Get.find<InviteeApproveApplyConsultationNotificationHandler>();
    IAAHandler.subscribe(_onInviteeApproveApplyConsultation);
    IRNHandler = Get.find<InviteeRejectNotificationHandler>();
    IRNHandler.subscribe(_onInviteeReject);
  }

  /// 拒绝会诊申请通知
  void _onRejectApplay(RejectApplyConsultationNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",
      title: i18nBook.notification.sysNotification.t,

      ///FIXME: operatorName 应为不可空(与后端沟通)
      infoTitle: i18nBook.notification.someoneRejectYourConsultation
          .translate(["${message.operatorName ?? ""}"]),
      infoItems: [
        if (message.rejectReason != null)
          NotificationInfoItem(
            title: i18nBook.notification.rejectReason.t,
            content: message.rejectReason!,
          ),
      ],
      callback: () {
        handleOpenDetailByNotification(message.consultationCode ?? "");
        router.dialog(
          () => ScheduleDetailDialog(),
          transitionDuration: Duration(milliseconds: 500),
          transitionCurve: Curves.easeInOut,
          binding: ScheduleNotificationBinding(
              consultationCode: message.consultationCode ?? ""),
        );
      },
      callbackButtonText: i18nBook.notification.detail.t,
      type: NotificationType.error,
    );
    handleReceiveNotification(notification);
  }

  /// 会诊提醒通知
  void _onConsultationRemind(ConsultationRemindNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",
      title: i18nBook.notification.sysNotification.t,
      infoTitle:
          i18nBook.notification.consultationWillStartIn.translate(["###"]),
      countdownMinutes: message.countdownTime,
      countdownFinishTime: message.consultationTime!.toLocal(),
      countdownFinishText: i18nBook.notification.consultationStarted.t,
      infoItems: [
        if (message.patientName != null)
          NotificationInfoItem(
            title: i18nBook.common.fullName.t,
            content: message.patientName!,
          ),
        if (message.consultationTime != null &&
            message.consultationTimeEnd != null)
          NotificationInfoItem(
            title: i18nBook.notification.consultationTime.t,
            content: CalendarUtils.formatDateRange(
                message.consultationTime!.toLocal(),
                message.consultationTimeEnd!.toLocal()),
          ),
        if (message.expertName != null)
          NotificationInfoItem(
            title: i18nBook.notification.expertName.t,
            content: message.expertName!,
          ),
      ],
      type: NotificationType.countdown,
    );
    handleReceiveNotification(notification);
  }

  /// 会诊申请通知
  void _onApplyConsultation(ApplyConsultationNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",
      title: i18nBook.notification.sysNotification.t,
      infoTitle: i18nBook.notification.receiveConsultationApply
          .translate(["${message.operatorName ?? ""}"]),
      infoItems: [
        if (message.patientName != null)
          NotificationInfoItem(
            title: i18nBook.common.fullName.t,
            content: message.patientName!,
          ),
        if (message.consultationTime != null)
          NotificationInfoItem(
            title: i18nBook.notification.consultationTime.t,
            content:
                CalendarUtils.formatDate(message.consultationTime!.toLocal()),
          ),
        if (message.applyOrganizationName != null)
          NotificationInfoItem(
            title: i18nBook.notification.applyHospital.t,
            content: message.applyOrganizationName!,
          ),
      ],
      type: NotificationType.notification,
      callback: () {
        handleOpenDetailByNotification(message.consultationCode ?? "");
        router.dialog(
          () => ScheduleDetailDialog(),
          transitionDuration: Duration(milliseconds: 500),
          transitionCurve: Curves.easeInOut,
          binding: ScheduleNotificationBinding(
              consultationCode: message.consultationCode ?? ""),
        );
      },
      callbackButtonText: i18nBook.notification.detail.t,
    );
    handleReceiveNotification(notification);
  }

  /// 批准申请会诊通知
  void _onApprovalApplyConsultation(
      ApprovalApplyConsultationNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",
      title: i18nBook.notification.sysNotification.t,

      ///FIXME: operatorName 应为不可空(与后端沟通)
      infoTitle: i18nBook.notification.someoneAcceptYourConsultation
          .translate(["${message.operatorName ?? ""}"]),
      infoItems: [
        if (message.patientName != null)
          NotificationInfoItem(
            title: i18nBook.common.fullName.t,
            content: message.patientName!,
          ),
        if (message.consultationTime != null &&
            message.consultationTimeEnd != null)
          NotificationInfoItem(
            title: i18nBook.notification.consultationTime.t,
            content: CalendarUtils.formatDateRange(
                message.consultationTime!.toLocal(),
                message.consultationTimeEnd!.toLocal()),
          ),
        if (message.expertName != null)
          NotificationInfoItem(
            title: i18nBook.notification.expertName.t,
            content: message.expertName!,
          ),
      ],
      type: NotificationType.success,
    );
    handleReceiveNotification(notification);
  }

  /// 会诊受邀请人通知
  void _onInviteeConsultation(InviteeConsultationNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",

      title: i18nBook.notification.sysNotification.t,

      ///FIXME: operatorName 应为不可空(与后端沟通)
      infoTitle: i18nBook.notification.receiveConsultationInvitation
          .translate(["${message.operatorName ?? ''}"]),
      infoItems: [
        if (message.patientName != null)
          NotificationInfoItem(
            title: i18nBook.common.fullName.t,
            content: message.patientName!,
          ),
        if (message.consultationTime != null &&
            message.consultationTimeEnd != null)
          NotificationInfoItem(
            title: i18nBook.notification.consultationTime.t,
            content: CalendarUtils.formatDateRange(
                message.consultationTime!.toLocal(),
                message.consultationTimeEnd!.toLocal()),
          ),
      ],
      type: NotificationType.notification,
      callback: () {
        handleOpenDetailByNotification(message.consultationCode ?? "");
        router.dialog(
          () => ScheduleDetailDialog(),
          transitionDuration: Duration(milliseconds: 500),
          transitionCurve: Curves.easeInOut,
          binding: ScheduleNotificationBinding(
              consultationCode: message.consultationCode ?? ""),
        );
      },
      callbackButtonText: i18nBook.notification.detail.t,
    );
    handleReceiveNotification(notification);
  }

  /// 会诊受邀请参与人同意通知
  void _onInviteeApproveApplyConsultation(
      InviteeApproveApplyConsultationNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",

      title: i18nBook.notification.sysNotification.t,

      ///FIXME: operatorName 应为不可空(与后端沟通)
      infoTitle: i18nBook.notification.someoneAcceptYourInvitation
          .translate(["${message.operatorName ?? ''}"]),
      infoItems: [
        if (message.patientName != null)
          NotificationInfoItem(
            title: i18nBook.common.fullName.t,
            content: message.patientName!,
          ),
        if (message.consultationTime != null &&
            message.consultationTimeEnd != null)
          NotificationInfoItem(
            title: i18nBook.notification.consultationTime.t,
            content: CalendarUtils.formatDateRange(
                message.consultationTime!.toLocal(),
                message.consultationTimeEnd!.toLocal()),
          ),
      ],
      type: NotificationType.success,
    );
    handleReceiveNotification(notification);
  }

  void _onInviteeReject(InviteeRejectApplyConsultationNotification message) {
    final notification = ApplicationNotification(
      code: message.consultationCode ?? "",

      title: i18nBook.notification.sysNotification.t,

      ///FIXME: operatorName 应为不可空(与后端沟通)
      infoTitle: i18nBook.notification.someoneRejectYourInvitation
          .translate(["${message.operatorName ?? ''}"]),
      infoItems: [
        if (message.patientName != null)
          NotificationInfoItem(
            title: i18nBook.common.fullName.t,
            content: message.patientName!,
          ),
        if (message.consultationTime != null &&
            message.consultationTimeEnd != null)
          NotificationInfoItem(
            title: i18nBook.notification.consultationTime.t,
            content: CalendarUtils.formatDateRange(
                message.consultationTime!.toLocal(),
                message.consultationTimeEnd!.toLocal()),
          ),
        if (message.rejectReason != null)
          NotificationInfoItem(
            title: i18nBook.notification.rejectReason.t,
            content: message.rejectReason!,
          ),
      ],
      type: NotificationType.error,
    );
    handleReceiveNotification(notification);
  }

  @override
  void onClose() {
    super.onClose();
  }

  void sendMockNotification() {
    final notification = ApplicationNotification(
      code: "",
      title: i18nBook.notification.sysNotification.t,
      infoTitle:
          i18nBook.notification.receiveConsultationInvitation.translate([""]),
      infoItems: [
        NotificationInfoItem(
          title: i18nBook.common.fullName.t,
          content: '',
        ),
        NotificationInfoItem(
          title: i18nBook.notification.consultationTime.t,
          content: '2021-01-01 12:00 ~ 13:00',
        ),
      ],
      type: NotificationType.notification,
    );
    handleReceiveNotification(notification);
  }
}

///  应用内通知
class ApplicationNotification {
  ApplicationNotification({
    required this.title,
    required this.infoTitle,
    required this.infoItems,
    required this.type,
    required this.code,
    this.countdownMinutes,
    this.countdownFinishText,
    this.countdownFinishTime,
    this.callback,
    this.callbackButtonText,
  });

  final String title;
  final String infoTitle;
  final List<NotificationInfoItem> infoItems;
  final NotificationType type;
  final String code;
  final int? countdownMinutes;
  final String? countdownFinishText;
  final DateTime? countdownFinishTime;
  final Function? callback;
  final String? callbackButtonText;
}

/// 通知信息字段
class NotificationInfoItem {
  NotificationInfoItem({
    required this.title,
    required this.content,
  });

  final String title;
  final String content;
}

/// 通知类型
enum NotificationType {
  /// 通知
  notification,

  /// 警告
  warning,

  /// 错误
  error,

  /// 成功
  success,

  /// 倒计时
  countdown,
}
