import 'package:fis_common/index.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:fis_ui/values/font_sizes.dart';
import 'package:fis_ui/widgets/progressbar/progressbar.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/managers/interfaces/remote_controller.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/controller.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:universal_html/html.dart';
import 'package:fis_common/logger/logger.dart';

class ProgressLinear extends FStatefulWidget implements FPage {
  final String deviceCode;
  final bool isLogs;
  final String? packageCode;
  const ProgressLinear({
    super.key,
    required this.deviceCode,
    this.packageCode,
    this.isLogs = false,
  });

  @override
  String get pageName => 'ProgressLinear';

  @override
  FState<ProgressLinear> createState() => _ProgressLinearState();
}

class _ProgressLinearState extends FState<ProgressLinear> {
  static TextStyle _textStyle = TextStyle(
    color: Colors.white,
    fontSize: FFontSizes.BODY,
  );
  final remoteControllerManager = Get.find<IRemoteControllerManager>();
  final _controller = Get.find<DeviceLiveListController>();
  bool _isShowProgress = false;
  bool isShell = FPlatform.isMacOS || FPlatform.isWindows;

  // int progress = 0;
  String statusTitle = '';
  bool isDownloadError = false;
  String fileToken = '';
  String fileName = '';
  String _packageCode = '';

  @override
  FWidget build(BuildContext context) {
    if (_isShowProgress || _controller.state.deviceProgress != 0)
      return _buildProgress();
    else if (widget.isLogs &&
        _controller.state.currentDeviceCode == widget.deviceCode)
      return FSizedBox(
        child: FText(
          i18nBook.remoteControl.getUltrasoundLog.t,
          style: _textStyle,
        ),
      );
    else if (!widget.isLogs &&
        _controller.state.currentDeviceCode == widget.deviceCode)
      return FSizedBox(
        child: FText(
          i18nBook.remoteControl.pushPackage.t,
          style: _textStyle,
        ),
      );
    else
      return FSizedBox();
  }

  @override
  void dispose() {
    remoteControllerManager.onDeviceDownloadPatchProgressToUser
        .removeListener(_onDeviceDownloadPatchProgressToUser);
    remoteControllerManager.onGetRemoteLogToClient
        .removeListener(_onGetRemoteLogToClient);

    super.dispose();
  }

  @override
  void initState() {
    _controller.state.deviceProgress = 0;
    _packageCode = widget.packageCode ?? '';
    statusTitle = '';
    _isShowProgress = false;
    isDownloadError = false;
    fileToken = '';
    remoteControllerManager.onDeviceDownloadPatchProgressToUser
        .addListener(_onDeviceDownloadPatchProgressToUser);
    remoteControllerManager.onGetRemoteLogToClient
        .addListener(_onGetRemoteLogToClient);

    super.initState();
  }

