// 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/modal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';

void main() {
  testWidgets(
    'showModal builds a new route with specified barrier properties',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: ElevatedButton(
                  onPressed: () {
                    showModal<void>(
                      context: context,
                      configuration: _TestModalConfiguration(),
                      builder: (BuildContext context) {
                        return const _FlutterLogoModal();
                      },
                    );
                  },
                  child: const Icon(Icons.add),
                ),
              );
            }),
          ),
        ),
      );
      await tester.tap(find.byType(ElevatedButton));
      await tester.pumpAndSettle();

      // New route containing _FlutterLogoModal is present.
      expect(find.byType(_FlutterLogoModal), findsOneWidget);
      final ModalBarrier topModalBarrier = tester.widget<ModalBarrier>(
        find.byType(ModalBarrier).at(1),
      );

      // Verify new route's modal barrier properties are correct.
      expect(topModalBarrier.color, Colors.green);
      expect(topModalBarrier.barrierSemanticsDismissible, true);
      expect(topModalBarrier.semanticsLabel, 'customLabel');
    },
  );

  testWidgets(
    'showModal forwards animation',
    (WidgetTester tester) async {
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: ElevatedButton(
                  onPressed: () {
                    showModal<void>(
                      context: context,
                      configuration: _TestModalConfiguration(),
                      builder: (BuildContext context) {
                        return _FlutterLogoModal(key: key);
                      },
                    );
                  },
                  child: const Icon(Icons.add),
                ),
              );
            }),
          ),
        ),
      );

      // Start forwards animation
      await tester.tap(find.byType(ElevatedButton));
      await tester.pump();

      // Opacity duration: Linear transition throughout 300ms
      double topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 0.0);

      // Halfway through forwards animation.
      await tester.pump(const Duration(milliseconds: 150));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 0.5);

      // The end of the transition.
      await tester.pump(const Duration(milliseconds: 150));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 1.0);

      await tester.pump(const Duration(milliseconds: 1));
      expect(find.byType(_FlutterLogoModal), findsOneWidget);
    },
  );

  testWidgets(
    'showModal reverse animation',
    (WidgetTester tester) async {
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: ElevatedButton(
                  onPressed: () {
                    showModal<void>(
                      context: context,
                      configuration: _TestModalConfiguration(),
                      builder: (BuildContext context) {
                        return _FlutterLogoModal(key: key);
                      },
                    );
                  },
                  child: const Icon(Icons.add),
                ),
              );
            }),
          ),
        ),
      );

      // Start forwards animation
      await tester.tap(find.byType(ElevatedButton));
      await tester.pumpAndSettle();
      expect(find.byType(_FlutterLogoModal), findsOneWidget);

      await tester.tapAt(Offset.zero);
      await tester.pump();

      // Opacity duration: Linear transition throughout 200ms
      double topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 1.0);

      // Halfway through forwards animation.
      await tester.pump(const Duration(milliseconds: 100));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 0.5);

      // The end of the transition.
      await tester.pump(const Duration(milliseconds: 100));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 0.0);

      await tester.pump(const Duration(milliseconds: 1));
      expect(find.byType(_FlutterLogoModal), findsNothing);
    },
  );

  testWidgets(
    'showModal builds a new route with specified barrier properties '
    'with default configuration(FadeScaleTransitionConfiguration)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: ElevatedButton(
                  onPressed: () {
                    showModal<void>(
                      context: context,
                      builder: (BuildContext context) {
                        return const _FlutterLogoModal();
                      },
                    );
                  },
                  child: const Icon(Icons.add),
                ),
              );
            }),
          ),
        ),
      );
      await tester.tap(find.byType(ElevatedButton));
      await tester.pumpAndSettle();

      // New route containing _FlutterLogoModal is present.
      expect(find.byType(_FlutterLogoModal), findsOneWidget);
      final ModalBarrier topModalBarrier = tester.widget<ModalBarrier>(
        find.byType(ModalBarrier).at(1),
      );

      // Verify new route's modal barrier properties are correct.
      expect(topModalBarrier.color, Colors.black54);
      expect(topModalBarrier.barrierSemanticsDismissible, true);
      expect(topModalBarrier.semanticsLabel, 'Dismiss');
    },
  );

  testWidgets(
    'showModal forwards animation '
    'with default configuration(FadeScaleTransitionConfiguration)',
    (WidgetTester tester) async {
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: ElevatedButton(
                  onPressed: () {
                    showModal<void>(
                      context: context,
                      builder: (BuildContext context) {
                        return _FlutterLogoModal(key: key);
                      },
                    );
                  },
                  child: const Icon(Icons.add),
                ),
              );
            }),
          ),
        ),
      );

      // Start forwards animation
      await tester.tap(find.byType(ElevatedButton));
      await tester.pump();

      // Opacity duration: First 30% of 150ms, linear transition
      double topFadeTransitionOpacity = _getOpacity(key, tester);
      double topScale = _getScale(key, tester);
      expect(topFadeTransitionOpacity, 0.0);
      expect(topScale, 0.80);

      // 3/10 * 150ms = 45ms (total opacity animation duration)
      // 1/2 * 45ms = ~23ms elapsed for halfway point of opacity
      // animation
      await tester.pump(const Duration(milliseconds: 23));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, closeTo(0.5, 0.05));
      topScale = _getScale(key, tester);
      expect(topScale, greaterThan(0.80));
      expect(topScale, lessThan(1.0));

      // End of opacity animation.
      await tester.pump(const Duration(milliseconds: 22));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 1.0);
      topScale = _getScale(key, tester);
      expect(topScale, greaterThan(0.80));
      expect(topScale, lessThan(1.0));

      // 100ms into the animation
      await tester.pump(const Duration(milliseconds: 55));
      topScale = _getScale(key, tester);
      expect(topScale, greaterThan(0.80));
      expect(topScale, lessThan(1.0));

      // Get to the end of the animation
      await tester.pump(const Duration(milliseconds: 50));
      topScale = _getScale(key, tester);
      expect(topScale, 1.0);

      await tester.pump(const Duration(milliseconds: 1));
      expect(find.byType(_FlutterLogoModal), findsOneWidget);
    },
  );

  testWidgets(
    'showModal reverse animation '
    'with default configuration(FadeScaleTransitionConfiguration)',
    (WidgetTester tester) async {
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: ElevatedButton(
                  onPressed: () {
                    showModal<void>(
                      context: context,
                      builder: (BuildContext context) {
                        return _FlutterLogoModal(key: key);
                      },
                    );
                  },
                  child: const Icon(Icons.add),
                ),
              );
            }),
          ),
        ),
      );

      // Start forwards animation
      await tester.tap(find.byType(ElevatedButton));
      await tester.pumpAndSettle();
      expect(find.byType(_FlutterLogoModal), findsOneWidget);

      // Tap on modal barrier to start reverse animation.
      await tester.tapAt(Offset.zero);
      await tester.pump();

      // Opacity duration: Linear transition throughout 75ms
      // No scale animations on exit transition.
      double topFadeTransitionOpacity = _getOpacity(key, tester);
      double topScale = _getScale(key, tester);
      expect(topFadeTransitionOpacity, 1.0);
      expect(topScale, 1.0);

      await tester.pump(const Duration(milliseconds: 25));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      topScale = _getScale(key, tester);
      expect(topFadeTransitionOpacity, closeTo(0.66, 0.05));
      expect(topScale, 1.0);

      await tester.pump(const Duration(milliseconds: 25));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      topScale = _getScale(key, tester);
      expect(topFadeTransitionOpacity, closeTo(0.33, 0.05));
      expect(topScale, 1.0);

      // End of opacity animation
      await tester.pump(const Duration(milliseconds: 25));
      topFadeTransitionOpacity = _getOpacity(key, tester);
      expect(topFadeTransitionOpacity, 0.0);
      topScale = _getScale(key, tester);
      expect(topScale, 1.0);

      await tester.pump(const Duration(milliseconds: 1));
      expect(find.byType(_FlutterLogoModal), findsNothing);
    },
  );

  testWidgets(
    'State is not lost when transitioning',
    (WidgetTester tester) async {
      final GlobalKey bottomKey = GlobalKey();
      final GlobalKey topKey = GlobalKey();

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Builder(builder: (BuildContext context) {
              return Center(
                child: Column(
                  children: <Widget>[
                    ElevatedButton(
                      onPressed: () {
                        showModal<void>(
                          context: context,
                          configuration: _TestModalConfiguration(),
                          builder: (BuildContext context) {
                            return _FlutterLogoModal(
                              key: topKey,
                              name: 'top route',
                            );
                          },
                        );
                      },
                      child: const Icon(Icons.add),
                    ),
                    _FlutterLogoModal(
                      key: bottomKey,
                      name: 'bottom route',
                    ),
                  ],
                ),
              );
            }),
          ),
        ),
      );

      // The bottom route's state should already exist.
      final _FlutterLogoModalState bottomState = tester.state(
        find.byKey(bottomKey),
      );
      expect(bottomState.widget.name, 'bottom route');

      // Start the enter transition of the modal route.
      await tester.tap(find.byType(ElevatedButton));
      await tester.pump();
      await tester.pump();

      // The bottom route's state should be retained at the start of the
      // transition.
      expect(
        tester.state(find.byKey(bottomKey)),
        bottomState,
      );
      // The top route's state should be created.
      final _FlutterLogoModalState topState = tester.state(
        find.byKey(topKey),
      );
      expect(topState.widget.name, 'top route');

      // Halfway point of forwards animation.
      await tester.pump(const Duration(milliseconds: 150));
      expect(
        tester.state(find.byKey(bottomKey)),
        bottomState,
      );
      expect(
        tester.state(find.byKey(topKey)),
        topState,
      );

      // End the transition and see if top and bottom routes'
      // states persist.
      await tester.pumpAndSettle();
      expect(
        tester.state(find.byKey(
          bottomKey,
          skipOffstage: false,
        )),
        bottomState,
      );
      expect(
        tester.state(find.byKey(topKey)),
        topState,
      );

      // Start the reverse animation. Both top and bottom
      // routes' states should persist.
      await tester.tapAt(Offset.zero);
      await tester.pump();
      expect(
        tester.state(find.byKey(bottomKey)),
        bottomState,
      );
      expect(
        tester.state(find.byKey(topKey)),
        topState,
      );

      // Halfway point of the exit transition.
      await tester.pump(const Duration(milliseconds: 100));
      expect(
        tester.state(find.byKey(bottomKey)),
        bottomState,
      );
      expect(
        tester.state(find.byKey(topKey)),
        topState,
      );

      // End the exit transition. The bottom route's state should
      // persist, whereas the top route's state should no longer
      // be present.
      await tester.pumpAndSettle();
      expect(
        tester.state(find.byKey(bottomKey)),
        bottomState,
      );
      expect(find.byKey(topKey), findsNothing);
    },
  );
}

