// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:animations/src/fade_through_transition.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets(
      'FadeThroughPageTransitionsBuilder builds a FadeThroughTransition',
      (WidgetTester tester) async {
    final AnimationController animation = AnimationController(
      vsync: const TestVSync(),
    );
    final AnimationController secondaryAnimation = AnimationController(
      vsync: const TestVSync(),
    );

    await tester.pumpWidget(
        const FadeThroughPageTransitionsBuilder().buildTransitions<void>(
      null,
      null,
      animation,
      secondaryAnimation,
      const Placeholder(),
    ));

    expect(find.byType(FadeThroughTransition), findsOneWidget);
  });

  testWidgets('FadeThroughTransition runs forward',
      (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    const String bottomRoute = '/';
    const String topRoute = '/a';

    await tester.pumpWidget(
      _TestWidget(
        navigatorKey: navigator,
      ),
    );
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 1.0);
    expect(find.text(topRoute), findsNothing);

    navigator.currentState!.pushNamed(topRoute);
    await tester.pump();
    await tester.pump();

    // Bottom route is full size and fully visible.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 1.0);
    // top route is at 95% of full size and not visible yet.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 0.92);
    expect(_getOpacity(topRoute, tester), 0.0);

    // Jump to half-way through the fade out (total duration is 300ms, 6/12th of
    // that are fade out, so half-way is 300 * 6/12 / 2 = 45ms.
    await tester.pump(const Duration(milliseconds: 45));
    // Bottom route is fading out.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    final double bottomOpacity = _getOpacity(bottomRoute, tester);
    expect(bottomOpacity, lessThan(1.0));
    expect(bottomOpacity, greaterThan(0.0));
    // Top route is still invisible.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 0.92);
    expect(_getOpacity(topRoute, tester), 0.0);

    // Let's jump to the end of the fade-out.
    await tester.pump(const Duration(milliseconds: 45));
    // Bottom route is completely faded out.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 0.0);
    // Top route is still invisible.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 0.92);
    expect(_getOpacity(topRoute, tester), 0.0);

    // Let's jump to the middle of the fade-in.
    await tester.pump(const Duration(milliseconds: 105));
    // Bottom route is not visible.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 0.0);
    // Top route is fading/scaling in.
    expect(find.text(topRoute), findsOneWidget);
    final double topScale = _getScale(topRoute, tester);
    final double topOpacity = _getOpacity(topRoute, tester);
    expect(topScale, greaterThan(0.92));
    expect(topScale, lessThan(1.0));
    expect(topOpacity, greaterThan(0.0));
    expect(topOpacity, lessThan(1.0));

    // Let's jump to the end of the animation.
    await tester.pump(const Duration(milliseconds: 105));
    // Bottom route is not visible.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 0.0);
    // Top route fully scaled in and visible.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    expect(_getOpacity(topRoute, tester), 1.0);

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text(bottomRoute), findsNothing);
    expect(find.text(topRoute), findsOneWidget);
  });

  testWidgets('FadeThroughTransition runs backwards',
      (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    const String bottomRoute = '/';
    const String topRoute = '/a';

    await tester.pumpWidget(
      _TestWidget(
        navigatorKey: navigator,
      ),
    );
    navigator.currentState!.pushNamed('/a');
    await tester.pumpAndSettle();

    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    expect(_getOpacity(topRoute, tester), 1.0);
    expect(find.text(bottomRoute), findsNothing);

    navigator.currentState!.pop();
    await tester.pump();

    // Top route is full size and fully visible.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    expect(_getOpacity(topRoute, tester), 1.0);
    // Bottom route is at 95% of full size and not visible yet.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 0.92);
    expect(_getOpacity(bottomRoute, tester), 0.0);

    // Jump to half-way through the fade out (total duration is 300ms, 6/12th of
    // that are fade out, so half-way is 300 * 6/12 / 2 = 45ms.
    await tester.pump(const Duration(milliseconds: 45));
    // Bottom route is fading out.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    final double topOpacity = _getOpacity(topRoute, tester);
    expect(topOpacity, lessThan(1.0));
    expect(topOpacity, greaterThan(0.0));
    // Top route is still invisible.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 0.92);
    expect(_getOpacity(bottomRoute, tester), 0.0);

    // Let's jump to the end of the fade-out.
    await tester.pump(const Duration(milliseconds: 45));
    // Bottom route is completely faded out.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    expect(_getOpacity(topRoute, tester), 0.0);
    // Top route is still invisible.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(
      _getScale(bottomRoute, tester),
      moreOrLessEquals(0.92, epsilon: 0.005),
    );
    expect(
      _getOpacity(bottomRoute, tester),
      moreOrLessEquals(0.0, epsilon: 0.005),
    );

    // Let's jump to the middle of the fade-in.
    await tester.pump(const Duration(milliseconds: 105));
    // Bottom route is not visible.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    expect(_getOpacity(topRoute, tester), 0.0);
    // Top route is fading/scaling in.
    expect(find.text(bottomRoute), findsOneWidget);
    final double bottomScale = _getScale(bottomRoute, tester);
    final double bottomOpacity = _getOpacity(bottomRoute, tester);
    expect(bottomScale, greaterThan(0.96));
    expect(bottomScale, lessThan(1.0));
    expect(bottomOpacity, greaterThan(0.1));
    expect(bottomOpacity, lessThan(1.0));

    // Let's jump to the end of the animation.
    await tester.pump(const Duration(milliseconds: 105));
    // Bottom route is not visible.
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 1.0);
    expect(_getOpacity(topRoute, tester), 0.0);
    // Top route fully scaled in and visible.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 1.0);

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text(topRoute), findsNothing);
    expect(find.text(bottomRoute), findsOneWidget);
  });

  testWidgets('FadeThroughTransition does not jump when interrupted',
      (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    const String bottomRoute = '/';
    const String topRoute = '/a';

    await tester.pumpWidget(
      _TestWidget(
        navigatorKey: navigator,
      ),
    );
    expect(find.text(bottomRoute), findsOneWidget);
    expect(find.text(topRoute), findsNothing);

    navigator.currentState!.pushNamed(topRoute);
    await tester.pump();

    // Jump to halfway point of transition.
    await tester.pump(const Duration(milliseconds: 150));
    // Bottom route is fully faded out.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 0.0);
    // Top route is fading/scaling in.
    expect(find.text(topRoute), findsOneWidget);
    final double topScale = _getScale(topRoute, tester);
    final double topOpacity = _getOpacity(topRoute, tester);
    expect(topScale, greaterThan(0.92));
    expect(topScale, lessThan(1.0));
    expect(topOpacity, greaterThan(0.0));
    expect(topOpacity, lessThan(1.0));

    // Interrupt the transition with a pop.
    navigator.currentState!.pop();
    await tester.pump();
    // Noting changed.
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 0.0);
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), topScale);
    expect(_getOpacity(topRoute, tester), topOpacity);

    // Jump to the halfway point.
    await tester.pump(const Duration(milliseconds: 75));
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    final double bottomOpacity = _getOpacity(bottomRoute, tester);
    expect(bottomOpacity, greaterThan(0.0));
    expect(bottomOpacity, lessThan(1.0));
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), lessThan(topScale));
    expect(_getOpacity(topRoute, tester), lessThan(topOpacity));

    // Jump to the end.
    await tester.pump(const Duration(milliseconds: 75));
    expect(find.text(bottomRoute), findsOneWidget);
    expect(_getScale(bottomRoute, tester), 1.0);
    expect(_getOpacity(bottomRoute, tester), 1.0);
    expect(find.text(topRoute), findsOneWidget);
    expect(_getScale(topRoute, tester), 0.92);
    expect(_getOpacity(topRoute, tester), 0.0);

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text(topRoute), findsNothing);
    expect(find.text(bottomRoute), findsOneWidget);
  });

  testWidgets('State is not lost when transitioning',
      (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    const String bottomRoute = '/';
    const String topRoute = '/a';

    await tester.pumpWidget(
      _TestWidget(
        navigatorKey: navigator,
        contentBuilder: (RouteSettings settings) {
          return _StatefulTestWidget(
            key: ValueKey<String?>(settings.name),
            name: settings.name,
          );
        },
      ),
    );

    final _StatefulTestWidgetState bottomState =
        tester.state(find.byKey(const ValueKey<String?>(bottomRoute)));
    expect(bottomState.widget.name, bottomRoute);

    navigator.currentState!.pushNamed(topRoute);
    await tester.pump();
    await tester.pump();

    expect(
      tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
      bottomState,
    );
    final _StatefulTestWidgetState topState = tester.state(
      find.byKey(const ValueKey<String?>(topRoute)),
    );
    expect(topState.widget.name, topRoute);

    await tester.pump(const Duration(milliseconds: 150));
    expect(
      tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
      bottomState,
    );
    expect(
      tester.state(find.byKey(const ValueKey<String?>(topRoute))),
      topState,
    );

    await tester.pumpAndSettle();
    expect(
      tester.state(find.byKey(
        const ValueKey<String?>(bottomRoute),
        skipOffstage: false,
      )),
      bottomState,
    );
    expect(
      tester.state(find.byKey(const ValueKey<String?>(topRoute))),
      topState,
    );

    navigator.currentState!.pop();
    await tester.pump();

    expect(
      tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
      bottomState,
    );
    expect(
      tester.state(find.byKey(const ValueKey<String?>(topRoute))),
      topState,
    );

    await tester.pump(const Duration(milliseconds: 150));
    expect(
      tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
      bottomState,
    );
    expect(
      tester.state(find.byKey(const ValueKey<String?>(topRoute))),
      topState,
    );

    await tester.pumpAndSettle();
    expect(
      tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
      bottomState,
    );
    expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
  });

  testWidgets('should keep state', (WidgetTester tester) async {
    final AnimationController animation = AnimationController(
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 300),
    );
    final AnimationController secondaryAnimation = AnimationController(
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 300),
    );
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: FadeThroughTransition(
          child: const _StatefulTestWidget(name: 'Foo'),
          animation: animation,
          secondaryAnimation: secondaryAnimation,
        ),
      ),
    ));
    final State<StatefulWidget> state = tester.state(
      find.byType(_StatefulTestWidget),
    );
    expect(state, isNotNull);

    animation.forward();
    await tester.pump();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pumpAndSettle();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

    secondaryAnimation.forward();
    await tester.pump();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pumpAndSettle();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

    secondaryAnimation.reverse();
    await tester.pump();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pumpAndSettle();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

    animation.reverse();
    await tester.pump();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pump(const Duration(milliseconds: 150));
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    await tester.pumpAndSettle();
    expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
  });
}

