import 'package:fis_common/event/event_type.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_ui/base_define/page.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/webapi/services/large_file_uploader.dart';
import 'package:flyinsono/js_platform/listener.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/desktop/device_live/device_live_list/controller.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fis_theme/theme.dart';
import 'package:flyinsono/views/desktop/device_live/device_live_list/widgets/add_version_dialog.dart';
import 'package:flyinsono/views/desktop/device_live/device_live_list/widgets/custom_progress_bar.dart';
import 'package:flyinsono/views/desktop/device_live/device_live_list/widgets/version_list_dialog.dart';
import 'package:get/get.dart';

// /// 上传包
class UploadPackageDialog extends FStatefulWidget implements FPage {
  final controller = Get.find<DeviceLiveListDesktopController>();
  UploadPackageDialog({
    super.key,
    this.isEdit = false,
    this.packageCode = '',
    this.packageData,
  });
  final bool? isEdit;
  final String? packageCode;
  final DevicePatchDTO? packageData;

  @override
  String get pageName => 'UploadPackageDialog';

  @override
  FState<FStatefulWidget> createState() {
    return FUploadPackageDialogState();
  }
}

class FUploadPackageDialogState extends FState<UploadPackageDialog> {
  html.File? file;
  final controller = Get.find<DeviceLiveListDesktopController>();
  final FEventHandler<double> onProcessChange = FEventHandler<double>();

  /// 正在上传中
  bool _isUploadding = false;
  @override
  void initState() {
    super.initState();
    controller.state.isCanSubmitPackage = true;
    _initData();
  }

  @override
  void dispose() async {
    controller.state.updateFileName = '';
    controller.state.uploadProgress = 0;
    controller.state.isCanSubmitPackage = false;
    onProcessChange.dispose();
    _isUploadding = false;
    super.dispose();
  }

