import 'dart:ui' show ImmutableBuffer, ImageDescriptor;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/widgets.dart';

import 'dart:async';

import 'package:get/get.dart';

import 'package:json_annotation/json_annotation.dart';

import 'index.dart';

part 'zoom_logic.g.dart';

class ZoomLogic extends GetxController {
  final logic = Get.find<HomeworkReviewLogic>();
  HomeworkReviewState get homeworkState => logic.state;

  ZoomState zoomState = ZoomState(zoomFile: Rx<ZoomFileModel?>(null));

  var oldTemplateId = null;
  late StreamSubscription _streamHomework;
  late StreamSubscription _streamZoomState;

  @override
  void onInit() {
    oldTemplateId = zoomState.zoomFile.value?.templateId;
    _streamZoomState = zoomState.zoomFile.listen((e) {
      var templateId = e?.templateId;
      print("ZOOMFILE 变化了 $templateId");
      if (templateId == null) return;

      var homeworkData = homeworkState.data.value;
      var zgtAnswer = homeworkData?.zgtAnswer;
      print("333333");
      if (zgtAnswer == null) return;
      print("444444 ${homeworkData!.templateId} 和 ${templateId}");
      if (oldTemplateId == templateId) return;

      // getNetworkImageDimensions(zgtAnswer);

      // 第三方库网络图，图片会被解码并缓存于内存
      oldTemplateId = templateId;
      print("获取图片尺寸....");
      CachedNetworkImageProvider(zgtAnswer).getImageSize().then((s) {
        // 提取宽度和高度
        if (s == null) return;
        var oldVal = zoomState.zoomFile.value!;
        oldVal.fileWidth = s.width;
        oldVal.fileHeight = s.height;
        zoomState.zoomFile.value = ZoomFileModel.fromJson(oldVal.toJson());
      });
    });
    _streamHomework = homeworkState.data.listen((e) {
      print("HOMEWORKSTATE 变化了");
      if (e == null || zoomState.zoomFile.value == null) return;
      zoomState.zoomFile.value!.templateId = e.templateId;
      print("666666 ${e.templateId}");
      zoomState.zoomFile.value = ZoomFileModel.fromJson(zoomState.zoomFile.value!.toJson());
    });
    super.onInit();
  }

  @override
  void onClose() {
    _streamHomework.cancel();
    _streamZoomState.cancel();
    super.onClose();
  }
}

class ZoomState {
  final Rx<ZoomFileModel?> zoomFile;

  const ZoomState({required this.zoomFile});
}

@JsonSerializable()
class ZoomFileModel extends Object {
  double viewWidth; // 容器宽度
  double viewHeight; // 容器高度

  int? templateId; // 页码

  double? fileWidth; // 文件宽度
  double? fileHeight; // 文件高度

  double? actualWidth; // 实际展示宽度
  double? actualHeight; // 实际展示高度

  ZoomFileModel({
    required this.viewWidth,
    required this.viewHeight,
    this.templateId,
    this.fileWidth,
    this.fileHeight,
    this.actualWidth,
    this.actualHeight,
  }) {
    // 图片已视图宽为基准，高度自适应可滑动   图片的实际宽高都需要乘此基准值.
    if (fileHeight == null || fileWidth == null) return;

    var scaleRatio = viewWidth / fileWidth!;
    actualWidth = fileWidth! * scaleRatio;
    actualHeight = fileHeight! * scaleRatio;

    // remainingHeight = boxHeight - actualImgHeight;
    // imageHeightOffsetStart = remainingHeight / 2;
    // imageHeightOffsetend = imageHeightOffsetStart + actualImgHeight;
  }

  factory ZoomFileModel.fromJson(Map<String, dynamic> srcJson) => _$ZoomFileModelFromJson(srcJson);

  Map<String, dynamic> toJson() => _$ZoomFileModelToJson(this);
}

// 最终版
extension GetImageSize on ImageProvider {
  Future<Size?> getImageSize({bool avoidDecode = false}) async {
    if (avoidDecode) {
      // 是否要免解码
      final cacheStatus = await obtainCacheStatus(configuration: const ImageConfiguration());
      final tracked = cacheStatus?.tracked ?? false;
      // 内存缓存中存在时优先从缓存中取，不在内存缓存中时转换为 ImageDescriptor
      if (!tracked) {
        ImmutableBuffer? buffer;
        if (this is AssetBundleImageProvider) {
          final key = await obtainKey(const ImageConfiguration()) as AssetBundleImageKey;
          buffer = await key.bundle.loadBuffer(key.name);
        } else if (this is FileImage) {
          final file = (this as FileImage).file;
          final int lengthInBytes = await file.length();
          if (lengthInBytes > 0) {
            buffer = await ImmutableBuffer.fromFilePath(file.path);
          }
        } else if (this is MemoryImage) {
          final bytes = (this as MemoryImage).bytes;
          buffer = await ImmutableBuffer.fromUint8List(bytes);
        }
        if (buffer != null) {
          final descriptor = await ImageDescriptor.encoded(buffer);
          final size = Size(descriptor.width.toDouble(), descriptor.height.toDouble());
          buffer.dispose();
          descriptor.dispose();
          if (!size.isEmpty) return size;
        }
      }
    }

    // 免解码末开启或内存缓存已存在，最后再兜底上面未处理的情况
    final completer = Completer<Size?>();
    ImageStream imageStream = resolve(const ImageConfiguration());

    ImageStreamListener? listener;
    listener = ImageStreamListener(
      (imageInfo, synchronousCall) {
        if (!completer.isCompleted) {
          completer.complete(Size(imageInfo.image.width.toDouble(), imageInfo.image.height.toDouble()));
        }
        WidgetsBinding.instance.addPostFrameCallback((_) {
          imageInfo.dispose();
          imageStream.removeListener(listener!);
        });
      },
      onError: (exception, stackTrace) {
        if (!completer.isCompleted) {
          completer.complete();
        }
        imageStream.removeListener(listener!);
      },
    );
    imageStream.addListener(listener);

    return completer.future;
  }
}
