import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/router/types.dart';
import 'package:get/get.dart';

const _barrierColor = Color(0x80000000);
const _barrierFreeColor = Colors.transparent;

///FIS的路由配置实例
class FRouter {
  FRouter._();

  final Map<int, String> _navCurrentNames = {};

  List<FRouteSetting<dynamic>>? _routes;

  /// 当前路由
  Route<dynamic>? get current => Get.rawRoute;

  /// 当前路由名
  String? get currentName => Get.currentRoute;

  /// 路由表
  List<FRouteSetting<dynamic>> get routes => _routes!;

  void setRoutes(List<FRouteSetting<dynamic>> routeList) {
    _routes ??= routeList;
  }

  /// 跳转到新路由页面
  ///
  /// [name] 路由Name
  ///
  /// [parameters] 传参
  ///
  /// [id] 路由导航Id
  Future<T?>? to<T>(
    String name, {
    Map<String, String>? parameters,
    int? id,
  }) {
    // _recordNavCurrentName(id, name);
    if (id != null && parameters != null) {
      _RouterArguments.routerArguments[id] = parameters;
    }
    return Get.toNamed<T>(
      name,
      parameters: id == null ? parameters : null,
      arguments: id == null ? null : parameters,
      id: id,
    );
  }

  /// 使用新路由页面覆盖当前路由页面
  ///
  /// [name] 路由Name
  ///
  /// [parameters] 传参
  ///
  /// [id] 路由导航Id
  Future<T?>? replace<T>(
    String name, {
    Map<String, String>? parameters,
    int? id,
  }) {
    if (id != null && parameters != null) {
      _RouterArguments.routerArguments[id] = parameters;
    }
    // _recordNavCurrentName(id, name);
    // off 和 offAndTo 的区别：
    // off只有当前页到下一页的推进动画
    // offAndTo会显示从上一页到下一页的动画
    return Get.offNamed<T>(
      name,
      parameters: id == null ? parameters : null,
      arguments: id == null ? null : parameters,
      id: id,
    );
  }

  /// 清除所有历史路由并跳转到新路由页面
  ///
  /// [name] 路由Name
  ///
  /// [parameters] 传参
  ///
  /// [id] 路由导航Id
  Future<T?>? offAll<T>(
    String name, {
    Map<String, String>? parameters,
    int? id,
  }) {
    // _recordNavCurrentName(id, name);
    return Get.offAllNamed<T>(
      name,
      parameters: id == null ? parameters : null,
      arguments: id == null ? null : parameters,
      id: id,
    );
  }

  /// 返回上一页
  ///
  /// [result] 结果
  ///
  /// [id] 路由导航Id
  void back<T>({T? result, int? id}) {
    Get.back<T>(result: result, id: id);
  }

  /// 弹窗打开页面
  ///
  /// [pageBuilder] 页面生成方法
  ///
  /// [binding] 依赖绑定
  ///
  /// [dismissible] 是否可点击罩层关闭
  ///
  /// [isShowBarrier] 是否展示遮罩层
  ///
  /// [parameters] 传参
  ///
  /// [transitionDuration] 过渡时长
  ///
  /// [transitionCurve] 过渡样式曲线
  ///
  /// [id] 导航Id
  Future<T?>? dialog<T>(
    FWidget Function() pageBuilder, {
    Bindings? binding,
    bool? dismissible,
    bool? isShowBarrier = true,
    Map<String, String>? parameters,
    Duration? transitionDuration,
    Curve? transitionCurve,
    int? id,
  }) async {
    final builder = binding == null
        ? pageBuilder
        : () {
            binding.dependencies();
            return pageBuilder();
          };
    final navigatorKey = id == null ? null : Get.nestedKey(id);

    return Get.lazyDialog<T>(
      builder,
      barrierDismissible: dismissible ?? true,
      barrierColor: isShowBarrier! ? _barrierColor : _barrierFreeColor,
      arguments: parameters,
      transitionCurve: Curves.fastLinearToSlowEaseIn,
      transitionDuration: const Duration(milliseconds: 200),
      navigatorKey: navigatorKey,
    );
  }

