import 'dart:async';
import 'dart:convert';

import 'package:fis_common/index.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_ui/widgets/scroll/scroll_extensions.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/interfaces/network_error_handler.dart';
import 'package:flyinsono/managers/interfaces/remote_controller.dart';
import 'package:flyinsono/managers/interfaces/remote_maintenance.dart';
import 'package:flyinsono/managers/interfaces/device.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/rpc.dart';
import 'package:fis_common/http/http_error.dart';
import 'package:get/get.dart';
import 'state.dart';

abstract class DeviceLiveListController extends DeviceLiveListBaseController {
  @override
  final DeviceLiveListState state = DeviceLiveListState();
  final liveConsultationManager = Get.find<ILiveConsultationManager>();
  final deviceManager = Get.find<IDeviceManager>();
  final remoteControllerManager = Get.find<IRemoteControllerManager>();
  final remoteMaintenanceManager = Get.find<IRemoteMaintenanceManager>();
  var networkErrorHandlerManager = Get.find<INetworkErrorHandlerManager>();

  ///选中推送的补丁包Code
  String pushPatchCode = '';
  Timer? _heartbeatTimer;
  int _networkRetryCount = 0;

  @override
  void onReady() {
    super.onReady();
    if (CartSystemPlatform.specialOnceOperationFlag) {
      CartSystemPlatform.specialOnceOperationFlag = false;
      return;
    }
    reloadList();
  }

  /// 处理分享
  ///
  /// [index] 索引
  void handleShare(int index);

  /// 处理进入直播
  ///
  /// [index] 索引
  void handleEnterLive(int index);

  @override
  Future<void> reloadList() async {
    state.pageIndex = 1;
    await _loadList(true);
  }

  @override
  Future<void> loadMoreList() async {
    if (!state.hasNextPage) return;

    state.pageIndex += 1;
    final loaded = await _loadList();
    if (!loaded) {
      // 加载更多失败，回复当前页状态
      state.pageIndex -= 1;
    }
  }

  /// 系统设置
  Future<void> sendCommandToDeviceAsync({
    String? actionType,
    required String deviceCode,
    String? settings,
  }) async {
    await rpc.device.sendCommandToDeviceAsync(
      SendCommandToDeviceRequest(
        token: Store.user.token,
        deviceCode: deviceCode,
        actionType: actionType ?? 'Get',
        settings: settings,
      ),
    );
  }

