import 'dart:collection';

import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/services/index.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/values/features.dart';
import 'package:fis_common/index.dart';
import 'package:flyinsono/views/desktop/device_live/device_live_list/controller.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';

class DeviceLiveListState extends DeviceLiveListBaseState {
  final _deviceList = FRxList<DeviceExtendInfoDTO>([]);

  final RxInt _isShowDeviceDetailIndex = RxInt(-1);
  final Rx<List<DevicePatchDTO>> _devicePatchList = Rx(<DevicePatchDTO>[]);
  final Rx<bool> _tableLoading = Rx(false);
  final Rx<List<DeviceConnectStateResult>> _remoteControlList = Rx([]);
  final Rx<bool> _isPushDevicePatch = Rx(false);
  final Rx<bool> _isGettingLogs = Rx(false);
  final Rx<double> _progress = Rx(0);
  final Rx<int> _deviceProgress = Rx(0);
  final Rx<String> _packageName = Rx('');
  final Rx<String> _packageCode = Rx('');
  final Rx<List> _listPages = Rx([]);
  final Rx<String> _currentDeviceCode = Rx('');
  final Rx<String> _deviceSelectPrinterCode = Rx('');
  final RxList<DevicePrinterDTO> _printDriverTableDatas =
      RxList(<DevicePrinterDTO>[]);
  final Rx<Map> _systemSettingItem = Rx(Map());
  final Rx<Map> _systemSettingContentItem = Rx(Map());

  /// 设备详情的下标
  int get isShowDeviceDetailIndex => _isShowDeviceDetailIndex.value;
  set isShowDeviceDetailIndex(int val) => _isShowDeviceDetailIndex.value = val;

  /// 搜索关键字
  String? searchKeyword;

  /// 一级对话框搜索关键字
  String? firstDialogSearchKeyword;

  /// 设备列表
  UnmodifiableListView<DeviceExtendInfoDTO> get deviceList =>
      UnmodifiableListView(_deviceList);

  Map<String, ConnectStatusEnum?> connectStatus = {};

  /// 补充设备列表
  void appendDeviceList(List<DeviceExtendInfoDTO> dtoList) {
    _deviceList.addAll(dtoList);
  }

  /// 更新设备列表
  void updateDeviceList(List<DeviceExtendInfoDTO> dtoList) {
    _deviceList.value = dtoList;
  }

  /// 更新指定设备
  void updateDevice(int index, DeviceExtendInfoDTO dto) {
    //
  }

  /// 表格loadding
  set tableLoading(bool value) => _tableLoading.value = value;
  bool get tableLoading => _tableLoading.value;

  /// 可以推送的包列表
  List<DevicePatchDTO> get devicePatchList => _devicePatchList.value;
  set devicePatchList(List<DevicePatchDTO> val) => _devicePatchList.value = val;

  List<DeviceConnectStateResult> get remoteControlList =>
      _remoteControlList.value;
  set remoteControlList(List<DeviceConnectStateResult> val) =>
      _remoteControlList.value = val;

  /// 推送时候的进度条
  double get progress => _progress.value;
  set progress(double val) => _progress.value = val;

  /// 设备端下载的进度条
  int get deviceProgress => _deviceProgress.value;
  set deviceProgress(int val) => _deviceProgress.value = val;

  /// 推送时候的包名称
  String get packageName => _packageName.value;
  set packageName(String val) => _packageName.value = val;

  /// 推送时候的包code
  String get packageCode => _packageCode.value;
  set packageCode(String val) => _packageCode.value = val;

  /// 当前设备code
  String get currentDeviceCode => _currentDeviceCode.value;
  set currentDeviceCode(String val) => _currentDeviceCode.value = val;

  /// 当前选中的打印机云驱动code
  String get deviceSelectPrinterCode => _deviceSelectPrinterCode.value;
  set deviceSelectPrinterCode(String val) =>
      _deviceSelectPrinterCode.value = val;

