import 'dart:async';
import 'dart:math';

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:flutter/material.dart';
import 'package:fis_common/env/env.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/router.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/device.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/controller.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/state.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/widgets/get_device_logs_dialog.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/widgets/printer_settings_dialog.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/widgets/progress_linear.dart';
import 'package:flyinsono/views/common/device_live/device_live_list/widgets/system_settings_dialog.dart';
import 'package:flyinsono/views/desktop/device_live/device_live_list/widgets/management_dialog.dart';
import 'package:get/get.dart';

class RemoteMainTenance extends FStatefulWidget implements FPage {
  const RemoteMainTenance({
    super.key,
    required this.index,
    required this.width,
    required this.height,
  });

  /// 索引
  final int index;
  final double width;
  final double height;
  @override
  FState<RemoteMainTenance> createState() => _RemoteMainTenanceState();

  @override
  String get pageName => 'RemoteMainTenance';
}

/// 连接按钮状态
enum ConnectIconStatus {
  /// 无状态
  None,

  /// 连接中
  Connecting,

  /// 断开中
  Disconnecting,

  /// 连接失败
  ConnectFail,
}

class _RemoteMainTenanceState extends FState<RemoteMainTenance>
    with TickerProviderStateMixin {
  static TextStyle _textStyle = TextStyle(
    color: Colors.white,
    fontSize: FFontSizes.BODY,
  );

  final deviceManager = Get.find<IDeviceManager>();
  final _controller = Get.find<DeviceLiveListController>();
  final liveConsultationManager = Get.find<ILiveConsultationManager>();
  final remoteControllerManager = Get.find<IRemoteControllerManager>();
  final networkErrorHandlerManager = Get.find<INetworkErrorHandlerManager>();
  String _patchCode = "";

  late DeviceExtendInfoDTO _dto = _controller.state.deviceList[widget.index];
  late DeviceRemoteControllerInfos _deviceRemoteControllerInfos =
      DeviceRemoteControllerInfos(
    deviceExtendInfo: _dto,
    connectStatus: ConnectStatusEnum.UnConnect,
  );
  late AnimationController _animationController;
  late Animation<double> _pageFlipAnimation;

  ConnectIconStatus connectPromp = ConnectIconStatus.None;

  bool get isWaitConnect =>
      _deviceRemoteControllerInfos.connectStatus ==
      ConnectStatusEnum.WaitConnect;
  bool get isCompleteConnect =>
      _deviceRemoteControllerInfos.connectStatus ==
      ConnectStatusEnum.CompleteConnect;
  bool get isOnline => _dto.isOnline == true;
  bool get isCurrentDevice =>
      _controller.state.currentDeviceCode == _dto.deviceCode;
  bool get isHover => _controller.state.isShowDeviceDetailIndex == widget.index;

  @override
  void initState() {
    super.initState();
    remoteControllerManager.onConnectStatusToClient
        .addListener(_onConnectStatusToClient);
    remoteControllerManager.onDeviceDisconnectRemote
        .addListener(_onDeviceDisconnectRemote);
    remoteControllerManager.onDeviceRejectRemoteControl
        .addListener(_onDeviceRejectRemoteControl);

    /// 网络断开
    networkErrorHandlerManager.onNetworkInterruption
        .addListener(_onNetworkInterruption);
    _animationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 500),
    );

    _pageFlipAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    ));
  }

  @override
  void dispose() {
    super.dispose();
    remoteControllerManager.onConnectStatusToClient
        .removeListener(_onConnectStatusToClient);
    remoteControllerManager.onDeviceDisconnectRemote
        .removeListener(_onDeviceDisconnectRemote);
    remoteControllerManager.onDeviceRejectRemoteControl
        .removeListener(_onDeviceRejectRemoteControl);

    /// 网络断开
    networkErrorHandlerManager.onNetworkInterruption
        .removeListener(_onNetworkInterruption);
    _animationController.dispose();
  }

  void _onNetworkInterruption(sender, e) {
    setState(() {});

    // _controller.closeHeartbeat();
    _deviceRemoteControllerInfos.connectStatus =
        ConnectStatusEnum.CompleteDisconnect;
    _animationController.reverse();
  }

  @override
  FWidget build(BuildContext context) {
    return FInkWell(
      child: FObx(() {
        _dto = _controller.state.deviceList[widget.index];
        final isConnect = _controller.state.remoteControlList
            .any((item) => item.deviceCode == _dto.deviceCode);
        _deviceRemoteControllerInfos = DeviceRemoteControllerInfos(
          deviceExtendInfo: _dto,
          connectStatus: isConnect
              ? ConnectStatusEnum.CompleteConnect
              : ConnectStatusEnum.UnConnect,
        );
        if (isConnect) {
          _animationController.forward();
        }
        return _buildRemoteMaintenanceModule(widget.width, widget.height);
      }),
      onTap: () {
        print('阻止事件冒泡');
      },
    );
  }

  /// 远程维护模块
  FWidget _buildRemoteMaintenanceModule(double width, double height) {
    if (isOnline && !isHover) {
      return FContainer(
        decoration: BoxDecoration(
          border: Border(
            top: BorderSide(
              color: Color.fromRGBO(245, 245, 245, 1),
              width: 0.5,
            ),
          ),
          color: Colors.grey,
        ),
        width: width,
        height: isCompleteConnect ? height : 41,
        child: FColumn(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            if (isCompleteConnect) ...[
              FContainer(
                margin: EdgeInsets.only(
                  left: 15,
                  top: 5,
                ),
                child: FText(
                  '${_dto.displayName}',
                  style: _textStyle,
                ),
              ),
              FExpanded(
                child: QuickFWidget(
                  AnimatedBuilder(
                    animation: _pageFlipAnimation,
                    builder: (context, child) {
                      return isCompleteConnect
                          ? Transform(
                              alignment: Alignment.center,
                              transform: (Matrix4.identity()
                                ..setEntry(3, 2, 0.001)
                                // 确保参数类型是 double
                                ..rotateY(
                                    (1 - _pageFlipAnimation.value) * pi / 2)),
                              child: _buildButtonGroup(),
                            )
                          : FSizedBox();
                    },
                  ),
                ),
              )
            ],
            FContainer(
              padding: EdgeInsets.symmetric(horizontal: 15),
              child: FRow(
                children: [
                  FText(
                    i18nBook.remoteControl.remoteControl.t,
                    style: _textStyle,
                  ),
                  FSwitch(
                    value: isCompleteConnect,
                    onChanged: (value) => _changeDeviceStatus(value),
                  ),
                  _buildConnectStatusIcon(connectPromp),
                ],
              ),
            ),
          ],
        ),
      );
    } else
      return FSizedBox();
  }

  FWidget _buildConnectStatusIcon(ConnectIconStatus connectPromp) {
    switch (connectPromp) {
      case ConnectIconStatus.Connecting:
      case ConnectIconStatus.Disconnecting:
        return FCenter(
          child: FSizedBox(
            width: 20,
            height: 20,
            child: FCircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation(Colors.white),
              strokeWidth: 3,
            ),
          ),
        );
      case ConnectIconStatus.ConnectFail:
        return FSizedBox(
          child: FCenter(
            child: FSizedBox(
              width: 20,
              height: 20,
              child: FIcon(
                Icons.highlight_off,
                color: Colors.white,
              ),
            ),
          ),
        );
      default:
        return FSizedBox();
    }
  }

  FWidget _buildProgress(FWidget progressChild) {
    return FContainer(
      height: 38,
      alignment: Alignment.center,
      child: progressChild,
      margin: EdgeInsets.symmetric(
        horizontal: 4,
      ),
    );
  }

  /// 按钮组
  FWidget _buildButtonGroup() {
    return FContainer(
      padding: EdgeInsets.symmetric(horizontal: 6),
      child: FColumn(
        children: [
          FObx(() {
            if (_controller.state.isPushDevicePatch && isCurrentDevice)
              return _buildProgress(
                ProgressLinear(
                  deviceCode: _dto.deviceCode ?? '',
                  packageCode: _controller.pushPatchCode,
                ),
              );
            else
              return _buildTextOutlinedButton(
                i18nBook.remoteControl.updatePush.t,
                () => _pushUpdatePackage(),
                Icons.move_up_rounded,
              );
          }),
          FObx(() {
            if (_controller.state.isGettingLogs && isCurrentDevice)
              return _buildProgress(
                ProgressLinear(
                  deviceCode: _dto.deviceCode ?? '',
                  isLogs: true,
                ),
              );
            else {
              final exportLogBtn = _buildTextOutlinedButton(
                i18nBook.remoteControl.getLog.t,
                () => _getLogs(),
                Icons.grading_outlined,
              );
              if (FPlatform.isMacOS || FPlatform.isWindows) {
                if (_controller.state.hasDownloadedLogs &&
                    !CartSystemPlatform.isCartSystemVersion) {
                  return FRow(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      FExpanded(child: exportLogBtn),
                      FGestureDetector(
                        onTap: () {
                          _controller.openLogDownloadPath();
                        },
                        child: FIcon(Icons.search),
                        businessParent: FVirtualPageWidget("RemoteMainTenance"),
                        name: "OpenDeviceLogPath",
                      ),
                      FSizedBox(width: 8),
                    ],
                  );
                }
              }
              return exportLogBtn;
            }
          }),
          if (_dto.deviceType == 'US')
            _buildTextOutlinedButton(
              i18nBook.remoteControl.remoteParameterAdjustment.t,
              () async {
                await _controller.startRemoteController(_dto);
              },
              Icons.control_camera_rounded,
            ),
          if (_dto.deviceType == 'US')
            _buildTextOutlinedButton(
              i18nBook.remoteControl.systemSettings.t,
              () => openSystemSettingsDialog(),
              Icons.settings_system_daydream_outlined,
            ),
          if (_dto.deviceType == 'US')
            _buildTextOutlinedButton(
              i18nBook.remoteControl.printerSettings.t,
              () => openPrinterSettings(),
              Icons.local_printshop_outlined,
            ),
          if (_dto.deviceType != 'US' && _dto.isCanRestart)
            _buildTextOutlinedButton(
              i18nBook.remoteControl.reboot.t,
              () async {
                _controller.restartDeviceAsync(
                  deviceCode: _dto.deviceCode,
                );
                _deviceRemoteControllerInfos = DeviceRemoteControllerInfos(
                  deviceExtendInfo: _dto,
                  connectStatus: ConnectStatusEnum.UnConnect,
                );
                setState(() {});
              },
              Icons.refresh_rounded,
            ),
        ],
      ),
    );
  }

  /// 边框按钮
  FWidget _buildTextOutlinedButton(
    String textString,
    Function onPressed,
    IconData iconData,
  ) {
    return FContainer(
      margin: EdgeInsets.only(top: 10, left: 10, right: 10),
      child: FRow(
        children: [
          FExpanded(
            child: FElevatedButtonWithIcon(
              businessParent: this.widget,
              name: textString,
              icon: FIcon(
                iconData,
                size: 20,
              ),
              onPressed: () => onPressed.call(),
              label: FText(
                textString,
                textAlign: TextAlign.center,
                style: _textStyle,
              ),
            ),
          ),
        ],
      ),
    );
  }

  /// 设备端连接通知
  void _onConnectStatusToClient(Object a, ConnectStatusToClientNotification e) {
    setState(() {
      if (e.deviceCode == _dto.deviceCode) {
        if (e.remoteDeviceState == RemoteDeviceStateEnum.Success) {
          _deviceRemoteControllerInfos.connectStatus =
              ConnectStatusEnum.CompleteConnect;
          connectPromp = ConnectIconStatus.None;
        }
        if (e.remoteDeviceState == RemoteDeviceStateEnum.Fail) {
          connectPromp = ConnectIconStatus.ConnectFail;
        }
      }
    });
  }

  /// 切换超声机的状态
  void _changeDeviceStatus(bool value) async {
    _dto = _controller.state.deviceList[widget.index];

    if (value) {
      _initConnectStatus();
      _deviceRemoteControllerInfos.connectStatus =
          ConnectStatusEnum.WaitConnect;
      connectPromp = ConnectIconStatus.Connecting;
      liveConsultationManager.cacheDeviceParametersNotification = null;
      final result = await _controller.applyRemoteConnectionAsync(
        deviceCode: _dto.deviceCode ?? '',
      );
      if (!result) {
        _deviceRemoteControllerInfos.connectStatus =
            ConnectStatusEnum.UnConnect;
        connectPromp = ConnectIconStatus.None;
      }
      _animationController.forward();
    } else {
      _controller.closeHeartbeat();
      _controller.pushDevicePatchAsync(
        deviceCode: _dto.deviceCode ?? '',
        patchCode: _patchCode,
        pushEnum: PushDevicePatchEnum.Cancel,
      );
      connectPromp = ConnectIconStatus.Disconnecting;
      _controller.applyRemoteConnectionAsync(
        deviceCode: _dto.deviceCode ?? '',
        controlType: ControlDeviceParameterEnum.End,
      );
      _animationController.reverse();
    }
    setState(() {});
  }

  // 客户端初始化连接状态
  void _initConnectStatus() {
    if (_dto.deviceCode == _controller.state.currentDeviceCode) {
      _controller.state.isPushDevicePatch = false;
      _controller.state.isGettingLogs = false;
    }
  }

  /// 设备端断开连接的通知
  void _onDeviceDisconnectRemote(
      Object a, DeviceDisconnectRemoteControlNotification e) {
    _controller.getDeviceStateListByTokenAsync();
    if (e.deviceCode == _dto.deviceCode) {
      if (e.remoteDeviceState ==
          RemoteDeviceStateEnum.DeviceTimeOutDisconnect) {
        PromptBox.toast(i18nBook.remoteControl.deviceTimeoutDisconnection.t);
      } else if (e.remoteDeviceState ==
          RemoteDeviceStateEnum.UserTimeOutDisconnect) {
        PromptBox.toast(i18nBook.remoteControl.clientTimeout.t);
      } else if (e.remoteDeviceState ==
          RemoteDeviceStateEnum.DeviceDisconnect) {
        PromptBox.toast(i18nBook.remoteControl.deviceDisconnected.t);
        Future.delayed(Duration(milliseconds: 1000), () {
          _controller.reloadList();
        });
      }

      connectPromp = ConnectIconStatus.None;
      _deviceRemoteControllerInfos.connectStatus =
          ConnectStatusEnum.CompleteDisconnect;
    }
    setState(() {});
  }

  /// 远程推送包
  void _pushUpdatePackage() {
    _controller.findPushDevicePatchPagesAsync(_dto.deviceCode, '',
        _dto.deviceType == 'US' ? ["US", "FISSDK"] : ["sonopost"]);
    _controller.state.currentDeviceCode = _dto.deviceCode!;
    router.dialog(
      () => FObx(
        () => ManagementDialog(
          dialogName: i18nBook.remoteControl.selectUpdatePackage.t,
          tableColumn: PackageTableColumn.updatePackageList(false),
          tableData: _controller.state.devicePatchList,
          onMakeSure: (DevicePatchDTO value) async {
            final result = await _controller.pushDevicePatchAsync(
              deviceCode: _dto.deviceCode ?? '',
              patchCode: value.code ?? '',
            );
            if (result) {
              _patchCode = value.code ?? '';
              _controller.state.isPushDevicePatch = true;
              _controller.state.isGettingLogs = false;
            }
            router.back();
          },
          tableLoading: _controller.state.tableLoading,
          onRefresh: (value) {
            _controller.findPushDevicePatchPagesAsync(
              _dto.deviceCode,
              value,
              _dto.deviceType == 'US' ? ["US", "FISSDK"] : ["sonopost"],
            );
          },
        ),
      ),
      dismissible: false,
    );
  }

  /// 获取日志
  void _getLogs() {
    _controller.state.currentDeviceCode = _dto.deviceCode!;
    router.dialog(
      () => DeviceLogsDialog(
        deviceCode: _dto.deviceCode ?? '',
      ),
      dismissible: false,
    );
  }

  /// 打开系统设置
  void openSystemSettingsDialog() {
    _controller.sendCommandToDeviceAsync(
      deviceCode: _dto.deviceCode ?? '',
    );
    router.dialog(
      () => SystemSettingsDialog(deviceCode: _dto.deviceCode ?? ''),
      dismissible: false,
    );
  }

  void openPrinterSettings() {
    _controller.setDevicePrinterAsync(
      deviceCode: _dto.deviceCode,
    );
    router.dialog(
      () => PrinterSettingsDialog(
        deviceCode: _dto.deviceCode ?? '',
      ),
      dismissible: false,
    );
  }

  void _onDeviceRejectRemoteControl(
      Object a, DeviceRejectRemoteControlNotification e) {
    setState(() {
      if (e.deviceCode == _dto.deviceCode) {
        connectPromp = ConnectIconStatus.None;
        PromptBox.toast(i18nBook.remoteControl.probeControlOff.t);
      }
    });
  }
}

class DeviceRemoteControllerInfos {
  DeviceRemoteControllerInfos({
    this.deviceExtendInfo,
    this.connectStatus,
  });

  DeviceExtendInfoDTO? deviceExtendInfo;
  ConnectStatusEnum? connectStatus;
}
