import 'dart:math';
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:mnemo_cards/di/locator.dart';
import 'package:mnemo_cards/features/yandex_ads/yandex_ads.dart';
import 'package:flutter/painting.dart';
import 'package:mnemo_cards/utils/color_helper.dart';
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:yandex_mobileads/mobile_ads.dart';

import '../features/card_flipper/flip_card.dart';
import '../features/card_flipper/flip_card_controllers.dart';
import '../features/card_flipper/flip_side.dart';
import '../theme/themes.dart';
import 'image_fade.dart';
import 'mnemo_text.dart';

class GameCardWidget extends StatefulWidget {
  static const borderRadius = 32.0;

  final GameCardDto card;
  final MemoryImage? image;
  final bool showFront;
  final bool isFirstCard;
  final FlipCardController? flipCardController;
  final Color? backColor;

  const GameCardWidget(
    this.card,
    this.image,
    this.flipCardController,
    this.showFront,
    this.isFirstCard,
    this.backColor, {
    super.key,
  });

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

class GameCardDecoration extends StatelessWidget {
  final Widget child;
  final double alpha;
  final Color? borderColor;

  GameCardDecoration({
    required this.child,
    this.alpha = 1.0,
    this.borderColor,
  });

  @override
  Widget build(BuildContext context) => Container(
        padding: EdgeInsets.all(8.0 * alpha),
        margin: EdgeInsets.only(
          left: 10.0 * alpha,
          right: 10.0 * alpha,
          bottom: 2.0 * alpha,
          top: 0.0 * alpha,
        ),
        decoration: BoxDecoration(
          color: Colors.white,
          boxShadow: [
            if (alpha > 0)
              BoxShadow(
                color: Colors.black.withOpacity(0.25 * alpha),
                blurRadius: 4.0 * alpha,
              ),
          ],
          borderRadius: BorderRadius.circular(
              12 + (GameCardWidget.borderRadius - 12) * alpha),
          border: Border.all(
            color: (borderColor ?? borderGray).withOpacity(1.0 - alpha * alpha),
          ),
        ),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(
              8 + (GameCardWidget.borderRadius - 8) * alpha),
          child: child,
        ),
      );
}

class _GameCardWidgetState extends State<GameCardWidget> {
  FlipCardController? get _flipCardController => widget.flipCardController;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context).textTheme;
    print('${widget.card.original}');

    final frontWidget = FrontCard(widget.card, widget.image);
    final backWidget = _BackWidget(
      widget.card,
      widget.backColor,
    );
    Duration? dragStart;
    Duration? dragUpdate;

    return GameCardDecoration(
      child: Material(
        color: Colors.transparent,
        child: GestureDetector(
          onVerticalDragStart: (start) {
            dragStart = start.sourceTimeStamp;
          },
          onVerticalDragUpdate: (update) {
            dragUpdate = update.sourceTimeStamp;
          },
          onVerticalDragEnd: (update) {
            final pps = update.velocity.pixelsPerSecond;
            if (widget.isFirstCard &&
                pps.dy.abs() > 2 * pps.dx.abs() &&
                pps.dy.abs() > 70 &&
                (dragStart != null &&
                    dragUpdate != null &&
                    (dragUpdate!.inMilliseconds - dragStart!.inMilliseconds) >
                        50)) {
              _flipCardController?.flipcard();
            }
          },
          behavior: HitTestBehavior.deferToChild,
          onDoubleTap: () async {
            await locator.favoriteCardsController
                .switchFavoriteCard(widget.card);
          },
          child: (widget.isFirstCard)
              ? FlipCard(
                  rotateSide: RotateSide.left,
                  onTapFlipping: false,
                  axis: FlipAxis.horizontal,
                  controller: _flipCardController!,
                  frontWidget: frontWidget,
                  backWidget: backWidget,
                )
              : widget.showFront
                  ? frontWidget
                  : backWidget,
        ),
      ),
    );
  }
}

class _BackWidget extends StatelessWidget {
  final GameCardDto card;
  final Color? _backColor;