  /// 是否正在推送包
  bool get isPushDevicePatch => _isPushDevicePatch.value;
  set isPushDevicePatch(bool val) => _isPushDevicePatch.value = val;

  /// 是否正在获取日志
  bool get isGettingLogs => _isGettingLogs.value;
  set isGettingLogs(bool val) => _isGettingLogs.value = val;

  /// 获取系统设置
  List get listPages => _listPages.value;
  set listPages(List val) => _listPages.value = val;

  /// 是否有远程维护权限
  bool get hasRemoteMaintain =>
      Store.user.hasFeature(FeatureKeys.RemoteMaintain);

  /// 是否有远程维护管理员权限
  bool get hasRemoteManager => Store.user.hasFeature(FeatureKeys.RemoteManager);

  /// 获取系统缓存的tab
  Map get systemSettingItem => _systemSettingItem.value;
  set systemSettingItem(Map val) => _systemSettingItem.value = val;

  /// 获取系统缓存的子集tab
  Map get systemSettingContentItem => _systemSettingContentItem.value;
  set systemSettingContentItem(Map val) =>
      _systemSettingContentItem.value = val;

  List<DevicePrinterDTO> get printDriverTableDatas => _printDriverTableDatas;
  set printDriverTableDatas(List<DevicePrinterDTO> v) =>
      _printDriverTableDatas.value = v;

  /// 是否已下载日志
  bool hasDownloadedLogs = false;
}

class DeviceLiveListBaseState {
  /// 当前页码
  int pageIndex = 1;

  /// 每页数量
  int pageSize = kIsMobile ? 15 : 35;

  /// 数据总数
  int totalCount = 0;

  /// 是否存在下一页
  bool get hasNextPage => pageIndex * pageSize < totalCount;
}

class PackageTableColumn {
  /// 更新包管理表格Header
  static List<FTableColumn<DevicePatchDTO>> updatePackageList([
    bool? isPackageManager = true,
  ]) {
    final controller = Get.find<DeviceLiveListDesktopController>();
    final TextStyle textStyle = TextStyle(
      fontSize: 15,
    );

    return <FTableColumn<DevicePatchDTO>>[
      FTableColumn<DevicePatchDTO>(
        headerText: i18nBook.remedical.updatePackageName.t,
        render: (rowData, index) => FCenter(
          child: FText(
            rowData.name.toString(),
            style: textStyle,
          ),
        ),
      ),
      FTableColumn<DevicePatchDTO>(
        headerText: i18nBook.remedical.description.t,
        textFormatter: (rowData, index) => rowData.description!.isEmpty
            ? i18nBook.realTimeConsultation.noAssistant.t
            : rowData.description.toString(),
      ),
      FTableColumn<DevicePatchDTO>(
        headerText: i18nBook.remedical.applicableSystemVersion.t,
        render: (rowData, index) => FCenter(
          child: FText(
            getVersion(rowData.deviceType, rowData.osVersion),
            style: textStyle,
          ),
        ),
      ),
      FTableColumn<DevicePatchDTO>(
        headerText: i18nBook.remedical.applicableSoftwareVersion.t,
        render: (rowData, index) => FCenter(
          child: FText(
            getVersion(rowData.deviceType, rowData.softwareVersion),
            style: textStyle,
          ),
        ),
      ),
      if (isPackageManager!)
        FTableColumn<DevicePatchDTO>(
          headerText: i18nBook.remoteControl.adaptedDevices.t,
          render: (rowData, index) => FCenter(
            child: FText(
              getDeviceTypeTitle(
                controller.state.applyDeviceList,
                rowData.deviceType,
              ),
              style: textStyle,
            ),
          ),
        ),
      FTableColumn<DevicePatchDTO>(
        headerText: i18nBook.remoteControl.size.t,
        render: (rowData, index) => FCenter(
          child: FText(
            formatBytes(rowData.fileSize, 2),
            style: textStyle,
          ),
        ),
      ),
      FTableColumn<DevicePatchDTO>(
        headerText: i18nBook.remoteControl.releaseTime.t,
        render: (rowData, index) => FCenter(
          child: FText(
            formatDateTime(rowData.createTime),
            style: textStyle,
          ),
        ),
      ),
    ];
  }