double _getOpacity(GlobalKey key, WidgetTester tester) {
  final Finder finder = find.ancestor(
    of: find.byKey(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(GlobalKey key, WidgetTester tester) {
  final Finder finder = find.ancestor(
    of: find.byKey(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 _FlutterLogoModal extends StatefulWidget {
  const _FlutterLogoModal({
    Key? key,
    this.name,
  }) : super(key: key);

  final String? name;

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

class _FlutterLogoModalState extends State<_FlutterLogoModal> {
  @override
  Widget build(BuildContext context) {
    return const Center(
      child: SizedBox(
        width: 250,
        height: 250,
        child: Material(
          child: Center(
            child: FlutterLogo(size: 250),
          ),
        ),
      ),
    );
  }
}

class _TestModalConfiguration extends ModalConfiguration {
  _TestModalConfiguration({
    Color barrierColor = Colors.green,
    bool barrierDismissible = true,
    String barrierLabel = 'customLabel',
    Duration transitionDuration = const Duration(milliseconds: 300),
    Duration reverseTransitionDuration = const Duration(milliseconds: 200),
  }) : super(
          barrierColor: barrierColor,
          barrierDismissible: barrierDismissible,
          barrierLabel: barrierLabel,
          transitionDuration: transitionDuration,
          reverseTransitionDuration: reverseTransitionDuration,
        );

  @override
  Widget transitionBuilder(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    return FadeTransition(
      opacity: animation,
      child: child,
    );
  }
}
