import 'dart:async';
import 'dart:collection';
import 'dart:typed_data';
import 'dart:ui';
import 'package:fis_measure/view/player/controller.dart';
import 'package:fis_measure/view/player/enums.dart';
import 'package:fis_measure/view/player/events.dart';
import 'package:flutter/material.dart' hide Image;
import 'package:vid_player_demo/utils/image_holder.dart';
import 'package:vid_player_demo/utils/utils.dart';
import 'dart:ui' as ui;
import 'vid_painter.dart';

///基于Canvas组件的播放器
class VidCanvasPlayer extends StatefulWidget {
  const VidCanvasPlayer(
    this.controller, {
    Key? key,
    this.width,
    this.height,
  }) : super(key: key);

  final VidPlayerController controller;

  final double? width;
  final double? height;

  @override
  State<StatefulWidget> createState() => _VidCanvasPlayerState();
}

class _VidCanvasPlayerState extends State<VidCanvasPlayer> {
  Uint8List? frameBytes;
  ui.Image? image;
  MyImageHolder? holder;
  DateTime lastFrameTime = DateTime.now();
  ListQueue<int> frames = ListQueue<int>()..addFirst(30); //预留一位防止分母为0
  int maxFramesNum = 10;
  int curFPS = 30;
  List<double> curColorFilterMatrix = <double>[
    1, 0, 0, 0, 0, // red
    0, 1, 0, 0, 0, // green
    0, 0, 1, 0, 0, // blue
    0, 0, 0, 1, 0, // alpha
  ];

  @override
  void initState() {
    widget.controller.eventHandler.addListener(onControllerEvent);
    startFPSListener();
    super.initState();
  }

  @override
  void didUpdateWidget(covariant VidCanvasPlayer oldWidget) {
    if (oldWidget.controller != widget.controller) {
      throw UnsupportedError("[VidTestPlayer] unsupport replace controller.");
    }
    // image?.dispose(); //TODO 不知是否生效
    super.didUpdateWidget(oldWidget);
  }

  void onControllerEvent(Object sender, VidPlayerEvent e) {
    if (e is VidPlayerStatusChangeEvent) {
      if (!widget.controller.hasView) {
        setState(() {});
      }
    }
    if (e is VidPlayerFrameIndexChangeEvent) {
      onFrameChanged(e);
    }
    if (e is VidPlayerBrightnessChangeEvent) {
      updateFrame();
    }
    if (e is VidPlayerContrastChangeEvent) {
      updateFrame();
    }
    if (e is VidPlayerFilterChangeEvent) {
      onFilterMatrixChanged(e);
      // updateFrame();
    }
  }

  void onFrameChanged(VidPlayerFrameIndexChangeEvent e) {
    loadFrame(e);
  }

  void onFilterMatrixChanged(VidPlayerFilterChangeEvent e) {
    setState(() {
      curColorFilterMatrix = e.filterMatrix;
    });
  }

  void loadFrame(VidPlayerFrameIndexChangeEvent e) async {
    // List<StackTrace>? debugList = image?.debugGetOpenHandleStackTraces();
    // print("${DateTime.now()} Load frame \n ${debugList.toString()}");
    // image?.dispose();
    final oldImg = image;
    image = await _loadImage(e.bytes);
    // image = await decodeImageFromList(e.bytes);
    oldImg?.dispose();

    /// 输出数组的前20位数字
    // print(
    //     "${e.width} x ${e.height} ${e.bytes.length} ${e.bytes.sublist(3000, 3020)}");
    // print("${DateTime.now()} Load frame ${image?.width} x ${image?.height}");
    // holder = MyImageHolder(image!.clone());
    setState(() {});
    // image?.dispose();
    // image?.dispose();

    countCurFPS();
  }

  Future<Image> _loadImage(Uint8List bytes) async {
    final Completer<Image> completer = Completer<Image>();
    decodeVidFromList(bytes, (Image image) => completer.complete(image));

    // ui.decodeImageFromList(bytes, (Image image) => completer.complete(image));

    return completer.future;
  }

  void decodeVidFromList(Uint8List bytes, ImageDecoderCallback callback) async {
    ImmutableBuffer.fromUint8List(bytes).then((ImmutableBuffer buffer) async {
      final ImageDescriptor descriptor = await ImageDescriptor.encoded(buffer);
      descriptor.instantiateCodec().then((Codec codec) {
        final Future<FrameInfo> frameInfo = codec.getNextFrame();
        codec.dispose();
        return frameInfo;
      }).then((FrameInfo frameInfo) {
        buffer.dispose();
        descriptor.dispose();
        return callback(frameInfo.image);
      });
    });
  }

  void updateFrame() {
    setState(() {});
  }

  void countCurFPS() {
    int fps = 1000 ~/ DateTime.now().difference(lastFrameTime).inMilliseconds;
    lastFrameTime = DateTime.now();
    frames.addFirst(fps);
    while (frames.length > maxFramesNum) {
      frames.removeLast();
    }
    curFPS = frames.reduce((a, b) => a + b) ~/ frames.length;
  }

  @override
  Widget build(BuildContext context) {
    Widget? child;
    switch (widget.controller.status) {
      case VidPlayStatus.init:
        child = const Text("Loading");
        break;
      case VidPlayStatus.ready:
        child = const Text("Ready");
        break;
      case VidPlayStatus.loadFail:
        child = const Text("Load fail");
        break;
      case VidPlayStatus.play:
      case VidPlayStatus.pause:
        child = buildFrameView(context);
        break;
      case VidPlayStatus.stop:
      case VidPlayStatus.dispose:
        child = const Text("Closed");
        break;
    }
    return buildBox(context, child);
  }

  ///创建播放器容器，可以在此叠加信息
  Widget buildBox(BuildContext context, Widget child) {
    return Stack(
      children: [
        Text(
            "当前帧：${widget.controller.currentFrameIndex} \n估算平均帧率：$curFPS fps \n"),
        Container(
          alignment: Alignment.center,
          child: child,
        ),
      ],
    );
  }

  Widget buildFrameView(BuildContext context) {
    if (image != null) {
      final size = MediaQuery.of(context).size;
      return CustomPaint(
        painter:
            VidPainter(image: image!, colorFilterMatrix: curColorFilterMatrix),
        isComplex: false, //是否为复杂图像（true会缓存）
        size: size,
      );
    } else {
      return const Text("No holder");
    }
  }

  @override
  void dispose() {
    widget.controller.eventHandler.removeListener(onControllerEvent);
    stopFPSListener();
    super.dispose();
  }
}
