import 'dart:async';
import 'dart:ffi';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:guru_widgets/animation/standard/transform_animation.dart';
import 'package:rxdart/rxdart.dart';
import 'dialog_daily_reward_gift_design_model.dart';

class DialogDailyRewardGiftWidget extends StatefulWidget {
  final Color? backgroundColor;
  final String titleText;
  final TextStyle? titleTextStyle;
  final Color? borderColor;
  final double? borderWidth;
  final List<GiftConfig> giftList;
  final Image watchAdImage;
  final String guideText;
  final TextStyle? guideTextStyle;
  final Image? closeImage;
  final VoidCallback? closeCallback;

  const DialogDailyRewardGiftWidget({
    Key? key,
    this.backgroundColor,
    this.borderColor,
    this.borderWidth,
    this.closeImage,
    this.closeCallback,
    required this.titleText,
    this.titleTextStyle,
    required this.guideText,
    this.guideTextStyle,
    required this.giftList,
    required this.watchAdImage,
  })  : assert(giftList.length == 3),
        super(key: key);

  @override
  _DialogDailyRewardGiftWidgetState createState() => _DialogDailyRewardGiftWidgetState();
}

class _DialogDailyRewardGiftWidgetState extends State<DialogDailyRewardGiftWidget> {
  DialogDailyRewardDesignSpec get designSpec => DialogDailyRewardDesignSpec.get();
  DialogDailyRewardContentDesignSpec get contentSpec => designSpec.contentSpec;

  List<BehaviorSubject<GiftConfig?>> giftSubjects = List.generate(3, (index) => BehaviorSubject.seeded(null));
  Stream<List<GiftConfig>> get totalGiftStream => Rx.combineLatest3(giftSubjects[0], giftSubjects[1], giftSubjects[2], (a, b, c) {
        List<GiftConfig> list = [];
        if (a != null && a is GiftConfig && b != null && b is GiftConfig && c != null && c is GiftConfig) {
          list.addAll([a, b, c]);
        }
        return list;
      });

