import 'dart:async';
import 'package:fis_i18n/i18n.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/interfaces/entities/image_report_list_params.dart';
import 'package:flyinsono/managers/interfaces/group.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:flyinsono/managers/interfaces/remedical.dart';
import 'package:flyinsono/managers/interfaces/report.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/exam_images_list_view.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/report/reports_mobile_new.dart';
import 'package:flyinsono/pages/remedical/image_report_inner_view/controller.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'index.dart';
import 'package:fis_common/logger/logger.dart';

class GroupChatController extends GetxController {
  GroupChatController({this.initArgs});
  final groupManager = Get.find<IGroupManager>();
  final reportManager = Get.find<IReportManager>();
  final remedicalManager = Get.find<IRemedicalManager>();

  /// 初始化页面入参
  final ChatPageArgs? initArgs;

  final state = GroupChatState();

  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

  /// 消息列表滚动控制器
  final ScrollController messageViewScrollController = ScrollController();

  final FocusNode focusNode = FocusNode();
  bool get noMoreData => (_currentPage) * _pageSize >= _totalMessageNum;

  /// loading 效果 Timer
  Timer _animationTimer = Timer(Duration(seconds: 1), () {});

  /// 数据载入中
  bool _kisLoading = false;

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

  /// 每页条数
  int _pageSize = 8;

  /// 总数据条数
  int _totalMessageNum = 8;

  int cacheIndex = 0;

  bool canCreateReport = false;

  /// 当前群聊code
  String _userGroupCode = "";
  String get userGroupCode => _userGroupCode;

  /// DevicesCodes
  List<String> _deviceCodes = [];

  /// 群成员列表(前八个)
  List<UserExtendDTO> eightMembers = [];

  /// 群设备列表(前八个)
  List<DeviceInfoDTO> eightDevices = [];

  ///选中的检查记录Code
  String recordCode = '';

  ///选中的检查病人Code
  String patientCode = '';

  /// 打开侧面抽屉
  void openDrawer() {
    if (scaffoldKey.currentState == null) return;
    scaffoldKey.currentState!.openEndDrawer();
  }

  /// 关闭侧面抽屉
  void closeDrawer() {
    if (scaffoldKey.currentState == null) return;
    scaffoldKey.currentState!.openEndDrawer();
  }

  /// 消息列表滚到底部
  void _messageListViewScrollToBottom() {
    messageViewScrollController.animateTo(
      0,
      duration: Duration(milliseconds: 300),
      curve: Curves.easeOut,
    );
  }

  /// 移动端打开图像页面
  Future<void> openImagePageOnMobile(SimpleRecordInfoDTO recordInfo) async {
    final remedicalManager = Get.find<IRemedicalManager>();

    final String recordCode = recordInfo.recordCode ?? "";
    print('openImagePageOnMobile set recordCode:$recordCode');
    logger.i('openImageAndReportsDrawer set recordCode:$recordCode');
    if (recordCode.isEmpty) {
      PromptBox.toast("error: recordCode is empty");
      return;
    }
    List<RemedicalMeasuredInfoDTO> measureImages =
        await remedicalManager.findRemedicalMeasuredInfoAsync(recordCode);
    List<RemedicalAISelectedInfoDTO> aiImages = await remedicalManager
        .findAIImages(recordCode, recordInfo.patientCode ?? "");
    RemedicalListResult cloudImageInfo =
        await reportManager.getRemedicalListByRecordInfoAsync(recordCode);
    await Get.to(
      () => ExamImagesListView(
        cloudImageInfos: [cloudImageInfo],
        measureImages: measureImages,
        aiImages: aiImages,
        recordCode: recordCode,
        patientCode: recordInfo.patientCode,
        patientName: recordInfo.patientName,
        isCanWriteReport: recordInfo.canCreateReport,
        onRefreshCloudImages: () async {
          return [
            await reportManager.getRemedicalListByRecordInfoAsync(recordCode)
          ];
        },
      ),
    );
  }

