// ignore_for_file: must_be_immutable

import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:vnoteapp/components/floating_window/click_notification.dart';

/// [FloatingItem]一个单独功能完善的列表项类
class FloatingItem extends StatefulWidget {
  FloatingItem({
    super.key,
    required this.top,
    required this.isLeft,
    required this.title,
    required this.imageProvider,
    required this.index,
    required this.left,
    required this.isEntering,
    this.width,
  });

  /// [index] 列表项的索引值
  int index;

  /// [top]列表项的y坐标值
  double top;

  /// [left]列表项的x坐标值
  double left;

  ///[isLeft] 列表项是否在左侧，否则是右侧
  bool isLeft;

  /// [title] 列表项的文字说明
  String title;

  ///[imageProvider] 列表项Logo的imageProvider
  ImageProvider imageProvider;

  ///[width] 屏幕宽度的 1 / 2
  double? width;

  ///[isEntering] 列表项是否触发进场动画
  bool isEntering;

  @override
  _FloatingItemState createState() => _FloatingItemState();

  /// 全部列表项执行退场动画
  static void reverse() {
    for (int i = 0; i < _FloatingItemState.animationControllers.length; ++i) {
      if (!_FloatingItemState.animationControllers[i]
          .toString()
          .contains('DISPOSED')) {
        _FloatingItemState.animationControllers[i].reverse();
      }
    }
  }

  /// 全部列表项执行进场动画
  static void forward() {
    for (int i = 0; i < _FloatingItemState.animationControllers.length; ++i) {
      if (!_FloatingItemState.animationControllers[i]
          .toString()
          .contains('DISPOSED')) {
        _FloatingItemState.animationControllers[i].forward();
      }
    }
  }

  /// 每次更新时释放所有动画资源，清空动画控制器列表
  static void resetList() {
    for (int i = 0; i < _FloatingItemState.animationControllers.length; ++i) {
      if (!_FloatingItemState.animationControllers[i]
          .toString()
          .contains('DISPOSED')) {
        _FloatingItemState.animationControllers[i].dispose();
      }
    }
    _FloatingItemState.animationControllers.clear();
    _FloatingItemState.animationControllers = [];
  }
}

class _FloatingItemState extends State<FloatingItem>
    with TickerProviderStateMixin {
  /// [isPress] 列表项是否被按下
  bool isPress = false;

  ///[image] 列表项Logo的[ui.Image]对象，用于绘制Logo
  ui.Image? image;

  /// [animationController] 列表关闭动画的控制器
  AnimationController? animationController;

  /// [animationController] 所有列表项的动画控制器列表
  static List<AnimationController> animationControllers = [];

  /// [animation] 列表项的关闭动画
  Animation? animation;

  @override
  void initState() {
// TODO: implement initState
    isPress = false;

    /// 获取Logo的ui.Image对象
    loadImageByProvider(widget.imageProvider).then((value) {
      setState(() {
        image = value;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: widget.left,
      top: widget.top,
      child: GestureDetector(
        /// 监听按下事件，在点击区域内则将[isPress]设为true，若在关闭区域内则不做任何操作
        onPanDown: (details) {
          if (widget.isLeft) {
            /// 点击区域内
            if (details.globalPosition.dx < widget.width!) {
              setState(() {
                isPress = true;
              });
            }
          } else {
            /// 点击区域内
            if (details.globalPosition.dx < widget.width! * 2 - 50) {
              setState(() {
                isPress = true;
              });
            }
          }
        },

        /// 监听抬起事件
        onTapUp: (details) async {
          /// 通过左右列表项来决定关闭的区域，以及选中区域，触发相应的关闭或选中事件
          if (widget.isLeft) {
            /// 位于关闭区域
            if (details.globalPosition.dx >= widget.width! && !isPress) {
              /// 等待关闭动画执行完毕
              await animationController?.reverse();

              /// 通知父级触发关闭事件
              ClickNotification(deletedIndex: widget.index).dispatch(context);
            } else {
              /// 通知父级触发相应的点击事件
              ClickNotification(clickIndex: widget.index).dispatch(context);
            }
          } else {
            /// 位于关闭区域
            if (details.globalPosition.dx >= widget.width! * 2 - 50.0 &&
                !isPress) {
              /// 设置从中间返回至边缘的关闭动画
              await animationController?.reverse();

              /// 通知父级触发关闭事件
              ClickNotification(deletedIndex: widget.index).dispatch(context);
            } else {
              /// 通知父级触发选中事件
              ClickNotification(clickIndex: widget.index).dispatch(context);
            }
          }

          /// 抬起后取消选中
          setState(() {
            isPress = false;
          });
        },
        onTapCancel: () {
          /// 超出范围取消选中
          setState(() {
            isPress = false;
          });
        },
        child: Container(
          color: Colors.red,
        ),
      ),
    );
    //  CustomPaint(
    //     size: Size(widget.width! + 50.0, 50.0),
    //     painter: FloatingItemPainter(
    //       title: widget.title,
    //       isLeft: widget.isLeft,
    //       isPress: isPress,
    //       image: image,
    //     ))));
  }

  /// 通过ImageProvider获取ui.image
  Future<ui.Image> loadImageByProvider(
    ImageProvider provider, {
    ImageConfiguration config = ImageConfiguration.empty,
  }) async {
    Completer<ui.Image> completer = Completer<ui.Image>(); //完成的回调
    ImageStreamListener listener;
    ImageStream stream = provider.resolve(config); //获取图片流
    listener = ImageStreamListener((ImageInfo frame, bool sync) {
//监听
      final ui.Image image = frame.image;
      completer.complete(image); //完成
      // stream.removeListener(listener); //移除监听
    });
    stream.addListener(listener); //添加监听
    return completer.future; //返回
  }

  @override
  void didUpdateWidget(FloatingItem oldWidget) {
// TODO: implement didUpdateWidget
    animationController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 100));

    /// 初始化进场动画
    if (widget.isLeft) {
      animation = Tween<double>(begin: -(widget.width! + 50.0), end: 0.0)
          .animate(animationController!)
        ..addListener(() {
          setState(() {
            widget.left = animation!.value;
          });
        });
    } else {
      animation =
          Tween<double>(begin: widget.width! * 2, end: widget.width! - 50.0)
              .animate(animationController!)
            ..addListener(() {
              setState(() {
                widget.left = animation!.value;
              });
            });
    }
    animationControllers.add(animationController!);

    /// 执行进场动画
    if (animationController!.status == AnimationStatus.dismissed &&
        widget.isEntering) {
      animationController!.forward();
    }

    /// 无需执行进场动画，将列表项置于动画末尾
    else {
      animationController!.forward(from: 100.0);
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
// TODO: implement dispose
    /// 释放动画资源，避免内存泄漏
    if (!animationController.toString().toString().contains('DISPOSED')) {
      animationController!.dispose();
    }
    super.dispose();
  }
}