double _getOpacity(String key, WidgetTester tester) {
  final Finder finder = find.ancestor(
    of: find.byKey(ValueKey<String?>(key)),
    matching: find.byType(FadeTransition),
  );
  return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
    final FadeTransition transition = widget as FadeTransition;
    return a * transition.opacity.value;
  });
}

double _getScale(String key, WidgetTester tester) {
  final Finder finder = find.ancestor(
    of: find.byKey(ValueKey<String?>(key)),
    matching: find.byType(ScaleTransition),
  );
  return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
    final ScaleTransition transition = widget as ScaleTransition;
    return a * transition.scale.value;
  });
}

class _TestWidget extends StatelessWidget {
  const _TestWidget({this.navigatorKey, this.contentBuilder});

  final Key? navigatorKey;
  final _ContentBuilder? contentBuilder;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navigatorKey as GlobalKey<NavigatorState>?,
      theme: ThemeData(
        platform: TargetPlatform.android,
        pageTransitionsTheme: const PageTransitionsTheme(
          builders: <TargetPlatform, PageTransitionsBuilder>{
            TargetPlatform.android: FadeThroughPageTransitionsBuilder(),
          },
        ),
      ),
      onGenerateRoute: (RouteSettings settings) {
        return MaterialPageRoute<void>(
          settings: settings,
          builder: (BuildContext context) {
            return contentBuilder != null
                ? contentBuilder!(settings)
                : Center(
                    key: ValueKey<String?>(settings.name),
                    child: Text(settings.name!),
                  );
          },
        );
      },
    );
  }
}

class _StatefulTestWidget extends StatefulWidget {
  const _StatefulTestWidget({Key? key, this.name}) : super(key: key);

  final String? name;

  @override
  State<_StatefulTestWidget> createState() => _StatefulTestWidgetState();
}

class _StatefulTestWidgetState extends State<_StatefulTestWidget> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.name!);
  }
}

typedef _ContentBuilder = Widget Function(RouteSettings settings);