  /// 系统设置获取到的结果
  Future<void> getResultFromServerAsync({
    String? resultCode,
    bool? isInitSystemSettings = true,
  }) async {
    var result;
    try {
      result = await rpc.device.getResultFromServerAsync(
        GetResultFromServerRequest(
          token: Store.user.token,
          resultCode: resultCode ?? '',
        ),
      );
      if (isInitSystemSettings!) {
        state.listPages = [];
        //To tace some bugs, ugly, try to fix it after bug is resolved.
        try {
          state.listPages =
              jsonDecode(jsonDecode(result)['Settings'])['ListPages'];
        } catch (e) {
          logger.e('isInitSystemSettings error happened:', e);
          logger.e('The result is: $result');
          logger.e('The setting  is: ${jsonDecode(result)['Settings']}');
          logger.e(
              'The ListPages  is: ${jsonDecode(jsonDecode(result)['Settings'])['ListPages']}');
        }
        // 获取页配置
      } else {
        final applyLicenseResult =
            jsonDecode(jsonDecode(result)['Settings'])['ApplyLicenseResult'];
        final systemButtonResult =
            jsonDecode(jsonDecode(result)['Settings'])['ListPages']
                .last['Result'];
        if (systemButtonResult == 'TestvStationFailed') {
          PromptBox.toast(
              i18nBook.remoteControl.testFailed.translate(['VStation']));
        } else if (systemButtonResult == 'TestvStationSuccess') {
          PromptBox.toast(
              i18nBook.remoteControl.testSucceeded.translate(['VStation']));
        } else if (systemButtonResult == 'TestDicomServerSuccess') {
          PromptBox.toast(i18nBook.remoteControl.testSucceeded
              .translate([i18nBook.remoteControl.connectedStorage.t]));
        } else if (systemButtonResult == 'TestDicomServerFailed') {
          PromptBox.toast(
              // DicomServer
              i18nBook.remoteControl.testFailed
                  .translate([i18nBook.remoteControl.connectedStorage.t]));
        } else if (applyLicenseResult == 'InvalidLicense') {
          PromptBox.toast(i18nBook.remoteControl.invalidLicenseCode.t);
        } else if (systemButtonResult == 'ClearRemedicalCacheSuccess') {
          PromptBox.toast(i18nBook.remoteControl.clearSuccess.t);
        } else {
          PromptBox.toast(i18nBook.organization.saveSuccess.t);
        }
      }
    } catch (e) {
      logger.e('getResultFromServerAsync execute ex:', e);

      logger.e('The result is: $result');
      logger.e('The setting  is: ${jsonDecode(result)['Settings']}');
      logger.e(
          'The ListPages  is: ${jsonDecode(jsonDecode(result)['Settings'])['ListPages']}');
      logger.e(
          'The ApplyLicenseResult  is: ${jsonDecode(jsonDecode(result)['Settings'])['ApplyLicenseResult']}');
      PromptBox.toast(i18nBook.errorCodes.errorCodeUN.t);
      Future.delayed(Duration(milliseconds: 500), () {
        Get.back();
      });
      return;
    }
  }

  /// 可推送的更新包
  Future<void> findPushDevicePatchPagesAsync(
    String? deviceCode, [
    String? keyWord = '',
    List<String>? findOnlyDeviceTypes,
  ]) async {
    state.tableLoading = true;
    final PageResult<DevicePatchDTO> result =
        await rpc.device.findPushDevicePatchPagesAsync(
      FindPushDevicePatchPageRequest(
        token: Store.user.token,
        keyword: keyWord,
        deviceCode: deviceCode,
        findOnlyDeviceTypes: findOnlyDeviceTypes,
        pageIndex: 1,
        pageSize: 100,
      ),
    );

    if (result.pageData?.length != 0) {
      state.devicePatchList = result.pageData ?? [];
    }
    state.tableLoading = false;
    // if (result) {
    //   findDevicePatchPagesAsync();
    // }
  }

  ///查找打印驱动表格数据
  Future<void> findPrintDriverDatas({String keyWord = ''}) async {
    state.tableLoading = true;
    var pageDatas = await remoteMaintenanceManager.findDevicePrinterPagesAsync(
        keyword: keyWord);
    state.printDriverTableDatas = pageDatas.pageData ?? [];
    state.tableLoading = false;
  }

  /// 更新或取消推送设备补丁包
  Future<bool> pushDevicePatchAsync({
    required String deviceCode,
    required String patchCode,
    PushDevicePatchEnum? pushEnum,
  }) async {
    pushPatchCode = patchCode;
    return await rpc.device.pushDevicePatchAsync(
      PushDevicePatchRequest(
        token: Store.user.token,
        deviceCode: deviceCode,
        patchCode: patchCode,
        pushEnum: pushEnum ?? PushDevicePatchEnum.Start,
      ),
    );
  }

  /// 申请连接/断开请求
  Future<bool> applyRemoteConnectionAsync({
    required String deviceCode,
    ControlDeviceParameterEnum? controlType,
  }) async {
    bool result = false;
    try {
      result = await rpc.device.applyRemoteConnectionAsync(
        ControlDeviceConnectRequest(
          token: Store.user.token,
          deviceCode: deviceCode,
          isNeedSyn: true,
          controlType: controlType ?? ControlDeviceParameterEnum.Start,
        ),
      );
    } catch (e) {
      logger.e('DeviceLiveListController applyRemoteConnectionAsync ex:', e);
    }
    return result;
  }

