import 'dart:async';

import 'package:fis_common/env/env.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_common/web/shell_api_hepler.dart';
import 'package:fis_ui/define.dart';
import 'package:fis_ui/interface/interactive_container.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:get/get.dart';

/// for temporary preview only!!!
class QuickFWidget extends StatelessWidget implements FWidget {
  const QuickFWidget(this.child, {Key? key}) : super(key: key);
  final Widget child;
  @override
  Widget build(BuildContext context) => child;
}

typedef FWidgetCallback = FWidget Function();

typedef AsyncVoidCallback = Future<void> Function();

class FObx extends Obx implements FWidget {
  FObx(FWidgetCallback builder) : super(builder);
}

extension RxExt<T> on Rx<T> {
  /// 更新值
  void updateValue(T newValue) {
    if (newValue != value) {
      value = newValue;
    }
  }
}

/// 基于流驱动更新的数据实例
class FRx<T> extends Rx<T> {
  FRx(T initial) : super(initial);
}

/// 基于流驱动更新的Bool型数据实例
class FRxBool extends Rx<bool> {
  FRxBool(super.initial);
}

/// 基于流驱动更新的数组数据实例
class FRxList<T> extends RxList<T> {
  FRxList([List<T> initial = const []]) : super(initial);
}

/// 基于流驱动更新的字典数据实例
class FRxMap<K, V> extends RxMap<K, V> {
  FRxMap([Map<K, V> initial = const {}]) : super(initial);
}

/// 基于流驱动更新的集合数据实例
class FRxSet<T> extends RxSet<T> {
  FRxSet([Set<T> initial = const {}]) : super(initial);
}

/// 基于流驱动更新的数据实例[可空]
class FRxn<T> extends FRx<T?> {
  FRxn([T? initial]) : super(initial);

  /// 更新值
  void updateValue(T? newValue) {
    if (newValue != value) {
      value = newValue;
    }
  }
}

abstract class FisView<T> extends GetView<T> implements FWidget {
  const FisView({Key? key}) : super(key: key);
  @override
  FWidget build(BuildContext context);
}

/// 虚拟页面组件
class FVirtualPageWidget extends Container implements FInteractiveContainer {
  /// 仅限全局场景使用
  static final FVirtualPageWidget global = FVirtualPageWidget("Global");

  late final String _pageName;

  FVirtualPageWidget(String name) {
    _pageName = name;
  }

  @override
  String get pageName => _pageName;
}

abstract class FControllerBase extends GetxController {
  final AppState appState = Store.app;

  bool get busy => appState.busy;
  set busy(v) => appState.busy = v;

  void setBusy(String text) => appState.setBusy(text);

  void cancelBusy() => busy = false;

  Future<void> busyHandle(AsyncVoidCallback callback, {String? text}) async {
    if (text != null) {
      setBusy(text);
    } else {
      busy = true;
    }
    try {
      await callback();
    } catch (e) {
      logger.e("Unhandled page busy error", e);
    }
    busy = false;
  }

  /// 执行耗时操作
  ///
  /// - 此操作可能会阻塞线程
  ///
  /// - 需要全局Loading
  Future<void> executeTimeConsumingAction(Future<void> Function() action) {
    final completer = Completer<void>();
    busy = true;
    Store.app.lockBusy = true;
    Future.delayed(const Duration(milliseconds: 500), () async {
      // 会阻塞线程的操作，先让LoadingUI显示后再执行
      try {
        await action.call();
      } catch (e) {
        logger.e("FControllerBase executeTimeConsumingAction error", e);
      }
      Store.app.lockBusy = false;
      busy = false;
      completer.complete();
    });
    return completer.future;
  }

  @override
  void onReady() {
    super.onReady();
    busy = true;
    onLoad().then((_) {
      busy = false;
    });
  }

  @protected
  Future<void> onLoad() async {}

  /// 进入全屏
  void enterFullScreen() async {
    if (FPlatform.isIOS || FPlatform.isAndroid) {
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.landscapeLeft,
        DeviceOrientation.landscapeRight,
      ]);
      SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
      SystemChrome.setSystemUIChangeCallback((systemOverlaysAreVisible) async {
        await Future.delayed(const Duration(seconds: 1));
        SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
      });
    }
  }

  /// 退出全屏
  void exitFullScreen() async {
    if (FPlatform.isAndroid || FPlatform.isIOS) {
      // 恢复竖屏
      await SystemChrome.setPreferredOrientations(
        [
          DeviceOrientation.portraitUp, // 竖屏 Portrait 模式
          DeviceOrientation.portraitDown,
        ],
      );
      SystemChrome.setEnabledSystemUIMode(
        SystemUiMode.manual,
        overlays: SystemUiOverlay.values,
      );
      SystemChrome.setSystemUIChangeCallback((systemOverlaysAreVisible) async {
        // do nothing
      });
    }
  }
}

class FisBuilder<T extends GetxController> extends GetBuilder<T>
    implements FWidget {
  FisBuilder({
    Key? key,
    T? init,
    bool global = true,
    required GetControllerBuilder<T> builder,
    bool autoRemove = true,
    bool assignId = false,
    Object Function(T value)? filter,
    String? tag,
    void Function(GetBuilderState<T> state)? initState,
    void Function(GetBuilderState<T>)? dispose,
    didChangeDependencies,
    Object? id,
    void Function(GetBuilder oldWidget, GetBuilderState<T> state)?
        didUpdateWidget,
  }) : super(
          key: key,
          init: init,
          global: global,
          builder: builder,
          autoRemove: autoRemove,
          assignId: assignId,
          initState: initState,
          filter: filter,
          tag: tag,
          dispose: dispose,
          id: id,
          didChangeDependencies: didChangeDependencies,
          didUpdateWidget: didUpdateWidget,
        );
}

///Todo:finlay 推车相关
class CartSystemPlatform {
  static bool _value = false;

  static bool _valueWithOldPlatform = false;

  static bool specialOnceOperationFlag = false;
  static bool get isCartSystemVersion => _value;
  static bool get isCartSystemWithOldPlatform => _valueWithOldPlatform;

  ///当前环境是否是推车
  static Future<void> getIsCartSystemVersion() async {
    try {
      if (FPlatform.isWindows) {
        _value = await ShellApiHelper.call("getIsCartSystemVersion", []);
      }
    } catch (e) {
      logger.e("getIsCartSystemVersion error", e);
    }
  }

  ///当前环境是否是老推车环境
  static Future<void> getIsCartSystemVersionWithOldPlatform() async {
    try {
      if (FPlatform.isWindows) {
        _valueWithOldPlatform = await ShellApiHelper.call(
            "getIsCartSystemVersionWithOldPlatform", []);
      }
    } catch (e) {
      logger.e("getIsCartSystemVersionWithOldPlatform error", e);
    }
  }

  ///推送当前服务器地址到盒子
  static Future<void> synchServerAddressToSonopost(
      String host, String port) async {
    try {
      if (FPlatform.isWindows && isCartSystemVersion) {
        await ShellApiHelper.call('switchLoginServer', [host, port]);
      }
    } catch (e) {
      logger.e("switchLoginServer error", e);
    }
  }
}