  /// 获取路由传参
  ///
  /// [navigateId] 路由导航Id
  Map<String, String>? getParams([int? navigateId]) {
    if (Get.arguments != null) {
      final params = Get.arguments as Map<String, String>;
      return params;
    }
    if (navigateId == null) {
      final params = Get.parameters;
      return params.cast<String, String>();
    } else if (_RouterArguments.routerArguments.containsKey(navigateId)) {
      return _RouterArguments.routerArguments[navigateId];
    }
    return null;
  }

  /// 通用路由生成器
  Route? onGenerateRoute(
    RouteSettings settings, {
    required List<String> registeredNames,
    required int? id,
  }) {
    final name = settings.name;
    if (name != null) {
      _recordNavCurrentName(id, name);
      if (registeredNames.contains(name)) {
        final routeSetting = _findPageByName(name);
        if (routeSetting != null) {
          return _buildPageRoute(settings, routeSetting);
        }
      }
    }
    return null;
  }

  /// 获取嵌套导航当前路由名称
  String? getCurrentNameByNavId(int id) {
    if (_navCurrentNames.containsKey(id)) return _navCurrentNames[id];
    return null;
  }

  void _recordNavCurrentName(int? id, String name) {
    if (id != null) {
      _navCurrentNames[id] = name;
    }
  }

  GetPageRoute _buildPageRoute(RouteSettings settings, GetPage page) {
    return GetPageRoute(
      settings: settings,
      page: page.page,
      binding: page.binding,
      transition: page.transition,
      customTransition: page.customTransition,
      transitionDuration:
          page.transitionDuration ?? const Duration(milliseconds: 250),
    );
  }

  FRouteSetting<dynamic>? _findPageByName(String name) {
    final setting = routes.firstWhereOrNull((x) => x.name == name);
    // if (setting == null) throw ArgumentError("Route name unregistered.");
    return setting;
  }

  // FRouteSetting<dynamic> _findPageByName(String name) {
  //   final splitNames = name.split('/');
  //   splitNames.removeWhere((x) => x.isEmpty);
  //   var routeList = routes;
  //   dynamic setting;
  //   for (String scopeName in splitNames) {
  //     setting = routeList.firstWhereOrNull((x) => x.name == "/$scopeName");
  //     if (setting == null) break;
  //     routeList = setting.children;
  //   }
  //   return setting;
  // }
}

/// 全局路由实例
final router = FRouter._();

extension FRouteExtOfGetx on GetInterface {
  Future<T?> lazyDialog<T>(
    FWidget Function() pageBuilder, {
    bool? barrierDismissible,
    Color? barrierColor,
    bool? isShowBarrier,
    bool useSafeArea = true,
    GlobalKey<NavigatorState>? navigatorKey,
    Object? arguments,
    Duration? transitionDuration,
    Curve? transitionCurve,
    String? name,
    RouteSettings? routeSettings,
  }) {
    assert(debugCheckHasMaterialLocalizations(context!));

    //  final theme = Theme.of(context, shadowThemeOnly: true);
    final theme = Theme.of(context!);
    return generalDialog<T>(
      pageBuilder: (buildContext, animation, secondaryAnimation) {
        final pageChild = pageBuilder();
        FWidget dialog = FBuilder(builder: (context) {
          return FThemeWidget(data: theme, child: pageChild);
        });
        if (useSafeArea) {
          dialog = FSafeArea(child: dialog);
        }
        return dialog;
      },
      barrierDismissible: barrierDismissible ?? true,
      barrierLabel: MaterialLocalizations.of(context!).modalBarrierDismissLabel,
      barrierColor: barrierColor ?? Colors.black54,
      transitionDuration:
          transitionDuration ?? const Duration(milliseconds: 250),
      transitionBuilder: (context, animation, secondaryAnimation, child) {
        return FadeTransition(
          opacity: CurvedAnimation(
            parent: animation,
            curve: transitionCurve ?? defaultDialogTransitionCurve,
          ),
          child: child,
        );
      },
      navigatorKey: navigatorKey,
      routeSettings:
          routeSettings ?? RouteSettings(arguments: arguments, name: name),
    );
  }
}

class _RouterArguments {
  ///id,arguments
  static Map<int, Map<String, String>> routerArguments = {};
}
