import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_svg/svg.dart';
import 'dart:io';
import 'dart:ui' as ui show Codec;

import '../../basic/Common.dart';
import '../../basic/Method.dart';
import '../FilePhotoViewScreen.dart';

// 从本地加载图片
class ResourceFileImageProvider
    extends ImageProvider<ResourceFileImageProvider> {
  final String path;
  final double scale;

  ResourceFileImageProvider(this.path, {this.scale = 1.0});

  @override
  ImageStreamCompleter loadBuffer(
      ResourceFileImageProvider key, DecoderBufferCallback decode) {
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(key),
      scale: key.scale,
    );
  }

  @override
  Future<ResourceFileImageProvider> obtainKey(
      ImageConfiguration configuration) {
    return SynchronousFuture<ResourceFileImageProvider>(this);
  }

  Future<ui.Codec> _loadAsync(ResourceFileImageProvider key) async {
    assert(key == this);
    return PaintingBinding.instance
        .instantiateImageCodecFromBuffer(await ImmutableBuffer.fromUint8List(await File(path).readAsBytes()));
  }

  @override
  bool operator ==(dynamic other) {
    if (other.runtimeType != runtimeType) return false;
    final ResourceFileImageProvider typedOther = other;
    return path == typedOther.path && scale == typedOther.scale;
  }

  @override
  int get hashCode => Object.hash(path, scale);

  @override
  String toString() => '$runtimeType('
      'path: ${describeIdentity(path)},'
      ' scale: $scale'
      ')';
}

// 从本地加载图片
// class ResourceDownloadFileImageProvider
//     extends ImageProvider<ResourceDownloadFileImageProvider> {
//   final String path;
//   final double scale;
//
//   ResourceDownloadFileImageProvider(this.path, {this.scale = 1.0});
//
//   @override
//   ImageStreamCompleter load(
//       ResourceDownloadFileImageProvider key, DecoderCallback decode) {
//     return MultiFrameImageStreamCompleter(
//       codec: _loadAsync(key),
//       scale: key.scale,
//     );
//   }
//
//   @override
//   Future<ResourceDownloadFileImageProvider> obtainKey(
//       ImageConfiguration configuration) {
//     return SynchronousFuture<ResourceDownloadFileImageProvider>(this);
//   }
//
//   Future<ui.Codec> _loadAsync(ResourceDownloadFileImageProvider key) async {
//     assert(key == this);
//     return PaintingBinding.instance!.instantiateImageCodec(
//         await File(await method.downloadImagePath(path)).readAsBytes());
//   }
//
//   @override
//   bool operator ==(dynamic other) {
//     if (other.runtimeType != runtimeType) return false;
//     final ResourceDownloadFileImageProvider typedOther = other;
//     return path == typedOther.path && scale == typedOther.scale;
//   }
//
//   @override
//   int get hashCode => hashValues(path, scale);
//
//   @override
//   String toString() => '$runtimeType('
//       'path: ${describeIdentity(path)},'
//       ' scale: $scale'
//       ')';
// }

// 从远端加载图片
// class ResourceRemoteImageProvider
//     extends ImageProvider<ResourceRemoteImageProvider> {
//   final String fileServer;
//   final String path;
//   final double scale;
//
//   ResourceRemoteImageProvider(this.fileServer, this.path, {this.scale = 1.0});
//
//   @override
//   ImageStreamCompleter load(
//       ResourceRemoteImageProvider key, DecoderCallback decode) {
//     return MultiFrameImageStreamCompleter(
//       codec: _loadAsync(key),
//       scale: key.scale,
//     );
//   }
//
//   @override
//   Future<ResourceRemoteImageProvider> obtainKey(
//       ImageConfiguration configuration) {
//     return SynchronousFuture<ResourceRemoteImageProvider>(this);
//   }
//
//   Future<ui.Codec> _loadAsync(ResourceRemoteImageProvider key) async {
//     assert(key == this);
//     var downloadTo = await method.remoteImageData(fileServer, path);
//     return PaintingBinding.instance!
//         .instantiateImageCodec(await File(downloadTo.finalPath).readAsBytes());
//   }
//
//   @override
//   bool operator ==(dynamic other) {
//     if (other.runtimeType != runtimeType) return false;
//     final ResourceRemoteImageProvider typedOther = other;
//     return fileServer == typedOther.fileServer &&
//         path == typedOther.path &&
//         scale == typedOther.scale;
//   }
//
//   @override
//   int get hashCode => hashValues(fileServer, path, scale);
//
//   @override
//   String toString() => '$runtimeType('
//       'fileServer: ${describeIdentity(fileServer)},'
//       ' path: ${describeIdentity(path)},'
//       ' scale: $scale'
//       ')';
// }

