import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_swipe_detector/flutter_swipe_detector.dart';
import 'package:gshop/application/game/game_bloc.dart';
import 'package:gshop/infrastructure/service/services.dart';
import 'package:gshop/presentation/components/components.dart';
import 'package:gshop/presentation/style/style.dart';
import 'package:gshop/presentation/style/theme/theme_wrapper.dart';
import 'components/button.dart';
import 'components/emtpy_board.dart';
import 'components/score_board.dart';
import 'components/tile_board.dart';

class Game extends StatefulWidget {
  const Game({super.key});

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

class _GameState extends State<Game>
    with TickerProviderStateMixin, WidgetsBindingObserver {
  late final AnimationController _moveController = AnimationController(
    duration: const Duration(milliseconds: 75),
    vsync: this,
  )..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        context.read<GameBloc>().add(const GameEvent.merge());
        _scaleController.forward(from: 0.0);
      }
    });

  late final CurvedAnimation _moveAnimation = CurvedAnimation(
    parent: _moveController,
    curve: Curves.easeInOut,
  );

  late final AnimationController _scaleController = AnimationController(
    duration: const Duration(milliseconds: 200),
    vsync: this,
  )..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        context.read<GameBloc>().add(GameEvent.endRound(
            onSuccess: () {
              _moveController.forward(from: 0.0);
            },
            onFail: () {}));
      }
    });

  late final CurvedAnimation _scaleAnimation = CurvedAnimation(
    parent: _scaleController,
    curve: Curves.easeInOut,
  );

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return ThemeWrapper(builder: (colors, controller) {
      return Scaffold(
        backgroundColor: colors.backgroundColor,
        body: SafeArea(
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16.0),
                child: Column(
                  children: [
                    Row(
                      children: [
                        PopButton(color: colors.textBlack),
                        8.horizontalSpace,
                        Text(
                          AppHelpers.getTranslation(TrKeys.game),
                          style: CustomStyle.interNoSemi(
                              color: colors.textBlack, size: 18),
                        ),
                      ],
                    ),
                    32.verticalSpace,
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Column(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: [
                            Row(
                              children: [
                                ScoreBoard(
                                  colors: colors,
                                ),
                                32.horizontalSpace,
                                ButtonWidget(
                                  icon: Icons.undo,
                                  onPressed: () {
                                    context
                                        .read<GameBloc>()
                                        .add(const GameEvent.undo());
                                  },
                                  colors: colors,
                                ),
                                16.horizontalSpace,
                                ButtonWidget(
                                  colors: colors,
                                  icon: Icons.refresh,
                                  onPressed: () {
                                    //Restart the game
                                    context
                                        .read<GameBloc>()
                                        .add(const GameEvent.newGame());
                                  },
                                )
                              ],
                            ),
                          ],
                        )
                      ],
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 32.0,
              ),
              KeyboardListener(
                autofocus: true,
                focusNode: FocusNode(),
                onKeyEvent: (event) {
                  context.read<GameBloc>().add(GameEvent.onKey(
                      onSuccess: () {
                        _moveController.forward(from: 0.0);
                      },
                      onFail: () {},
                      event: event));
                },
                child: SwipeDetector(
                  onSwipe: (direction, offset) {
                    context.read<GameBloc>().add(GameEvent.move(
                        onSuccess: () {
                          _moveController.forward(from: 0.0);
                        },
                        onFail: () {},
                        direction: direction));
                  },
                  child: Stack(
                    children: [
                      const EmptyBoardWidget(),
                      TileBoardWidget(
                          colors: colors,
                          moveAnimation: _moveAnimation,
                          scaleAnimation: _scaleAnimation)
                    ],
                  ),
                ),
              )
            ],
          ),
        ),
      );
    });
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.inactive) {
      context.read<GameBloc>().add(const GameEvent.save());
    }
    super.didChangeAppLifecycleState(state);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);

    _moveAnimation.dispose();
    _scaleAnimation.dispose();
    _moveController.dispose();
    _scaleController.dispose();
    super.dispose();
  }
}
