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

import 'package:flutter/src/widgets/dual_transition_builder.dart';

void main() {
  testWidgets('runs animations', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 300),
    );

    await tester.pumpWidget(Center(
      child: DualTransitionBuilder(
        animation: controller,
        forwardBuilder: (
          BuildContext context,
          Animation<double> animation,
          Widget? child,
        ) {
          return ScaleTransition(
            scale: animation,
            child: child,
          );
        },
        reverseBuilder: (
          BuildContext context,
          Animation<double> animation,
          Widget? child,
        ) {
          return FadeTransition(
            opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
            child: child,
          );
        },
        child: Container(
          color: Colors.green,
          height: 100,
          width: 100,
        ),
      ),
    ));
    expect(_getScale(tester), 0.0);
    expect(_getOpacity(tester), 1.0);

    controller.forward();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));
    expect(_getScale(tester), 0.5);
    expect(_getOpacity(tester), 1.0);

    await tester.pump(const Duration(milliseconds: 150));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 1.0);

    await tester.pumpAndSettle();
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 1.0);

    controller.reverse();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 0.5);

    await tester.pump(const Duration(milliseconds: 150));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 0.0);

    await tester.pumpAndSettle();
    expect(_getScale(tester), 0.0);
    expect(_getOpacity(tester), 1.0);
  });

  testWidgets('keeps state', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 300),
    );

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: DualTransitionBuilder(
          animation: controller,
          forwardBuilder: (
            BuildContext context,
            Animation<double> animation,
            Widget? child,
          ) {
            return ScaleTransition(
              scale: animation,
              child: child,
            );
          },
          reverseBuilder: (
            BuildContext context,
            Animation<double> animation,
            Widget? child,
          ) {
            return FadeTransition(
              opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
              child: child,
            );
          },
          child: const _StatefulTestWidget(name: 'Foo'),
        ),
      ),
    ));
    final State<StatefulWidget> state =
        tester.state(find.byType(_StatefulTestWidget));
    expect(state, isNotNull);

    controller.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))));

    controller.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))));
  });

  testWidgets('does not jump when interrupted - forward',
      (WidgetTester tester) async {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 300),
    );
    await tester.pumpWidget(Center(
      child: DualTransitionBuilder(
        animation: controller,
        forwardBuilder: (
          BuildContext context,
          Animation<double> animation,
          Widget? child,
        ) {
          return ScaleTransition(
            scale: animation,
            child: child,
          );
        },
        reverseBuilder: (
          BuildContext context,
          Animation<double> animation,
          Widget? child,
        ) {
          return FadeTransition(
            opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
            child: child,
          );
        },
        child: Container(
          color: Colors.green,
          height: 100,
          width: 100,
        ),
      ),
    ));
    expect(_getScale(tester), 0.0);
    expect(_getOpacity(tester), 1.0);

    controller.forward();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));
    expect(_getScale(tester), 0.5);
    expect(_getOpacity(tester), 1.0);

    controller.reverse();
    expect(_getScale(tester), 0.5);
    expect(_getOpacity(tester), 1.0);
    await tester.pump();
    expect(_getScale(tester), 0.5);
    expect(_getOpacity(tester), 1.0);

    await tester.pump(const Duration(milliseconds: 75));
    expect(_getScale(tester), 0.25);
    expect(_getOpacity(tester), 1.0);

    await tester.pump(const Duration(milliseconds: 75));
    expect(_getScale(tester), 0.0);
    expect(_getOpacity(tester), 1.0);

    await tester.pumpAndSettle();
    expect(_getScale(tester), 0.0);
    expect(_getOpacity(tester), 1.0);
  });

  testWidgets('does not jump when interrupted - reverse',
      (WidgetTester tester) async {
    final AnimationController controller = AnimationController(
      value: 1.0,
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 300),
    );
    await tester.pumpWidget(Center(
      child: DualTransitionBuilder(
        animation: controller,
        forwardBuilder: (
          BuildContext context,
          Animation<double> animation,
          Widget? child,
        ) {
          return ScaleTransition(
            scale: animation,
            child: child,
          );
        },
        reverseBuilder: (
          BuildContext context,
          Animation<double> animation,
          Widget? child,
        ) {
          return FadeTransition(
            opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
            child: child,
          );
        },
        child: Container(
          color: Colors.green,
          height: 100,
          width: 100,
        ),
      ),
    ));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 1.0);

    controller.reverse();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 0.5);

    controller.forward();
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 0.5);
    await tester.pump();
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 0.5);

    await tester.pump(const Duration(milliseconds: 75));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 0.75);

    await tester.pump(const Duration(milliseconds: 75));
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 1.0);

    await tester.pumpAndSettle();
    expect(_getScale(tester), 1.0);
    expect(_getOpacity(tester), 1.0);
  });
}

double _getScale(WidgetTester tester) {
  final ScaleTransition scale = tester.widget(find.byType(ScaleTransition));
  return scale.scale.value;
}

double _getOpacity(WidgetTester tester) {
  final FadeTransition scale = tester.widget(find.byType(FadeTransition));
  return scale.opacity.value;
}

class _StatefulTestWidget extends StatefulWidget {
  const _StatefulTestWidget({Key? key, required 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);
  }
}
