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/utils.dart';

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

  final VidPlayerController controller;

  final double? width;
  final double? height;

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

class _VidScenePlayerState extends State<VidScenePlayer> {
  Uint8List? frameBytes;
  Image? image;
  DateTime lastFrameTime = DateTime.now();
  ListQueue<int> frames = ListQueue<int>()..addFirst(30); //预留一位防止分母为0
  int maxFramesNum = 10;
  int curFPS = 30;

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

  @override
  void didUpdateWidget(covariant VidScenePlayer oldWidget) {
    if (oldWidget.controller != widget.controller) {
      throw UnsupportedError("[VidTestPlayer] unsupport replace controller.");
    }
    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();
    }
  }

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

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

    setState(() {});
    countCurFPS();
  }

  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 SizedBox(
          width: size.width, height: size.height, child: Container());
      // return CustomPaint(
      //   painter: VidPainter(image: image!, contextSize: size),
      //   isComplex: false, //是否为复杂图像（true会缓存）
      //   size: size,
      // );
    } else {
      return Container();
    }
  }

  void drawUsImage(image) async {
    // ContainerLayer containerLayer = ContainerLayer();
    // PaintingContext paintingContext = PaintingContext(containerLayer, Rect.zero);

    /// create Canvas & Recorder
    PictureRecorder recorder = PictureRecorder();
    Canvas canvas = Canvas(recorder);

    /// set offset
    final offset = -Offset(image.width / 2, image.height / 2);

    /// draw image
    canvas.drawImage(image, offset, Paint());

    /// draw circle
    // canvas.drawCircle(Offset.zero, 200, Paint()..color = Colors.red);

    /// get picture
    final picture = recorder.endRecording();
    var centerX = window.physicalSize.width / 2.0;
    var centerY = window.physicalSize.height / 2.0;

    /// build scene
    final SceneBuilder sceneBuilder = SceneBuilder()
      ..pushOffset(centerX, centerY)
      ..addPicture(Offset.zero, picture, willChangeHint: true)
      ..pop();

    /// get scene
    Scene scene = sceneBuilder.build();

    window.render(scene);
    scene.dispose();
    picture.dispose();
    image.dispose();
  }

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