import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:openim_common/openim_common.dart';

class ChatPicturePreview extends StatelessWidget {
  ChatPicturePreview({
    Key? key,
    this.currentIndex = 0,
    this.images = const [],
    this.heroTag,
    this.onTap,
    this.onLongPress,
  })  : controller = images.length > 1 ? ExtendedPageController(initialPage: currentIndex, pageSpacing: 50) : null,
        super(key: key);
  final int currentIndex;
  final List<MediaSource> images;
  final String? heroTag;
  final Function()? onTap;
  final Function(String url)? onLongPress;
  final ExtendedPageController? controller;
  GlobalKey<ExtendedImageSlidePageState> slidePagekey = GlobalKey<ExtendedImageSlidePageState>();
  @override
  Widget build(BuildContext context) {
    return ExtendedImageSlidePage(
      key: slidePagekey,
      slideAxis: SlideAxis.vertical,
      slidePageBackgroundHandler: (offset, pageSize) => defaultSlidePageBackgroundHandler(
        color: Colors.black,
        offset: offset,
        pageSize: pageSize,
      ),
      child: Stack(
        children: [
          MetaHero(
            heroTag: heroTag,
            onTap: onTap ?? () => Get.back(),
            onLongPress: () {
              final index = controller?.page?.round() ?? currentIndex;
              onLongPress?.call(images[index].url!);
            },
            child: _childView,
          ),
          if (images.length > 1)
            Positioned(
              top: MediaQuery.paddingOf(context).top + 12,
              left: 16,
              child: _PreviewIndex(
                controller: controller,
                total: images.length,
                initial: currentIndex,
              ),
            ),
        ],
      ),
    );
  }

  Widget get _childView {
    return images.length == 1 ? _networkGestureImage(images[0]) : _pageView;
  }

  Widget get _pageView => ExtendedImageGesturePageView.builder(
        controller: controller,
        onPageChanged: (int index) {},
        itemCount: images.length,
        itemBuilder: (BuildContext context, int index) {
          return _networkGestureImage(images.elementAt(index));
        },
      );

  Widget _networkGestureImage(MediaSource source) => ExtendedImage.network(
        source.thumbnail,
        fit: BoxFit.contain,
        mode: ExtendedImageMode.gesture,
        clearMemoryCacheWhenDispose: true,
        clearMemoryCacheIfFailed: true,
        handleLoadingProgress: true,
        enableSlideOutPage: true,
        initGestureConfigHandler: (ExtendedImageState state) {
          return GestureConfig(
            inPageView: true,
            initialScale: 1.0,
            maxScale: 5.0,
            animationMaxScale: 6.0,
            initialAlignment: InitialAlignment.center,
          );
        },
        loadStateChanged: (ExtendedImageState state) {
          switch (state.extendedImageLoadState) {
            case LoadState.loading:
              {
                if (source.url?.isVideoFileName == true) {
                  return null;
                }

                return Center(
                  child: SizedBox(
                    width: 24,
                    height: 24,
                    child: CircularProgressIndicator(
                      color: Styles.c_0089FF,
                      strokeWidth: 2,
                    ),
                  ),
                );
              }
            case LoadState.completed:
              final url = source.url;
              if (url?.isVideoFileName == true) {
                return Center(
                    child: ChatVideoPlayerView(
                  url: url,
                  coverUrl: source.thumbnail,
                ));
              }
              return Center(
                child: ExtendedImage.network(url!),
              );
            case LoadState.failed:
              state.imageProvider.evict();
              return GestureDetector(
                onTap: () => state.reLoadImage(),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(Icons.broken_image_outlined,
                        size: 64, color: Styles.c_FFFFFF_opacity70),
                    const SizedBox(height: 16),
                    const Text('图片加载失败',
                        style: TextStyle(color: Colors.white, fontSize: 16)),
                    const SizedBox(height: 4),
                    Text('点击重试',
                        style: TextStyle(
                            color: Styles.c_FFFFFF_opacity70, fontSize: 14)),
                  ],
                ),
              );
          }
        },
      );
}

class MetaHero extends StatelessWidget {
  const MetaHero({
    Key? key,
    required this.heroTag,
    required this.child,
    this.onTap,
    this.onLongPress,
  }) : super(key: key);
  final Widget child;
  final String? heroTag;
  final Function()? onTap;
  final Function()? onLongPress;

  @override
  Widget build(BuildContext context) {
    final view = GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: onTap,
      onLongPress: onLongPress,
      child: child,
    );
    return heroTag == null ? view : Hero(tag: heroTag!, child: view);
  }
}

class _PreviewIndex extends StatefulWidget {
  const _PreviewIndex({
    required this.controller,
    required this.total,
    required this.initial,
  });

  final ExtendedPageController? controller;
  final int total;
  final int initial;

  @override
  State<_PreviewIndex> createState() => _PreviewIndexState();
}

class _PreviewIndexState extends State<_PreviewIndex> {
  late int _index;

  @override
  void initState() {
    super.initState();
    _index = widget.initial;
    widget.controller?.addListener(_onPage);
  }

  void _onPage() {
    final page = widget.controller?.page?.round();
    if (page != null && page != _index) {
      setState(() => _index = page);
    }
  }

  @override
  void dispose() {
    widget.controller?.removeListener(_onPage);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text(
      '${_index + 1}/${widget.total}',
      style: const TextStyle(color: Colors.white, fontSize: 14),
    );
  }
}