  const _BackWidget(
    this.card,
    this._backColor,
  );

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context).textTheme;
    final backColor = _backColor ?? Colors.lightBlueAccent[200];
    return Container(
      padding: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        color: backColor,
        boxShadow: const [BoxShadow()],
        borderRadius: BorderRadius.circular(32.0),
      ),
      child: Center(
        child: MnemoText(
          card.back?.isNotEmpty == true ? card.back : card.translation ?? '',
          textStyle: theme.displayMedium!.copyWith(color: Colors.white),
          maxLines: 2,
          softWrap: true,
        ),
      ),
    );
  }
}

class FrontCard extends StatelessWidget {
  final GameCardDto card;
  final MemoryImage? image;
  final double alpha;

  FrontCard(this.card, this.image, {super.key, this.alpha = 1.0});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context).textTheme;
    return StatefulBuilder(builder: (context, setState) {
      return AbsorbPointer(
        absorbing: alpha != 1,
        child: LayoutBuilder(builder: (context, constrains) {
          const targetTextAr = 10 / 9;
          const targetImageAr = 16 / 9;
          double ar = constrains.maxHeight / constrains.maxWidth;
          if (constrains.maxHeight.isInfinite) {
            ar = 16 / 9;
          }
          final textScale = min(1.0, ar / targetTextAr) * alpha * alpha;
          final imageScale =
              0.9 * min(1.0, pow(ar / targetImageAr, 1.5 * alpha));
          return Material(
            borderOnForeground: false,
            type: MaterialType.transparency,
            child: Stack(
              alignment: Alignment.center,
              children: [
                Padding(
                  padding: EdgeInsets.all(8.0 * imageScale * (alpha / 2 + 0.5)),
                  child: Column(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: ar > 1
                        ? MainAxisAlignment.spaceEvenly
                        : MainAxisAlignment.spaceAround,
                    children: [
                      Column(
                        children: [
                          GestureDetector(
                            child: MnemoText(
                              card.original ?? '',
                              textStyle: TextStyle(
                                fontSize: 15 * textScale + 12,
                                fontWeight: FontWeight.w600,
                              ),
                              maxLines: 1,
                            ),
                            onTap: () async {
                              final sp = await SharedPreferences.getInstance();
                              if (sp.getBool('sound_on') != false &&
                                  card.original != null) {
                                FlutterTts flutterTts = FlutterTts();
                                await flutterTts.setLanguage('es-ES');
                                await flutterTts.setSpeechRate(0.4);
                                flutterTts.speak(card.original!);
                              }
                            },
                          ),
                          GestureDetector(
                            onTap: () async {
                              final sp = await SharedPreferences.getInstance();
                              if (sp.getBool('sound_on') != false &&
                                  card.translation != null) {
                                FlutterTts flutterTts = FlutterTts();
                                await flutterTts.setLanguage('ru');
                                await flutterTts.setSpeechRate(0.5);
                                flutterTts.speak(
                                  card.translation!,
                                );
                              }
                            },
                            child: MnemoText(
                              card.translation?.toLowerCase(),
                              textStyle: TextStyle(
                                fontSize: 12 * textScale * alpha + 8,
                                fontWeight: FontWeight.w400,
                                color: theme.headlineSmall!.color!
                                    .withOpacity(0.5),
                              ),
                              maxLines: 1,
                            ),
                          ),
                          if (alpha > 0 &&
                              ar > 1 &&
                              card.transcription != null &&
                              card.transcriptionMnemo != null)
                            Padding(
                              padding: EdgeInsets.only(top: 4.0.h * alpha),
                              child: GestureDetector(
                                onTap: () async {
                                  final sp =
                                      await SharedPreferences.getInstance();
                                  if (sp.getBool('sound_on') != false) {
                                    FlutterTts flutterTts = FlutterTts();
                                    await flutterTts.setLanguage('ru');
                                    await flutterTts.setSpeechRate(0.5);
                                    flutterTts.speak(
                                      "${card.transcription} - ${card.transcriptionMnemo}",
                                    );
                                  }
                                },
                                child: MnemoText(
                                  "[${card.transcription}] - ${card.transcriptionMnemo}",
                                  textStyle: TextStyle(
                                    fontSize: 20 * textScale * alpha,
                                    fontWeight: FontWeight.w400,
                                  ),
                                  textAlign: TextAlign.center,
                                  maxLines: 2,
                                  // group: smallSize,
                                ),
                              ),
                            ),
                        ],
                      ),
                      Container(
                        width: constrains.maxHeight / ar * imageScale,
                        height: constrains.maxHeight / ar * imageScale,
                        clipBehavior: Clip.antiAlias,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(
                          GameCardWidget.borderRadius * imageScale,
                        )),
                        child: ImageFade(
                          key: ValueKey(card.id),
                          image: image,
                          // fix for elapsedInSeconds < 0 in debug mode
                          syncDuration: Duration.zero,
                        ),
                      ),
                      GestureDetector(
                        onTap: () async {
                          if (card.mnemo?.trim().isNotEmpty != true) {
                            return;
                          }
                          final sp = await SharedPreferences.getInstance();
                          if (sp.getBool('sound_on') != false) {
                            FlutterTts flutterTts = FlutterTts();
                            await flutterTts.setLanguage('ru');
                            await flutterTts.setSpeechRate(0.5);
                            flutterTts.speak(
                                card.mnemo!.replaceAll(RegExp(r'[\]\[]'), ''));
                          }
                        },
                        child: MnemoText(
                          card.mnemo?.isNotEmpty == true ? card.mnemo : '  ',
                          textStyle: TextStyle(
                            fontSize: 20 * textScale,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
                if (alpha > 0)
                  Align(
                    alignment: ar > 4 / 3
                        ? Alignment.bottomCenter
                        : Alignment.topCenter,
                    child: Text(
                      "mnemo cards",
                      style: TextStyle(
                          fontSize: 10 * textScale, color: Colors.black26),
                      maxLines: 1,
                      // group: smallSize,
                    ),
                  ),
                if (false &&
                    alpha > 0 &&
                    locator.favoriteCardsController.isFavoriteCard(card.id))
                  Align(
                    alignment:
                        ar > 4 / 3 ? Alignment.bottomLeft : Alignment.topLeft,
                    child: Padding(
                      padding: EdgeInsets.all(8.0.w),
                      child: Image.asset(
                        "icons/heart.png",
                        width: 8.w,
                        height: 8.h,
                      ),
                    ),
                  ),
                if (alpha > 0)
                  Opacity(
                    opacity: alpha,
                    child: Container(
                      padding: EdgeInsets.all(4.0.h * alpha),
                      alignment: Alignment.topRight,
                      child: IconButton(
                        icon: Icon(
                          Icons.volume_up,
                          size: (26 * textScale).toDouble(),
                        ),
                        onPressed: () async {
                          final sp = await SharedPreferences.getInstance();
                          if (sp.getBool('sound_on') != false) {
                            FlutterTts flutterTts = FlutterTts();
                            await flutterTts.setLanguage('es-ES');
                            await flutterTts.setSpeechRate(0.5);
                            flutterTts.speak(card.original!);
                          }
                        },
                      ),
                    ),
                  ),
              ],
            ),
          );
        }),
      );
    });
  }
}

class _BannerWidget extends StatelessWidget {
  final BoxConstraints constraints;
  final String adId;
  final String adKey;
  late final BannerAd bannerAd;

  bool bannerLoaded = false;

  _BannerWidget(this.constraints, this.adId, this.adKey)
      : super(key: ValueKey(adKey));

  @override
  Widget build(BuildContext context) {
    BannerAd? bannerAd;
    bool bannerLoaded = false;
    return StatefulBuilder(builder: (context, setState) {
      bannerAd ??= YandexAds.createBanner(
        BoxConstraints(
          maxHeight: constraints.maxHeight,
          maxWidth: constraints.maxWidth,
        ),
        id: adId,
        key: adKey,
        onLoaded: () {
          bannerLoaded = true;
          setState(() {});
        },
      );
      return (bannerLoaded || true)
          ? Container(
              alignment: Alignment.center,
              child: AdWidget(
                bannerAd: bannerAd!,
              ),
            )
          : Center(
              child: CircularProgressIndicator(),
            );
    });
  }
}