  /// 获取日志的接口
  Future<void> getRemoteLogAsync({
    required String deviceCode,
    required LogTimeEnum logTimeEnum,
  }) async {
    try {
      final result = await rpc.device.getRemoteLogAsync(
        GetRemoteLogRequest(
          token: Store.user.token,
          deviceCode: deviceCode,
          logTime: logTimeEnum,
        ),
      );
      if (result) {
        router.back();
      }
    } on FHttpError catch (e) {
      logger.w("check server validation fail. errorType: ${e.type}");
      PromptBox.toast(i18nBook.remoteControl.networkConnectionError.t);
      router.back();
    } catch (e) {
      logger.e("getRemoteLogAsync unknown error", e);
    }
  }

  /// 获取开启连接的设备列表
  Future<void> getDeviceStateListByTokenAsync() async {
    final result = await rpc.device.getDeviceStateListByTokenAsync(
      GetDeviceStateListRequest(
        token: Store.user.token,
      ),
    );
    List<DeviceConnectStateResult> remoteControlList = [];
    for (DeviceConnectStateResult i in result) {
      remoteControlList.add(i);
    }

    state.remoteControlList = remoteControlList;
  }

  /// 日志下载进度条
  void handleProgressChanged(progress, exportState) {
    double progressNum = double.parse(progress);
    state.deviceProgress = (50 + (0.5 * (progressNum * 100))).toInt();
    if (progressNum == 1) {
      state.hasDownloadedLogs = true;
      if (CartSystemPlatform.isCartSystemVersion) {
        PromptBox.toast(i18nBook.common.downloadSuccess.t);
      } else {
        PromptBox.toast(i18nBook.remoteControl.downloadLogSuccess.t);
      }
    }
  }

  /// 打开日志下载地址 文件窗口
  void openLogDownloadPath() {
    rpc.platform
        .openSpecifiedPath("@ShellDomain@\\Logs\\TerminalLogs"); // 在文件夹中打开桌面
  }

  /// 取消日志接口
  Future<void> userCancelLogDownloadAsync({
    required String deviceCode,
  }) async {
    await rpc.device.userCancelLogDownloadAsync(
      GetDeviceRequest(
        token: Store.user.token,
        deviceCode: deviceCode,
      ),
    );
  }

  /// 设置打印机
  Future<void> setDevicePrinterAsync({
    String? deviceCode,
    DevicePrinterEnum setPrinterEnum = DevicePrinterEnum.GetInstalledPrinters,
    List<DevicePrinterParameter>? parameters,
    bool isIpSearch = false,
  }) async {
    if (deviceCode.isNotNullOrEmpty) {
      await rpc.device.setDevicePrinterAsync(
        SetDevicePrinterRequest(
          deviceCode: deviceCode,
          setPrinterEnum: setPrinterEnum,
          parameters: parameters,
          token: Store.user.token,
        ),
      );
    } else if (setPrinterEnum == DevicePrinterEnum.SearchPrinter) {
      String? ip = "";
      if (isIpSearch) {
        ip = parameters?[0].parameterValue!;
      }
      var printers =
          await remoteMaintenanceManager.getUninstalledPrinters(ip: ip);
      print(printers);
      List<DevicePrinterParameterDTO> devicePrinterList = [];
      for (var printer in printers) {
        // 解析JSON字符串
        Map<String, dynamic> printerInfo = jsonDecode(printer);
        String name = printerInfo['Name'] ?? "";
        String manufacturer = printerInfo['Manufacturer'] ?? "";
        devicePrinterList.add(DevicePrinterParameterDTO(
          name: name,
          brand: manufacturer,
        ));
      }
      remoteControllerManager.onDevicePrinterResult.emit(
        this,
        DevicePrinterResultNotification(
          setPrinterEnum: DevicePrinterEnum.SearchPrinter,
          devicePrinterList: devicePrinterList,
        ),
      );
    }
  }