  FWidget _buildProgress() {
    return FColumn(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        FContainer(
          padding: EdgeInsets.only(
            top: 2,
            left: 10,
            right: 10,
            bottom: 5,
          ),
          child: FRow(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              FText(
                statusTitle,
                style: TextStyle(
                  fontSize: FFontSizes.BODY,
                  color: Colors.white,
                ),
              ),
              FRow(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  if (!isDownloadError) ...[
                    FObx(
                      () {
                        if (isShell &&
                            _controller.state.deviceProgress == 100) {
                          Future.delayed(Duration(milliseconds: 1500), () {
                            _controller.state.isGettingLogs = false;
                            _controller.state.isPushDevicePatch = false;
                            setState(() {});
                          });
                        }
                        return FText(
                          '${_controller.state.deviceProgress}%',
                          style: TextStyle(
                            fontSize: FFontSizes.BODY,
                            color: Colors.white,
                          ),
                        );
                      },
                    ),
                    FGestureDetector(
                      onTap: () async {
                        if (widget.isLogs) {
                          await _controller.userCancelLogDownloadAsync(
                            deviceCode: widget.deviceCode,
                          );
                        } else {
                          await _controller.pushDevicePatchAsync(
                            deviceCode: widget.deviceCode,
                            patchCode: _packageCode,
                            pushEnum: PushDevicePatchEnum.Cancel,
                          );
                          _controller.state.isPushDevicePatch = false;
                        }
                      },
                      businessParent: this.widget,
                      name: '',
                      child: FText(
                        i18nBook.common.cancel.t,
                        style: TextStyle(
                          color: Colors.blue,
                          fontSize: FFontSizes.BODY,
                          decoration: TextDecoration.underline, // 给文字添加下划线
                        ),
                      ),
                    )
                  ] else
                    FInkWell(
                      child: FIcon(
                        Icons.close,
                        size: FFontSizes.BODY,
                      ),
                      onTap: () {
                        _controller.state.isPushDevicePatch = false;
                      },
                    )
                ],
              ),
            ],
          ),
        ),
        FObx(() {
          return FProgeressbar(
            percentage: double.parse(
              (_controller.state.deviceProgress / 100).toStringAsFixed(2),
            ),
            animation: true,
            animationDuration: 100,
            animateFromLastPercentage: true,
            alignment: MainAxisAlignment.spaceBetween,
            backgroundColor: Colors.black26,
            progressBarColor: Colors.blue,
          );
        }),
      ],
    );
  }

  Future<void> _downloadFileFromWeb() async {
    final response = await http.get(Uri.parse(fileToken));
    final bytes = response.bodyBytes;
    if (isShell) {
      await rpc.platform.downloadBigFile(
        fileToken,
        "@ShellDomain@\\Logs\\TerminalLogs\\$fileName.zip",
      );
    } else {
      final blob = Blob([bytes], 'application/zip');
      final link = AnchorElement(href: Url.createObjectUrlFromBlob(blob));
      link.download = fileName;
      link.click();
    }
  }

  String _getStatusTitle(RemoteDeviceStateEnum remoteDeviceState) {
    switch (remoteDeviceState) {
      case RemoteDeviceStateEnum.Success:
        if (_controller.state.deviceProgress == 100) {
          Future.delayed(Duration(milliseconds: 1500), () {
            _controller.state.isGettingLogs = false;
            _controller.state.isPushDevicePatch = false;
            setState(() {});
          });
        }
        if (widget.isLogs) {
          _downloadFileFromWeb();
          if (isShell && _controller.state.deviceProgress == 50) {
            return i18nBook.remedical.downloadingLogs.t;
          } else {
            return i18nBook.remoteControl.getLogsSuccess.t;
          }
        } else
          return i18nBook.remoteControl.pushPackageSuccess.t;
      case RemoteDeviceStateEnum.Fail:
        return i18nBook.remoteControl.pushFailed.t;
      case RemoteDeviceStateEnum.DownloadPatchFail:
        return i18nBook.remoteControl.pushPackageFailed.t;
      case RemoteDeviceStateEnum.CancelDownloadPatch:

        /// 取消下载安装包成功
        Future.delayed(Duration(milliseconds: 1500), () {
          _controller.state.isPushDevicePatch = false;
          setState(() {});
        });

        return i18nBook.remoteControl.cancelDownloadInstallPackSuccess.t;
      case RemoteDeviceStateEnum.DownloadPatching:
        if (widget.isLogs) return i18nBook.remedical.RetrievingLog.t;
        return i18nBook.remoteControl.updatingPush.t;

      case RemoteDeviceStateEnum.LogDownloaddFail:
        return i18nBook.remoteControl.deviceLogsDownloadingFailed.t;
      case RemoteDeviceStateEnum.DeviceCancelLogDownload:

        /// 取消下载安装包成功
        Future.delayed(Duration(milliseconds: 1500), () {
          _controller.state.isGettingLogs = false;
          setState(() {});
        });

        return i18nBook.remoteControl.cancelDownloadLogSuccess.t;
      // return i18nBook.remoteControl.deviceLogsCancelFailed.t;
      case RemoteDeviceStateEnum.DeviceDisconnect:
        return i18nBook.remoteControl.deviceActiveDisconnection.t;
      case RemoteDeviceStateEnum.DeviceTimeOutDisconnect:
        return i18nBook.remoteControl.deviceTimeoutDisconnection.t;
      default:
        return i18nBook.remoteControl.pushFailed.t;
    }
  }

  _onDeviceDownloadPatchProgressToUser(
      Object a, DeviceDownloadPatchProgressToUserNotification e) {
    setState(() {
      if (e.deviceCode == widget.deviceCode) {
        if (e.remoteDeviceState == RemoteDeviceStateEnum.DownloadPatching) {
          setState(() {
            _isShowProgress = true;
          });
        }
        _controller.state.deviceProgress = e.progress;
        if (e.patchCode.isNotNullOrEmpty) {
          _packageCode = e.patchCode!;
        }

        logger.i(
            "Receive package code on DeviceDownloadPatchProgressToUserNotification patch code is- ${e.patchCode}");
        statusTitle = _getStatusTitle(e.remoteDeviceState);
        if ([
          RemoteDeviceStateEnum.DownloadPatchFail,
          RemoteDeviceStateEnum.DeviceTimeOutDisconnect,
        ].contains(e.remoteDeviceState)) {
          isDownloadError = true;
        }
      }
    });
  }

  _onGetRemoteLogToClient(Object a, GetRemoteLogToClientNotification e) {
    if (e.deviceCode == widget.deviceCode) {
      _isShowProgress = true;
      if (e.logFileToken?.isNotEmpty ?? false) {
        fileToken = e.logFileToken ?? '';
      }
      if (e.fileName?.isNotEmpty ?? false) {
        fileName = e.fileName ?? _runLogsFileName();
      }
      _packageCode = e.code ?? '';

      if (isShell) {
        _controller.state.deviceProgress = (e.rate * 0.5).toInt();
      } else {
        _controller.state.deviceProgress = e.rate;
      }
      statusTitle = _getStatusTitle(e.remoteDeviceState);
      setState(() {});
    }
  }

  String _runLogsFileName() {
    DateFormat format = DateFormat("yyyMMddHHmmss");
    var dateStr = format.format(DateTime.now().toLocal());
    var fileName = "[$dateStr]-${i18nBook.setting.runLog.t}.zip";
    return fileName;
  }
}