  static String getDeviceTypeTitle(
      List<FSelectOptionModel> applyDeviceList, String? deviceTypeValue) {
    return applyDeviceList
            .firstWhereOrNull((element) => element.value == deviceTypeValue)
            ?.title ??
        '';
  }

  /// 字节转换方法
  static String formatBytes(int bytes, int decimals) {
    if (bytes <= 0) return "0B";
    const suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
    var i = 0;
    var size = bytes.toDouble();
    while (size >= 1024 && i < suffixes.length - 1) {
      size /= 1024;
      i++;
    }
    return "${(size.toStringAsFixed(decimals))}${suffixes[i]}";
  }

  static String getVersion(String? deviceType, String? version) {
    if (deviceType != 'US') {
      return '-';
    } else {
      return version.isNullOrEmpty ? '通用' : version.toString();
    }
  }

  static String formatDateTime(DateTime? dateTime) {
    var formatter = DateFormat('yyyy-MM-dd HH:mm');
    return formatter.format(dateTime?.toLocal() ?? DateTime.now().toLocal());
  }
}

class PrintMachineTableColumn {
  ///打印机管理表格Header
  static List<FTableColumn<DevicePrinterDTO>> get printMachineList {
    return <FTableColumn<DevicePrinterDTO>>[
      FTableColumn<DevicePrinterDTO>(
        headerText: i18nBook.remoteControl.printerDriverName.t,
        render: (rowData, index) => FCenter(
          child: FText(
            rowData.name ?? '',
            style: const TextStyle(
              fontSize: 16,
            ),
          ),
        ),
      ),
      FTableColumn<DevicePrinterDTO>(
        headerText: i18nBook.remoteControl.printerBrand.t,
        render: (rowData, index) => FCenter(
          child: FText(
            rowData.printerBrands.toString(),
            style: const TextStyle(
              fontSize: 16,
            ),
          ),
        ),
      ),
      FTableColumn<DevicePrinterDTO>(
        headerText: i18nBook.remoteControl.adaptSystemVersion.t,
        render: (rowData, index) => FCenter(
          child: FText(
            rowData.osVersion ?? "-",
            style: const TextStyle(
              fontSize: 16,
            ),
          ),
        ),
      ),
      FTableColumn<DevicePrinterDTO>(
        headerText: i18nBook.remoteControl.supportedPrinterModels.t,
        render: (rowData, index) {
          var models = rowData.printerModels ?? [];
          var printerModel = '';
          for (var m in models) {
            printerModel += m + '.';
          }
          return FCenter(
            child: FText(
              printerModel,
              style: const TextStyle(
                fontSize: 16,
              ),
            ),
          );
        },
      ),
      FTableColumn<DevicePrinterDTO>(
          headerText: i18nBook.remoteControl.size.t,
          render: (rowData, index) {
            var fileSize = rowData.fileSize / 1024 / 1024;
            var fileSizeStr = fileSize.toStringAsFixed(2) + "MB";
            return FCenter(
              child: FText(
                fileSizeStr,
                style: const TextStyle(
                  fontSize: 16,
                ),
              ),
            );
          }),
      FTableColumn<DevicePrinterDTO>(
        headerText: i18nBook.remoteControl.releaseTime.t,
        textFormatter: (rowData, index) {
          DateFormat dateFormat = DateFormat('yyyy-MM-dd HH:mm');
          return dateFormat.format(
            rowData.createTime?.toLocal() ?? DateTime.now().toLocal(),
          );
        },
      ),
    ];
  }
}