  String _tipText = "";
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _tipText = widget.guideText;
    for (int i = 0; i < widget.giftList.length; i++) {
      giftSubjects[i].add(widget.giftList[i]);
    }
  }

  @override
  Widget build(BuildContext context) {
    if (widget.giftList.length != 3) {
      return const Center(
        child: Text("gift error"),
      );
    }
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Container(
          decoration: BoxDecoration(
              color: widget.backgroundColor ?? const Color(0xffffffff),
              borderRadius: contentSpec.cardRadius,
              border: Border.all(color: const Color.fromRGBO(2, 136, 88, 0.14), width: contentSpec.borderWidth)),
          width: contentSpec.measuredSize.width,
          child: Center(
            child: Container(
              width: contentSpec.measuredSize.width - contentSpec.borderWidth * 2,
              decoration: BoxDecoration(
                borderRadius: contentSpec.contentRadius,
                gradient: const LinearGradient(
                    colors: [Color(0xffe2f2ee), Color(0xffffffff)], begin: AlignmentDirectional.topCenter, end: AlignmentDirectional.bottomEnd),
              ),
              child: Stack(fit: StackFit.loose, children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Padding(
                      padding: contentSpec.titleInsets,
                      child: Text(
                        widget.titleText,
                        textAlign: TextAlign.center,
                        style: widget.titleTextStyle ?? TextStyle(color: const Color(0xff191B32), fontSize: contentSpec.titleFontSize),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.only(top: contentSpec.firstGiftTopSpace),
                      child: buildGiftWidget(0),
                    ),
                    SizedBox(
                      height: contentSpec.secondGiftTopSpace,
                    ),
                    Row(
                      children: [
                        Expanded(child: Container()),
                        buildGiftWidget(1),
                        SizedBox(
                          width: contentSpec.giftsSpace,
                        ),
                        buildGiftWidget(2),
                        Expanded(child: Container()),
                      ],
                    ),
                    StreamBuilder<List<GiftConfig>>(
                        stream: totalGiftStream,
                        builder: (context, snapshot) {
                          List<GiftConfig>? list = snapshot.data;
                          if (list != null && list.isEmpty) {
                            return Container();
                          }


                          list?.forEach((element) {
                            if(element.state == GiftState.claimed){
                              _tipText = element.claimTipText;
                            }
                          });
                          return Padding(
                            padding: EdgeInsets.only(top: contentSpec.guideTextTopSpace, bottom: contentSpec.guideTextBottomSpace),
                            child: Text(
                              _tipText,
                              style: widget.guideTextStyle ?? TextStyle(fontSize: contentSpec.guideTextFontSize, color: const Color(0xff191B32)),
                            ),
                          );
                        })
                  ],
                ),
                Positioned(
                    left: contentSpec.closeIconInsets.left,
                    top: contentSpec.closeIconInsets.top,
                    child: GestureDetector(
                      onTap: () {
                        widget.closeCallback?.call();
                      },
                      child: widget.closeImage ??
                          Icon(
                            Icons.close,
                            size: contentSpec.closeIconSize.height,
                          ),
                    ))
              ]),
            ),
          ),
        ),
      ],
    ));
  }

  Widget buildGiftWidget(index) {
    GiftConfig config = widget.giftList[index];
    return StreamBuilder<GiftConfig?>(
        stream: giftSubjects[index].stream,
        builder: (context, snapshot) {
          GiftConfig? giftConfig = snapshot.data;
          if (giftConfig == null) {
            return Container();
          }
          return GestureDetector(
              onTap: () async {
                if (giftConfig.state == GiftState.claimed) {

                  return;
                }
                Completer adCompleter = Completer();
                Completer<bool> collectionCompleter = Completer<bool>();
                config.giftCallback.call(adCompleter, collectionCompleter, giftConfig);
                await adCompleter.future;

                await collectionCompleter.future.then((result) {

                  if (result) {
                    giftSubjects[index].add(giftConfig.derive(updateState: GiftState.claimed));
                  }
                });
              },
              child: AnimatedTransformContainer.sequentially(
                height: contentSpec.giftHeight,
                width: contentSpec.giftWidth,
                animations: [
                  TransformAnimation(fromOpacity: 0, toOpacity: 0, duration: Duration(milliseconds: 200)),
                  TransformAnimation(
                    fromOpacity: 0.2,
                    toOpacity: 1.0,
                    fromScale: 0.2,
                    toScale: 1.0,
                    curve: Curves.easeOutBack,
                    duration:const Duration(milliseconds: 600),
                  )
                ],
                child: SizedBox(
                    height: contentSpec.giftHeight,
                    child: Stack(
                      children: [
                        giftConfig.state == GiftState.claimed ? giftConfig.claimedGift : giftConfig.unclaimedGift,
                        Positioned(
                            right: contentSpec.watchAdImageRightSpace,
                            bottom: contentSpec.watchAdImageBottomSpace,
                            child: Visibility(
                                visible: config.watchAds && config.state != GiftState.claimed,
                                child: Container(
                                    constraints: BoxConstraints(maxWidth: contentSpec.watchAdImageWidth),
                                    width: contentSpec.watchAdImageWidth,
                                    height: contentSpec.watchAdImageHeight,
                                    child: widget.watchAdImage)))
                      ],
                    )),
              ));
        });
  }
}

enum GiftState { idle, unclaimed, claimed }
enum GiftIndex{first,second,third}
class GiftConfig {
  final GiftIndex index;
  final GiftState state;
  final bool watchAds;
  final Image unclaimedGift;
  final Image claimedGift;
  final String claimTipText;
  final Function(Completer adCompleter, Completer collectionCompleter, GiftConfig giftConfig) giftCallback;
  GiftConfig(this.index, this.unclaimedGift, this.claimedGift, this.giftCallback,
      {this.claimTipText = "", this.state = GiftState.idle, this.watchAds = false});

  GiftConfig derive({GiftState? updateState, bool watchAds = false}) =>
      GiftConfig(index, unclaimedGift, claimedGift, giftCallback, state: updateState ?? state, watchAds: watchAds, claimTipText: claimTipText);
}