  ///报告列表
  Future<void> routerToReportsPage(
    SimpleRecordInfoDTO recordInfo,
  ) async {
    final remedicalManager = Get.find<IRemedicalManager>();
    // final reportManager = Get.find<IReportManager>();
    final String recordCode = recordInfo.recordCode ?? "";
    print('routerToReportsPage set recordCode:$recordCode');
    logger.i('openImageAndReportsDrawer set recordCode:$recordCode');
    if (recordCode.isEmpty) {
      PromptBox.toast("error: recordCode is empty");
      return;
    }
    List<ReportDTO> reportList =
        await remedicalManager.findExamReports(recordCode);

    var patientInfoDto =
        await remedicalManager.findPatientByCode(recordInfo.patientCode!);
    var patientInfo = remedicalManager.dtoConvertToPatientInfo(patientInfoDto);
    var mobileReportsContentView = MobileReportsContentViewNew(
      reportList: reportList,
      recordInfo: recordInfo,
      patientInfo: patientInfo,
      onTapShare: (reportCode) {},
      onRefresh: () => remedicalManager.findExamReports(recordCode),
      onTapImage: (index) {
        openImagePageOnMobile(recordInfo);
      },
    );
    Get.to(() => mobileReportsContentView);
  }

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
    messageViewScrollController.addListener(_scrollToTopListener);
    final initArgs = _getInitArgs();
    _initGroupInfo(initArgs);
    focusNode.addListener(_onFocusChange);
  }

  // 获取页面入参
  ChatPageArgs _getInitArgs() {
    // 要么使用页面初始化入参 initArgs 要么使用路由入参 Get.arguments
    if (initArgs == null) {
      final args = Get.arguments;
      if (args != null && args is ChatPageArgs) {
        return args;
      }
    } else {
      if (initArgs is ChatPageArgs) {
        return initArgs!;
      }
    }

    /// 如果没有获取到入参，返回空对象
    return ChatPageArgs(
      groupName: " ",
      userGroupCode: " ",
      deviceCodes: [],
      totalMembers: 0,
    );
  }

  /// 请求接口，初始化群聊基础数据
  void _initGroupInfo(ChatPageArgs args) async {
    _userGroupCode = args.userGroupCode;
    _deviceCodes = args.deviceCodes;
    state.groupName = args.groupName;
    state.totalDeviceAndMemberNum = args.totalMembers;
    _currentPage = 1;
    PageResult<SimpleRecordInfoDTO> records =
        await rpc.user.getUserGroupRecordPagesAsync(
      GetUserGroupRecordPagesRequest(
        language: i18nBook.locale.toCodeString('-'),
        deviceCodes: args.deviceCodes,
        userGroupCode: args.userGroupCode,
        token: Store.user.token,
        pageIndex: _currentPage,
        pageSize: _pageSize,
        //startTime:UtcDateConverter.getDayStartOrEndUTCTime(startTime)
      ),
    );
    PageResult<UserExtendDTO> membersResult =
        await groupManager.getGroupUserInfos(
      userGroupCode: args.userGroupCode,
      pageSize: 8,
    );
    PageResult<DeviceInfoDTO> devicesResult =
        await groupManager.getGroupDeviceInfos(
      userGroupCode: args.userGroupCode,
      pageSize: 8,
    );

    print("result is $records $membersResult $devicesResult");

    /// 初始化基础成员列表
    eightMembers = membersResult.pageData ?? [];
    eightDevices = devicesResult.pageData ?? [];
    // 初始化数量
    state.totalMemberNum = membersResult.totalCount;
    state.totalDeviceNum = devicesResult.totalCount;
    state.totalDeviceAndMemberNum = state.totalMemberNum + state.totalDeviceNum;
    _totalMessageNum = records.totalCount;
    state.messagesList = records.pageData ?? [];

    /// 下一帧执行
    Future.delayed(Duration.zero, () {
      _messageListViewScrollToBottom();
    });
    _initListening();
  }

  /// PC 客户端用于切换群聊
  void switchGroup(ChatPageArgs args) {
    _initGroupInfo(args);
    if (state.showImageAndReportsDrawer) {
      /// 如果图像抽屉开着，此时需要关掉
      state.showImageAndReportsDrawer = false;
    }
  }

  /// 加载更多数据
  Future<void> _loadMoreData() async {
    if (_kisLoading) return;
    _kisLoading = true;
    _animationTimer = Timer.periodic(Duration(milliseconds: 100), (t) {
      _updateLoadingString();
    });
    try {
      _currentPage++;
      PageResult<SimpleRecordInfoDTO> records =
          await rpc.user.getUserGroupRecordPagesAsync(
        GetUserGroupRecordPagesRequest(
          language: i18nBook.locale.toCodeString('-'),
          deviceCodes: _deviceCodes,
          userGroupCode: _userGroupCode,
          token: Store.user.token,
          pageIndex: _currentPage,
          pageSize: _pageSize,
          //开始结束时间需使用UTC时间
          //startTime:UtcDateConverter.getDayStartOrEndUTCTime(startTime)
        ),
      );
      state.messagesList = [...state.messagesList, ...records.pageData!];
    } catch (e) {
      print(e);
    }
    _kisLoading = false;
    _animationTimer.cancel();
  }

  void _updateLoadingString() {
    switch (state.loadingDot) {
      case "   ":
        state.loadingDot = ".  ";
        break;
      case ".  ":
        state.loadingDot = ".. ";
        break;
      case ".. ":
        state.loadingDot = "...";
        break;
      case "...":
        state.loadingDot = "   ";
        break;
      default:
        state.loadingDot = "   ";
        break;
    }
  }

  /// 滚动到顶部监听
  void _scrollToTopListener() {
    if (messageViewScrollController.position.pixels ==
        messageViewScrollController.position.maxScrollExtent) {
      _handleScrollToTop();
    }
  }

  /// 加载滚动到顶部的事件监听
  void _handleScrollToTop() {
    if (noMoreData) return;
    _loadMoreData();
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
    _animationTimer.cancel();
    messageViewScrollController.removeListener(_scrollToTopListener);
  }

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
    focusNode.dispose();
    _animationTimer.cancel();
    reportManager.onSubmitReport.removeListener(_onSubmitReport);
    messageViewScrollController.removeListener(_scrollToTopListener);
  }

  void openImageAndReportsDrawer(
    SimpleRecordInfoDTO recordInfo, {
    bool isReport = false,
  }) {
    recordCode = recordInfo.recordCode ?? '';
    print('openImageAndReportsDrawer set recordCode:$recordCode');
    logger.i('openImageAndReportsDrawer set recordCode:$recordCode');
    if (state.showImageAndReportsDrawer) {
      Get.find<ImagereportinnerviewController>().changeRecord(
        ImageReportListParams(
          recordCode: recordCode,
          isShowWriteReportButton: recordInfo.canCreateReport,
          index: isReport ? 2 : 0,
        ),
      );
    } else {
      cacheIndex = isReport ? 2 : 0;
      canCreateReport = recordInfo.canCreateReport;
      state.showImageAndReportsDrawer = true;
    }
  }

  void closeImageAndReportsDrawer() {
    state.showImageAndReportsDrawer = false;
  }

  void _onFocusChange() {
    if (focusNode.hasFocus) {
      // TextField获取了焦点
      if (state.showImageAndReportsDrawer) {
        state.showImageAndReportsDrawer = false;
      }
    }
  }

  void _initListening() {
    reportManager.onSubmitReport.addListener(_onSubmitReport);
  }

  Future<void> _onSubmitReport(Object sender, bool e) async {
    var recordDetail = await remedicalManager.queryRecordInfoAsync(recordCode);
    if (recordDetail != null) {
      var simpleRecordInfoDTO = state.messagesList
          .firstWhereOrNull((element) => element.recordCode == recordCode);
      if (simpleRecordInfoDTO?.recordStatus != recordDetail.recordStatus) {
        simpleRecordInfoDTO?.recordStatus = recordDetail.recordStatus;
        //TODO(Loki):此处需要更新UI
      }
    }
  }
}
