import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/mobile/names.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/pages/main/home/widgets/dialog_page.dart';
import 'package:flyinsono/pages/schedule/calendar/calendar_page/detail_dialog/schedule_detail_dialog.dart';
import 'package:flyinsono/pages/schedule/schedule_notification/schedule_notification_binding.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/desktop/notification_list/widgets/notification_list_container.dart';
import 'package:get/get.dart';

import 'state.dart';

class NotificationListController extends FControllerBase {
  NotificationListController();
  NotificationListState state = NotificationListState();

  /// 消息来时触发更新
  void onMessageReceive() {
    _updateUnreadCount();
  }

  /// 在别处打开进行详情的查看
  void onOpenDetailByNotification(String relevanceCode) {
    // 使用 relevanceCode 查询所有相关的消息，全部设置为已读
    _queryUnreadMessages(pageIndex: 1, pageSize: 50, keyword: relevanceCode)
        .then((List<MessageExtendInfoDTO> value) async {
      if (value.length > 0) {
        List<String> _noReadedIds = value
            .where((MessageExtendInfoDTO element) => element.isReaded == false)
            .map((e) => e.messageCode ?? '')
            .toList();
        if (_noReadedIds.length > 0) {
          bool success = await rpc.user.batchSetMessageStatusAsync(
            SetMessageInfoReqeust(
              token: Store.user.token,
              messageCodes: _noReadedIds,
            ),
          );
          if (success) {
            await Future.delayed(Duration(seconds: 1));
            _refreshNotificationList();
            _updateUnreadCount();
          }
        }
      }
    });
  }

  /// 未读消息数
  int _unreadCount = 0;

  /// 消息总数
  int _totalNotificationCount = 0;

  /// 当前页码
  // int _currentPage = 1;

  /// 每页消息数
  static int _pageSize = 10;

  /// 未读消息列表
  List<String>? _noReadCodes;

  /// 最大页码
  int get maxPage => (_totalNotificationCount / _pageSize).ceil();

  /// 是否展开消息列表
  bool _isExpandList = false;

  int get unreadCount => _unreadCount;

  final ScrollController notificationListScrollController =
      new ScrollController();

  /// 弹出盒实体
  OverlayEntry? _entry;

  _initData() async {
    _unreadCount = await _queryUnreadCount();
    update(["notification_list_button"]);
  }

  /// 调接口获取未读消息数，更新组件
  Future<void> _updateUnreadCount() async {
    _unreadCount = await _queryUnreadCount();
    update(["notification_list_button"]);
  }

  void openNotificationList(BuildContext context) {
    if (_isExpandList) {
      closeNotificationList();
      return;
    }
    _updateUnreadCount();
    _queryUnreadMessages(pageIndex: 1, pageSize: 10).then((value) {
      state.notificationList = value;
    });
    Get.put<OverlayViewController>(OverlayViewController());
    _createNewEntry(context);
    _isExpandList = true;
  }

  /// 加载更多消息
  void loadMoreNotification() {
    if (state.notificationList.length < _totalNotificationCount) {
      /// 计算页面下标
      int _currentPage = (state.notificationList.length / _pageSize).ceil() + 1;
      _queryUnreadMessages(pageIndex: _currentPage, pageSize: _pageSize)
          .then((value) {
        state.notificationList.addAll(value);
        update(["notification_list"]);
      });
    }
  }

  /// 刷新消息列表
  void _refreshNotificationList() {
    _queryUnreadMessages(pageIndex: 1, pageSize: 10).then((value) {
      state.notificationList = value;
      update(["notification_list"]);
    });
  }

  void closeNotificationList() {
    Get.delete<OverlayViewController>();
    if (_entry != null) {
      _entry?.remove();
      _entry = null;
    }
    _isExpandList = false;
  }

  /// 查询未读消息数 [此方法还能获取到未读消息的 code]
  Future<int> _queryUnreadCount() async {
    try {
      NoReadMessagesDTO result = await rpc.user.getNoReadMessagesAsync(
        GetNoReadMessagesRequest(
          token: Store.user.token,
          transactionType: TransactionTypeEnum.Consultion,
        ),
      );
      _noReadCodes = result.noReadCodes;
      return result.count;
    } catch (e) {
      return 0;
    }
  }

  Future<List<MessageExtendInfoDTO>> _queryUnreadMessages(
      {int pageIndex = 1, int pageSize = 10, String? keyword}) async {
    try {
      PageResult<MessageExtendInfoDTO> result =
          await rpc.user.getMessagesPageAsync(
        QueryMessageListRequest(
          token: Store.user.token,
          transactionType: TransactionTypeEnum.Consultion,
          pageIndex: pageIndex,
          pageSize: pageSize,
          keyword: keyword,
        ),
      );
      if (keyword == null) {
        _totalNotificationCount = result.totalCount;
      }
      if (result.pageData == null) return [];
      return result.pageData!;
    } catch (e) {
      return [];
    }
  }