  @override
  FWidget build(BuildContext context) {
    return FSimpleDialog(
      contentPadding: EdgeInsets.symmetric(vertical: 25, horizontal: 25),
      title: FText(
        widget.isEdit!
            ? i18nBook.remoteControl.editUpdatePackage.t
            : i18nBook.laboratory.upload.t,
        style: TextStyle(
          color: Colors.white,
          fontSize: 18,
        ),
      ),
      onClose: () {
        _confirmLeave();
      },
      okString: i18nBook.common.confirm.t,
      cancelString: i18nBook.common.cancel.t,
      children: [
        FContainer(
          width: 550,
          margin: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
          child: widget.isEdit!
              ? FColumn(
                  children: [
                    _buildUploadRow(
                      i18nBook.remoteControl.updatePackageName.t,
                      _buildInput(
                        onChanged: (value) {
                          controller.state.packageName = value;
                        },
                        textInput: controller.state.packageName,
                      ),
                      true,
                    ),
                    _buildUploadRow(
                      i18nBook.remedical.description.t,
                      _buildInput(
                        onChanged: (value) {
                          controller.state.description = value;
                        },
                        textInput: controller.state.description,
                      ),
                    ),
                    FObx(() {
                      if (controller.state.applyDeviceCode != 'sonopost')
                        return _buildUploadRow(
                          i18nBook.remoteControl.adaptedSoftwareVersions.t,
                          _buildMultipleSelect(
                            versionType: DeviceVersionEnum.SoftwareVersion,
                            versionListCallback: (List<String> value) {
                              controller.state.applySoftwareVersion =
                                  value.join(';');
                            },
                            addVersionTitle: i18nBook
                                .remoteControl.enterUltrasoundSoftwareVersion.t,
                            versionAddCallback: (value) {
                              if (controller
                                  .state.applySoftwareVersion.isEmpty) {
                                controller.state.applySoftwareVersion = value;
                              } else {
                                controller.state.applySoftwareVersion +=
                                    ';$value';
                              }
                            },
                            inputText: controller.state.applySoftwareVersion,
                          ),
                        );
                      else
                        return FSizedBox();
                    }),
                    FObx(() {
                      if (controller.state.applyDeviceCode != 'sonopost')
                        return _buildUploadRow(
                          i18nBook.remoteControl.adaptedSystemVersions.t,
                          _buildMultipleSelect(
                            versionType: DeviceVersionEnum.OsVersion,
                            versionListCallback: (List<String> value) {
                              controller.state.applySystemVersion =
                                  value.join(';');
                            },
                            addVersionTitle: i18nBook
                                .remoteControl.enterUltrasoundSystemVersion.t,
                            versionAddCallback: (value) {
                              if (controller.state.applySystemVersion.isEmpty) {
                                controller.state.applySystemVersion = value;
                              } else {
                                controller.state.applySystemVersion +=
                                    ';$value';
                              }
                            },
                            inputText: controller.state.applySystemVersion,
                          ),
                        );
                      else
                        return FSizedBox();
                    }),
                  ],
                )
              : FColumn(
                  children: [
                    _buildUploadRow(
                      i18nBook.remoteControl.updatePackageName.t,
                      _buildInput(
                        onChanged: (value) {
                          controller.state.packageName = value;
                        },
                      ),
                      true,
                    ),
                    _buildUploadRow(
                      i18nBook.remedical.description.t,
                      _buildInput(
                        onChanged: (value) {
                          controller.state.description = value;
                        },
                      ),
                    ),
                    _buildUploadRow(
                      i18nBook.remoteControl.adaptedDevices.t,
                      _buildSingleSelect(),
                    ),
                    FObx(() {
                      if (controller.state.applyDeviceCode != 'sonopost')
                        return _buildUploadRow(
                          i18nBook.remoteControl.adaptedSoftwareVersions.t,
                          _buildMultipleSelect(
                            versionType: DeviceVersionEnum.SoftwareVersion,
                            addVersionTitle: i18nBook
                                .remoteControl.enterUltrasoundSoftwareVersion.t,
                            versionListCallback: (List<String> value) {
                              controller.state.applySoftwareVersion =
                                  value.join(';');
                            },
                            versionAddCallback: (value) {
                              if (controller
                                  .state.applySoftwareVersion.isEmpty) {
                                controller.state.applySoftwareVersion = value;
                              } else {
                                controller.state.applySoftwareVersion +=
                                    ';$value';
                              }
                            },
                            inputText: controller.state.applySoftwareVersion,
                          ),
                        );
                      else
                        return FSizedBox();
                    }),
                    FObx(() {
                      if (controller.state.applyDeviceCode != 'sonopost')
                        return _buildUploadRow(
                          i18nBook.remoteControl.adaptedSystemVersions.t,
                          _buildMultipleSelect(
                            versionType: DeviceVersionEnum.OsVersion,
                            versionListCallback: (List<String> value) {
                              controller.state.applySystemVersion =
                                  value.join(';');
                            },
                            addVersionTitle: i18nBook
                                .remoteControl.enterUltrasoundSystemVersion.t,
                            versionAddCallback: (value) {
                              if (controller.state.applySystemVersion.isEmpty) {
                                controller.state.applySystemVersion = value;
                              } else {
                                controller.state.applySystemVersion +=
                                    ';$value';
                              }
                            },
                            inputText: controller.state.applySystemVersion,
                          ),
                        );
                      else
                        return FSizedBox();
                    }),
                    _buildUploadRow(
                      i18nBook.remoteControl.localUpdatePackageFile.t,
                      _buildUpload(),
                      true,
                    ),
                    FObx(() {
                      if (controller.state.uploadProgress > 0 && _isUploadding)
                        return FCustomProgressBar(
                          onProcessChange: onProcessChange,
                        );
                      else
                        return FSizedBox();
                    }),
                  ],
                ),
        ),
      ],
      isDefault: false,
      bottomButton: FContainer(
        padding: EdgeInsets.symmetric(vertical: 10),
        child: FRow(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _buildCommonButton(i18nBook.common.submit.t, () {
              if (controller.state.packageName.isNotEmpty) {
                controller.state.packageName =
                    controller.state.packageName.trim();
              }
              if (widget.isEdit!) {
                controller.editPackage(
                  name: controller.state.packageName,
                  code: widget.packageCode,
                );
              } else {
                controller.submitPackage(
                  file,
                  _onProcessChange,
                );
              }
            }),
          ],
        ),
      ),
    );
  }

  /// 上传单行
  FWidget _buildUploadRow(
    String label,
    FWidget value, [
    bool isRequired = false,
  ]) {
    final labelStyle = TextStyle(fontSize: 16);

    FWidget txt = FText.rich(
      TextSpan(
        children: [
          TextSpan(
            text: label,
            style: labelStyle,
          ),
          isRequired
              ? TextSpan(
                  text: ' *',
                  style: labelStyle.copyWith(color: Colors.red),
                )
              : TextSpan(),
        ],
      ),
    );

    return FContainer(
      margin: EdgeInsets.symmetric(
        vertical: 10,
      ),
      child: FRow(
        children: [
          FContainer(
            width: 150,
            child: txt,
          ),
          value,
        ],
      ),
    );
  }

  FWidget _buildCommonButton(String buttonName, VoidCallback onPressed) {
    return FObx(
      () => FElevatedButton(
        child: FText(buttonName),
        onPressed: controller.state.uploadingUpdatePackage
            ? null
            : () {
                onPressed.call();
              },
        businessParent: widget,
        name: buttonName,
        style: ElevatedButton.styleFrom(
          elevation: 0,
          padding: EdgeInsets.symmetric(
            vertical: 15,
            horizontal: 25,
          ),
          backgroundColor: controller.state.uploadingUpdatePackage
              ? Colors.grey
              : FTheme.ins.colorScheme.primary,
        ),
      ),
    );
  }

  /// 输入框
  FWidget _buildInput({
    bool readOnly = false,
    VoidCallback? onTap,
    String? textInput,
    ValueCallback? onChanged,
  }) {
    return FBorderInput(
      hintSize: 16,
      contentSize: 16,
      maxLength: 20,
      borderColor: Color.fromRGBO(234, 234, 234, 1),
      height: 38,
      readOnly: readOnly,
      hintText: '',
      onTap: onTap,
      onChanged: (value) {
        onChanged?.call(value);
      },
      controller: TextEditingController(
        text: textInput,
      ),
    );
  }

  /// 单选框
  FWidget _buildSingleSelect() {
    final select = FObx(
      () => FSelect<FSelectOptionModel, String>(
        source: controller.state.applyDeviceList,
        hintText: i18nBook.remoteControl.adaptedDevices.t,
        value: controller.state.applyDeviceCode,
        height: 36,
        optionLabelExtractor: (data) => data.title,
        fontFamily: FTheme.ins.localeSetting.fontFamily,
        optionValueExtractor: (data) => data.value,
        onSelectChanged: (value, index) {
          controller.state.applyDeviceCode = value ?? '';
        },
      ),
    );
    return FExpanded(child: select);
  }

  /// 多选
  FWidget _buildMultipleSelect({
    required DeviceVersionEnum versionType,
    required ValueCallback<List<String>> versionListCallback,
    required ValueCallback<String> versionAddCallback,
    required String inputText,
    required String addVersionTitle,
  }) {
    return FExpanded(
      child: FRow(
        children: [
          _buildInput(
            readOnly: true,
            onTap: () async {
              router.dialog(
                () => VersionListDialog(
                  deviceVersionType: versionType,
                  isSelectedVersion: inputText,
                  versionListCallback: versionListCallback,
                ),
              );
            },
            textInput: inputText,
          ),
          FContainer(
            margin: EdgeInsets.only(left: 10),
            child: _buildCommonButton(
              i18nBook.common.add.t,
              () {
                router.dialog(
                  () => AddVersionDialog(
                    deviceVersionType: versionType,
                    versionAddCallback: versionAddCallback,
                    addVersionTitle: addVersionTitle,
                  ),
                );
              },
            ),
          )
        ],
      ),
    );
  }

  FWidget _buildUpload() {
    return FExpanded(
      child: FRow(
        children: [
          FObx(
            () => _buildInput(
              readOnly: true,
              textInput: controller.state.updateFileName,
            ),
          ),
          FContainer(
            margin: EdgeInsets.only(left: 10),
            child: _buildCommonButton(
              i18nBook.common.add.t,
              () async {
                controller.state.uploadProgress = 0;
                try {
                  // 这边是大文件上传暂时没有取消上传的机制
                  file = await rpc.storage.pickAndUploadFile(
                    onSelectedFile: (name) {
                      controller.state.updateFileName = name;
                    },
                  );
                } catch (e) {}
              },
            ),
          )
        ],
      ),
    );
  }

  /// 二次确认弹窗 是否离开
  void _confirmLeave() {
    if (controller.state.uploadingUpdatePackage) {
      var container = JsListener();
      FConfirmAlert.show(
        context: Get.context!,
        title: i18nBook.common.tip.t,
        subTitle: i18nBook.remoteControl.confirmLeaveDuringUpload.t,
        confrimLabel: i18nBook.common.confirm.t,
        cancelLabel: i18nBook.common.cancel.t,
        onConfirm: () async {
          router.back();
        },
        businessParent: container,
      );
    } else {
      router.back();
    }
  }

  void _onProcessChange(v) {
    controller.state.uploadProgress = v;
    onProcessChange.emit(this, v);
    _isUploadding = true;
  }

  void _initData() {
    if (widget.packageData != null) {
      controller.state.applySoftwareVersion =
          widget.packageData?.softwareVersion ?? '';
      controller.state.applySystemVersion = widget.packageData?.osVersion ?? '';
      controller.state.description = widget.packageData?.description ?? '';
    } else {
      controller.state.applySoftwareVersion = '';
      controller.state.applySystemVersion = '';
      controller.state.description = '';
    }
  }
}
