import 'dart:async';
import 'package:fis_common/index.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/services/index.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/services/entity/local_setting.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/keyboard.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/architecture/webapi/services/large_file_uploader.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/index.dart';
import 'package:universal_html/html.dart' as html;
import 'state.dart';
import 'widgets/share_dialog.dart';

class DeviceLiveListDesktopController extends DeviceLiveListController
    with EnterPressListenOnControllerMixin {
  @override
  final DeviceLiveListDesktopState state = DeviceLiveListDesktopState();
  final searchFocusNode = FocusNode();
  bool _isSearchHasFocus = false;
  List<int> cacheBytes = [];
  Uint8List? bytes;

  @override
  void onClose() {
    _colseRemoteConnection();
    remoteControllerManager.onConnectStatusToClient
        .removeListener(_onConnectStatusToClient);
    super.onClose();
  }

  /// 提交上传包
  Future<bool> addDevicePatchAsync(
    List<UploadDeviceFileInfoDTO> uploadDeviceFileInfoList,
    int fileSize,
  ) async {
    state.uploadingUpdatePackage = true;

    final result = await rpc.device.addDevicePatchAsync(
      AddDevicePatchRequest(
        token: Store.user.token,
        name: state.packageName,
        description: state.description,
        deviceType: state.applyDeviceCode,
        softwareVersion: state.applySoftwareVersion,
        osVersion: state.applySystemVersion,
        fileUploadInfoList: uploadDeviceFileInfoList,
        fileSize: fileSize,
      ),
    );

    if (result) {
      router.back();
      return true;
    }
    router.back();
    return false;
  }

  /// 添加适配版本号版本
  Future<bool> addDevicePatchVersionAsync({
    DeviceVersionEnum? deviceVersionType,
    String? version,
    String? deviceType,
  }) async {
    final result = await rpc.device.addDevicePatchVersionAsync(
      AddDevicePatchVersionRequest(
        token: Store.user.token,
        versionTypeEnum: deviceVersionType ?? DeviceVersionEnum.SoftwareVersion,
        version: version,
        deviceType: deviceType ?? 'US',
      ),
    );
    return result;
  }

  /// 删除版本号版本
  Future<bool> deleteDevicePatchVersionAsync({
    String? deviceVersionCode,
  }) async {
    final result = await rpc.device.deleteDevicePatchVersionAsync(
      DeleteDevicePatchVersionRequest(
        token: Store.user.token,
        code: deviceVersionCode,
      ),
    );
    return result;
  }

  /// 删除更新包接口
  Future<void> deletePatchByCodeAsync(DevicePatchDTO devicePatch) async {
    final result = await rpc.device.deletePatchByCodeAsync(
      DeleteDevicePatchByCodeRequest(
        token: Store.user.token,
        code: devicePatch.code,
      ),
    );
    if (result) {
      findDevicePatchPagesAsync();
    }
  }

  Future<void> deletePrintDriverDatas(String code) async {
    var result = await remoteMaintenanceManager.deletePrinterByCodeAsync(code);
    if (result) {
      PromptBox.toast(i18nBook.user.deleteSuccess.t);
      findPrintDriverDatas();
    } else {
      PromptBox.toast(i18nBook.user.deleteFailed.t);
    }
  }

  /// 编辑更新包
  void editPackage({
    String? name = '',
    String? description = '',
    String? code = '',
  }) async {
    if (name.isNullOrEmpty) {
      PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
      return;
    }
    final result = await updateDevicePatchAsync(code);
    findDevicePatchPagesAsync(state.firstDialogSearchKeyword);
  }

  /// 查询更新包接口
  Future<void> findDevicePatchPagesAsync([String? keyWord = '']) async {
    state.tableLoading = true;
    final result = await rpc.device.findDevicePatchPagesAsync(
      FindDevicePatchPageRequest(
        token: Store.user.token,
        pageIndex: 1,
        pageSize: 1000,
        keyword: keyWord,
      ),
    );
    state.updatePackageTableContent = result.pageData ?? [];
    state.tableLoading = false;
  }

  /// 查询版本号版本
  Future<List<DevicePatchVersionDTO>> findDevicePatchVersionListAsync({
    DeviceVersionEnum? deviceVersionType,
    String? version,
    String? deviceType,
  }) async {
    final result = await rpc.device.findDevicePatchVersionListAsync(
      FindDevicePatchListRequest(
        token: Store.user.token,
        versionTypeEnum: deviceVersionType ?? DeviceVersionEnum.SoftwareVersion,
        deviceType: deviceType ?? 'US',
      ),
    );
    return result;
  }

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

  @override
  void handleEnterLive(int index) async {
    final code = getCodeByIndex(index);
    final dto = await deviceManager.getDeviceInfo(code);
    if (dto == null) {
      return;
    }

    if (dto.isOnline) {
      if (LocalSetting.ins.isUseSecondWindow == true) {
        if (FPlatform.isPureWeb) {
          final origin = html.window.location.origin;
          const pageName = "DeviceLive";
          final token = Store.user.token;
          final url =
              "$origin/index.html?page=$pageName&code=$code&token=$token";
          html.window.open(url, "");
        } else {
          final countLimit = Store.user.deviceLiveMaxCount;
          rpc.platform.openDeviceLiveWindow(code, Store.user.token, countLimit);
        }
      } else {
        router.to(
          RouteNames.Live.DeviceDetail,
          id: NavIds.HOME,
          parameters: {
            'code': code,
          },
        );
      }
    } else {
      // 提示不在线
      PromptBox.toast(i18nBook.live.tipsOfDeviceOffline.t);
    }
  }

  @override
  void handleShare(int index) async {
    final code = getCodeByIndex(index);
    final url = await deviceManager.shareDeviceLive(code);
    if (url != null && url.isNotEmpty) {
      router.dialog(
        () => DeviceLiveShareDialog(link: url),
      );
    }
  }

  /// 初始化适配设备
  Future<void> initDeviceInfo() async {
    try {
      List<FSelectOptionModel> deviceList = [];

      List<String> result = await rpc.device.getDevicePatchTypeListAsync(
        FindDeviceTypeItemsRequest(
          token: Store.user.token,
        ),
      );
      result.forEach((element) {
        deviceList.add(
          FSelectOptionModel(
            title: _deviceName(element),
            value: element,
          ),
        );
      });
      state.applyDeviceList = deviceList;
      if (state.applyDeviceList.isNotEmpty) {
        state.applyDeviceCode = deviceList.first.value;
      }
    } catch (e) {
      logger.e("initDeviceInfo ex", e);
    }
  }

  @override
  void onEnterPressed() {
    print(searchFocusNode.hasPrimaryFocus);
    if (_isSearchHasFocus) {
      reloadList();
    }
  }

  @override
  void onReady() {
    super.onReady();
    initDeviceInfo();
    _listenSearchFocusNode();
    findDevicePatchPagesAsync();
    findPrintDriverDatas();
    remoteControllerManager.onConnectStatusToClient
        .addListener(_onConnectStatusToClient);
  }

  /// 提交上传包的方法
  void submitPackage(
    html.File? file,
    void Function(double)? onProcessChange,
  ) async {
    try {
      state.uploadingUpdatePackage = true;
      if (file == null || state.packageName.isNullOrEmpty) {
        PromptBox.toast(
            i18nBook.realTimeConsultation.requiredItemsNotCompleted.t);
        return;
      }
      UploadDeviceFileInfo? uploadFileInfo = await rpc.storage
          .readAndUploadFile(file, onProcessChange, _checkCancel);
      if (!state.isCanSubmitPackage) {
        state.uploadingUpdatePackage = false;
        return;
      }
      if (state.packageName.isEmpty || uploadFileInfo == null) {
        PromptBox.toast(
            i18nBook.realTimeConsultation.requiredItemsNotCompleted.t);
        return;
      }
      List<UploadDeviceFileInfoDTO> uploadDeviceFileInfoList = [];
      for (var file in uploadFileInfo.fileInfos!) {
        uploadDeviceFileInfoList.add(UploadDeviceFileInfoDTO(
          partNum: file.partNum,
          fileUrl: file.fileToken,
        ));
      }
      final result = await addDevicePatchAsync(
        uploadDeviceFileInfoList,
        (uploadFileInfo.fileSize ?? 0),
      );
      if (result) {
        PromptBox.toast(i18nBook.remoteControl.uploadSucceeded.t);
        state.uploadingUpdatePackage = false;
      } else {
        PromptBox.toast(i18nBook.remoteControl.uploadFailed.t);
      }
      findDevicePatchPagesAsync();
    } catch (e) {
      state.uploadingUpdatePackage = false;
    }
  }

  bool _checkCancel() {
    if (state.isCanSubmitPackage) {
      return false;
    } else {
      return true;
    }
  }

  /// 修改更新包接口
  Future<bool> updateDevicePatchAsync(String? code) async {
    final result = await rpc.device.updateDevicePatchAsync(
      UpdateDevicePatchRequest(
        token: Store.user.token,
        code: code,
        name: state.packageName,
        description: state.description,
        softwareVersion: state.applySoftwareVersion,
        osVersion: state.applySystemVersion,
      ),
    );
    if (result) {
      router.back();
      return true;
    }
    router.back();
    return false;
  }

  String _deviceName(String device) {
    switch (device) {
      case 'US':
        return i18nBook.user.ulrSoundsMachine.t;
      case 'sonopost':
        return i18nBook.user.sonopost.t;
      default:
        return device;
    }
  }

  /// 关闭超声机
  void _colseRemoteConnection() async {
    await getDeviceStateListByTokenAsync();

    state.remoteControlList.forEach((element) async {
      await applyRemoteConnectionAsync(
        deviceCode: element.deviceCode ?? '',
        controlType: ControlDeviceParameterEnum.End,
      );
    });
    closeHeartbeat();
  }

  /// 设备端连接通知
  void _onConnectStatusToClient(Object a, ConnectStatusToClientNotification e) {
    getDeviceStateListByTokenAsync();
    startHeartbeat();
  }

  void _listenSearchFocusNode() {
    searchFocusNode.addListener(() {
      if (searchFocusNode.hasFocus) {
        _isSearchHasFocus = true;
      } else {
        Future.delayed(
          const Duration(milliseconds: 10),
          () {
            _isSearchHasFocus = false;
          },
        );
      }
    });
  }
}