  /// 初始化消息总数
  void _initTotalNotificationCount() async {
    try {
      PageResult<MessageExtendInfoDTO> result =
          await rpc.user.getMessagesPageAsync(
        QueryMessageListRequest(
          token: Store.user.token,
          transactionType: TransactionTypeEnum.Consultion,
          pageIndex: 1,
          pageSize: 1,
        ),
      );
      _totalNotificationCount = result.totalCount;
    } catch (e) {
      print(e);
    }
  }

  @override
  void onInit() {
    notificationListScrollController.addListener(() {
      if (notificationListScrollController.position.pixels ==
          notificationListScrollController.position.maxScrollExtent) {
        loadMoreNotification();
      }
    });
    _initTotalNotificationCount();
    super.onInit();
  }

  @override
  void onReady() {
    super.onReady();
    _initData();
  }

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

  /// 在上下文创建弹出盒
  void _createNewEntry(BuildContext context) {
    final OverlayState overlayState = Overlay.of(
      context,
    );

    final RenderBox target = context.findRenderObject()! as RenderBox;
    final RenderBox targetConatiner =
        overlayState.context.findRenderObject() as RenderBox;
    final Size containerSize = targetConatiner.size;
    final Offset targetOffset = target.localToGlobal(
      target.size.center(Offset.zero),
      ancestor: overlayState.context.findRenderObject(),
    );
    final Offset rightTopOffset =
        Offset(0, targetOffset.dy + target.size.height / 2);
    print("rightTopOffset: $rightTopOffset");
    final Widget overlay =
        _buildOverlay(rightTopOffset, context, containerSize.height * 0.8);
    _entry = OverlayEntry(builder: (BuildContext context) => overlay);
    overlayState.insert(_entry!);
  }

  /// 打开通知详情
  void _openNotificationDetail(MessageExtendInfoDTO message) async {
    await _setReaded(message);
    closeNotificationList();
    if (kIsMobile) {
      _openMobileConsultationDetail(message.relevanceCode!);
    } else {
      router.dialog(
        () => ScheduleDetailDialog(),
        transitionDuration: Duration(milliseconds: 500),
        transitionCurve: Curves.easeInOut,
        binding: ScheduleNotificationBinding(
            consultationCode: message.relevanceCode!),
      );
    }
  }

  /// 移动端点击通知进入详情页
  void _openMobileConsultationDetail(String consultationCode) async {
    try {
      await router.to(MobileRouteNames.RealTimeRemedical.ConsultationDetail,
          parameters: {
            'consultationCode': consultationCode,
          });
    } catch (e) {
      logger.e("openEditInit exception:", e);
      printError(info: e.toString());
    }
  }

  /// 设置为已读
  Future<void> _setReaded(MessageExtendInfoDTO message) async {
    try {
      bool success = await rpc.user.batchSetMessageStatusAsync(
        SetMessageInfoReqeust(
          token: Store.user.token,
          messageCodes: [message.messageCode!],
        ),
      );
      if (success) {
        await Future.delayed(Duration(seconds: 1));
        _updateUnreadCount();
      }
    } catch (e) {
      print(e);
    }
  }

  /// 全部标记为已读
  void setAllReaded() async {
    try {
      if (_noReadCodes == null || _noReadCodes!.isEmpty) {
        return;
      }
      bool success = await rpc.user.batchSetMessageStatusAsync(
        SetMessageInfoReqeust(
          token: Store.user.token,
          messageCodes: _noReadCodes,
        ),
      );
      if (success) {
        await Future.delayed(Duration(seconds: 1));
        PromptBox.toast(i18nBook.notification.allMarkedAsRead.t);
        _refreshNotificationList();
        _updateUnreadCount();
      }
    } catch (e) {
      print(e);
    }
  }

  /// 创建 Overlay 组件
  Widget _buildOverlay(Offset offset, BuildContext context, double height) {
    return FInkWell(
      onTap: () {
        closeNotificationList();
      },
      child: MouseRegion(
        cursor: SystemMouseCursors.basic,
        child: Container(
          child: Directionality(
            textDirection: Directionality.of(context),
            child: Stack(
              children: [
                Positioned(
                  top: offset.dy,
                  right: offset.dx,
                  child: FInkWell(
                    onTap: () {}, // 点击消息列表不关闭消息列表
                    child: MouseRegion(
                      cursor: SystemMouseCursors.basic,
                      child: Container(
                        width: 360,
                        height: height,
                        child: NotificationListConatiner(
                          onOpenNotification: _openNotificationDetail,
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
