/*
 * @Author: XianKaiQun
 * @Date: 2020-04-22 09:23:26
 * @LastEditors  : WuWei
 * @LastEditTime : 2023-05-24 15:08:59
 * @Descripttion: 
 */

import 'dart:io' show File;
import 'dart:typed_data';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:octo_image/octo_image.dart';
import 'package:wisdom_cli/new/utils/cache_image.dart';

class WImage extends StatelessWidget {
  const WImage({
    Key? key,
    this.placeholder,
    required this.image,
    this.excludeFromSemantics = false,
    this.imageSemanticLabel,
    this.fadeOutDuration = const Duration(milliseconds: 150),
    this.fadeOutCurve,
    this.fadeInDuration = const Duration(milliseconds: 150),
    this.fadeInCurve,
    this.width,
    this.height,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,
    this.borderRadius,
    this.isCache,
  })  : assert(image != null),
        assert(fadeOutDuration != null),
        // assert(fadeOutCurve != null),
        assert(fadeInDuration != null),
        // assert(fadeInCurve != null),
        assert(repeat != null),
        assert(matchTextDirection != null),
        super(key: key);
  WImage.network(
    String src, {
    Key? key,
    this.placeholder,
    this.excludeFromSemantics = false,
    this.imageSemanticLabel,
    this.fadeOutDuration = const Duration(milliseconds: 150),
    this.fadeOutCurve = Curves.easeOut,
    this.fadeInDuration = const Duration(milliseconds: 150),
    this.fadeInCurve = Curves.easeIn,
    this.width,
    this.height,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,
    this.borderRadius,
    this.isCache,
  })  : assert(fadeOutDuration != null),
        assert(fadeOutCurve != null),
        assert(fadeInDuration != null),
        assert(fadeInCurve != null),
        assert(repeat != null),
        assert(matchTextDirection != null),
        image = CachedNetworkImageProvider(src),
        super(key: key);

  WImage.cache(
    String src, {
    Key? key,
    this.placeholder,
    this.excludeFromSemantics = false,
    this.imageSemanticLabel,
    this.fadeOutDuration = const Duration(milliseconds: 0),
    this.fadeOutCurve,
    this.fadeInDuration = const Duration(milliseconds: 0),
    this.fadeInCurve,
    this.width,
    this.height,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,
    this.borderRadius,
    this.isCache = true,
  })  : assert(fadeOutDuration != null),
        // assert(fadeOutCurve != null),
        assert(fadeInDuration != null),
        // assert(fadeInCurve != null),
        assert(repeat != null),
        assert(matchTextDirection != null),
        image = WisLocalCacheNetworkImage(src, isLocalCache: true),
        super(key: key);

  WImage.asset(
    String assetName, {
    Key? key,
    this.placeholder,
    this.excludeFromSemantics = false,
    this.imageSemanticLabel,
    this.fadeOutDuration = const Duration(milliseconds: 1),
    this.fadeOutCurve = Curves.easeOut,
    this.fadeInDuration = const Duration(milliseconds: 1),
    this.fadeInCurve = Curves.easeIn,
    this.width,
    this.height,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,
    this.borderRadius,
    String? package,
    this.isCache,
  })  : assert(fadeOutDuration != null),
        assert(fadeOutCurve != null),
        assert(fadeInDuration != null),
        assert(fadeInCurve != null),
        assert(repeat != null),
        assert(matchTextDirection != null),
        image = AssetImage(assetName, package: package),
        super(key: key);

  WImage.file(
    File file, {
    Key? key,
    this.placeholder,
    this.excludeFromSemantics = false,
    this.imageSemanticLabel,
    this.fadeOutDuration = const Duration(milliseconds: 1),
    this.fadeOutCurve = Curves.easeOut,
    this.fadeInDuration = const Duration(milliseconds: 1),
    this.fadeInCurve = Curves.easeIn,
    this.width,
    this.height,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,
    this.borderRadius,
    this.isCache,
  })  : assert(fadeOutDuration != null),
        assert(fadeOutCurve != null),
        assert(fadeInDuration != null),
        assert(fadeInCurve != null),
        assert(repeat != null),
        assert(matchTextDirection != null),
        image = FileImage(file),
        super(key: key);

  WImage.memory(
    Uint8List bytes, {
    Key? key,
    this.placeholder,
    this.excludeFromSemantics = false,
    this.imageSemanticLabel,
    this.fadeOutDuration = const Duration(milliseconds: 150),
    this.fadeOutCurve = Curves.easeOut,
    this.fadeInDuration = const Duration(milliseconds: 150),
    this.fadeInCurve = Curves.easeIn,
    this.width,
    this.height,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,
    this.borderRadius,
    this.isCache,
  })  : assert(fadeOutDuration != null),
        assert(fadeOutCurve != null),
        assert(fadeInDuration != null),
        assert(fadeInCurve != null),
        assert(repeat != null),
        assert(matchTextDirection != null),
        image = MemoryImage(bytes),
        super(key: key);
  final Widget? placeholder;
  final ImageProvider? image;
  final Duration? fadeOutDuration;
  final Curve? fadeOutCurve;
  final Duration? fadeInDuration;
  final Curve? fadeInCurve;
  final double? width;
  final double? height;
  final BoxFit? fit;
  final AlignmentGeometry? alignment;
  final ImageRepeat? repeat;
  final bool? matchTextDirection;
  final bool? excludeFromSemantics;
  final String? imageSemanticLabel;
  final BorderRadius? borderRadius;
  final bool? isCache;

  @override
  Widget build(BuildContext context) {
    Widget result = OctoImage(
      image: image!,
      width: width,
      height: height,
      fit: fit,
      alignment: alignment as Alignment? ?? Alignment.center,
      repeat: repeat,
      matchTextDirection: matchTextDirection,
      gaplessPlayback: true,
      errorBuilder: (context, error, stackTrace) {
        return ColoredBox(
          color: Colors.black12,
          child: Icon(
            Icons.broken_image,
            color: Colors.black45,
          ),
        );
      },
    );

    /// 缓存无需使用OctoImage，会自带动画效果
    if (isCache == true)
      result = SizedBox(
        width: width,
        height: height,
        child: Image(
          image: image!,
          width: width,
          height: height,
          fit: fit,
          alignment: alignment ?? Alignment.center,
          repeat: repeat!,
          matchTextDirection: matchTextDirection!,
          gaplessPlayback: true,
          errorBuilder: (context, error, stackTrace) {
            return ColoredBox(
              color: Colors.black12,
              child: Icon(
                Icons.broken_image,
                color: Colors.black45,
              ),
            );
          },
        ),
      );

    ///高度长度限制一下，如果只在image中限制    那么淡出效果会导致图片布局异常
    if (height != null || width != null)
      result = SizedBox(
        width: width,
        height: height,
        child: result,
      );

    ///圆角
    if (borderRadius != null)
      result = ClipRRect(
        borderRadius: borderRadius ?? BorderRadius.zero,
        child: result,
      );
    if (!excludeFromSemantics!) {
      result = Semantics(
        container: imageSemanticLabel != null,
        image: true,
        label: imageSemanticLabel ?? '',
        child: result,
      );
    }

    return result;
  }
}