// 下载的图片
// class DownloadImage extends StatefulWidget {
//   final String path;
//   final double? width;
//   final double? height;
//
//   const DownloadImage({
//     Key? key,
//     required this.path,
//     this.width,
//     this.height,
//   }) : super(key: key);
//
//   @override
//   State<StatefulWidget> createState() => _DownloadImageState();
// }
//
// class _DownloadImageState extends State<DownloadImage> {
//   late final Future<String> _future = method.downloadImagePath(widget.path);
//
//   @override
//   Widget build(BuildContext context) {
//     return pathFutureImage(
//       _future,
//       widget.width,
//       widget.height,
//       context: context,
//     );
//   }
// }

// 远端图片
class RemoteImage extends StatefulWidget {
  final String fileServer;
  final String path;
  final double? width;
  final double? height;
  final BoxFit fit;

  const RemoteImage({
    Key? key,
    required this.fileServer,
    required this.path,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
  }) : super(key: key);

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

class _RemoteImageState extends State<RemoteImage> {
  late bool _mock;
  late Future<String> _future;

  @override
  void initState() {
    debugPrint("path=${widget.path}");
    _mock = widget.fileServer == "" || widget.path == "";
    if (!_mock) {
      _future = method.downloadImage(widget.path, widget.fileServer).then((value) => value!);
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // return buildMock(widget.width, widget.height);
    if (_mock) {
      return buildMock(widget.width, widget.height);
    }
    return pathFutureImage(
      _future,
      widget.width,
      widget.height,
      fit: widget.fit,
      context: context,
    );
  }
}

Widget pathFutureImage(Future<String> future, double? width, double? height,
    {BoxFit fit = BoxFit.cover, BuildContext? context}) {
  return FutureBuilder(
      future: future,
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.hasError) {
          print("${snapshot.error}");
          print("${snapshot.stackTrace}");
          return buildError(width, height);
        }
        if (snapshot.connectionState != ConnectionState.done) {
          return buildLoading(width, height);
        }
        return buildFile(
          snapshot.data!,
          width,
          height,
          fit: fit,
          context: context,
        );
      });
}

// 通用方法

Widget buildSvg(String source, double? width, double? height,
    {Color? color, double? margin}) {
  var widget = Container(
    width: width,
    height: height,
    padding: margin != null ? const EdgeInsets.all(10) : null,
    child: Center(
      child: SvgPicture.asset(
        source,
        width: width,
        height: height,
        color: color,
      ),
    ),
  );
  return GestureDetector(onLongPress: () {}, child: widget);
}

Widget buildMock(double? width, double? height) {
  var widget = Container(
    width: width,
    height: height,
    padding: const EdgeInsets.all(10),
    child: Center(
      child: SvgPicture.asset(
        'lib/assets/unknown.svg',
        width: width,
        height: height,
        color: Colors.grey.shade600,
      ),
    ),
  );
  return GestureDetector(onLongPress: () {}, child: widget);
}

Widget buildError(double? width, double? height) {
  return Image(
    image: const AssetImage('lib/assets/error.png'),
    width: width,
    height: height,
  );
}

Widget buildLoading(double? width, double? height) {
  double? size;
  if (width != null && height != null) {
    size = width < height ? width : height;
  }
  return SizedBox(
    width: width,
    height: height,
    child: Center(
      child: Icon(
        Icons.downloading,
        size: size,
        color: Colors.black12,
      ),
    ),
  );
}

Widget buildFile(String file, double? width, double? height,
    {BoxFit fit = BoxFit.cover, BuildContext? context}) {
  var image = Image(
    image: ResourceFileImageProvider(file),
    width: width,
    height: height,
    errorBuilder: (a, b, c) {
      print("$b");
      print("$c");
      return buildError(width, height);
    },
    fit: fit,
  );
  if (context == null) return image;
  return GestureDetector(
    onLongPress: () async {
      String? choose = await chooseListDialog(context, '请选择', ['预览图片', '保存图片']);
      switch (choose) {
        case '预览图片':
          Navigator.of(context).push(MaterialPageRoute(
            builder: (context) => FilePhotoViewScreen(file),
          ));
          break;
        case '保存图片':
          //TODO: SAVE image
          // saveImage(file, context);
          break;
      }
    },
    child: image,
  );
}