  Future<bool> restartDeviceAsync({
    String? deviceCode,
  }) async {
    return await rpc.device.restartDeviceAsync(
      RestartDeviceRequest(
        deviceCode: deviceCode,
        isNeedSyn: true,
        token: Store.user.token,
      ),
    );
  }

  /// 远程控制的心跳
  Future<void> remoteConnectHeartRateSendOnce({
    TransactionTypeEnum transactionType = TransactionTypeEnum.Consultion,
  }) async {
    try {
      var remoteConnectHeartRate = await rpc.device.remoteConnectHeartRateAsync(
        RemoteConnectHeartRateRequest(
          token: Store.user.token,
          isNeedSyn: true,
          transactionType: transactionType,
        ),
      );

      /// 重置连接次数
      if (_networkRetryCount != 0) {
        _networkRetryCount = 0;
        networkErrorHandlerManager.onNetworkInterruption.emit('', false);
        networkErrorHandlerManager.isNetworkInterruption = false;
      }
    } catch (e) {
      _networkRetryCount += 1;

      /// 三次心跳不通过直接置空状态呢
      if (_networkRetryCount == 3) {
        /// 远程控制连接的控制器列表置空
        state.remoteControlList = [];
        networkErrorHandlerManager.onNetworkInterruption.emit('', true);
        networkErrorHandlerManager.isNetworkInterruption = true;
      }
    }
  }

  ///远程调参
  Future<void> startRemoteController(DeviceExtendInfoDTO _dto) async {
    var deviceCode = _dto.deviceCode ?? '';
    var result = await remoteControllerManager.applyRemoteControlAsync(
      deviceCode: deviceCode,
      controllerType: ControlDeviceParameterEnum.Get,
    );
    if (result) {
      deviceManager.openRemoteControllerPage(deviceCode);
    }
  }

  /// 获取打印机设备列表
  Future<List<DevicePrinterParameterDTO>> getDevicePrintersForUploadAsync(
      String deviceCode) async {
    var result = await rpc.device.getDevicePrintersForUploadAsync(
      GetDevicePrintersForUploadRequest(
        deviceCode: deviceCode,
        token: Store.user.token,
      ),
    );
    return result;
  }

  @protected
  String getCodeByIndex(int index) => state.deviceList[index].deviceCode!;

  /// 开启远程连接心跳
  Future<void> startHeartbeat() async {
    closeHeartbeat();
    // 如果之前的定时器已经存在，则先取消之前的定时器
    _heartbeatTimer = Timer.periodic(
      Duration(seconds: 5),
      (timer) {
        remoteConnectHeartRateSendOnce(
            transactionType: TransactionTypeEnum.ControlParameter);
      },
    );
  }

  // 关闭远程连接心跳
  void closeHeartbeat() {
    print('清除心跳包');
    _heartbeatTimer?.cancel();
    _heartbeatTimer = null;
  }

  Future<bool> _loadList([bool refresh = false]) async {
    busy = true;

    final pagedList = await deviceManager.getUserDevicePagedList(
      state.pageIndex,
      state.pageSize,
      keyword: state.searchKeyword,
    );
    if (pagedList == null) {
      busy = false;
      return false;
    }
    state.totalCount = pagedList.dataCount;
    if (refresh) {
      state.updateDeviceList(pagedList.pageData!);
    } else {
      state.appendDeviceList(pagedList.pageData!);
    }
    busy = false;
    return true;
  }
}

abstract class DeviceLiveListBaseController extends FControllerBase {
  /// 状态
  final state = DeviceLiveListBaseState();

  @override
  Future<void> onLoad() async {
    super.onLoad();

    listScrollController.onScrollToBottom = () {
      loadMoreList();
    };
  }

  /// 列表滚动控制器
  final listScrollController = ScrollController();

  /// 加载更多列表
  Future<void> loadMoreList();

  /// 重新加载列表
  Future<void> reloadList();
}
