import 'package:flutter/material.dart';
import 'package:get/get.dart';

/*
  //使用示例，单个Controller
  final logic = Get.put(TestLogic());

  @override
  Widget build(BuildContext context) {
    return GetBindWidget(
      bind: logic,
      child: Container(),
    );
  }

  //使用示例，多个Controller
  final logicOne = Get.put(TestLogic(), tag: 'one');
  final logicTwo = Get.put(TestLogic());
  final logicThree = Get.put(TestLogic(), tag: 'three');

  @override
  Widget build(BuildContext context) {
    return GetBindWidget(
      binds: [logicOne, logicTwo, logicThree],
      tags: ['one', '', 'three'],
      child: Container(),
    );
  }
 */

/// 可以自定义绑定用于GetX框架无法正常回收Controller的场景，包裹根视图，设置bind属性，手动绑定到Controller，
/// 当页面退出的时候指定解绑Controller
class GetBindWidget extends StatefulWidget {
  const GetBindWidget({
    Key? key,
    this.bind,
    this.tag,
    this.binds,
    this.tags,
    required this.child,
  })  : assert(
          binds == null || tags == null || binds.length == tags.length,
          'The binds and tags arrays length should be equal\n'
          'and the elements in the two arrays correspond one-to-one',
        ),
        super(key: key);

  final GetxController? bind;
  final String? tag;

  final List<GetxController>? binds;
  final List<String>? tags;

  final Widget child;

  @override
  _GetBindWidgetState createState() => _GetBindWidgetState();
}

class _GetBindWidgetState extends State<GetBindWidget> {
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

  @override
  void dispose() {
    _closeGetXController();
    _closeGetXControllers();

    super.dispose();
  }

  ///Close GetxController bound to the current modules
  void _closeGetXController() {
    if (widget.bind == null) {
      return;
    }

    var key = widget.bind.runtimeType.toString() + (widget.tag ?? '');
    GetInstance().delete(key: key);
  }

  ///Batch close GetxController bound to the current modules
  void _closeGetXControllers() {
    if (widget.binds == null) {
      return;
    }

    for (var i = 0; i < widget.binds!.length; i++) {
      var type = widget.binds![i].runtimeType.toString();

      if (widget.tags == null) {
        GetInstance().delete(key: type);
      } else {
        var key = type + (widget.tags?[i] ?? '');
        GetInstance().delete(key: key);
      }
    }
  }
}
