// 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.

@Tags(<String>['reduced-test-set'])

import 'package:fake_async/fake_async.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

class _MockAnimationController extends AnimationController {
  _MockAnimationController()
      : super(duration: const Duration(minutes: 1), vsync: const TestVSync());
  int forwardCalls = 0;
  int reverseCalls = 0;

  @override
  TickerFuture forward({double? from}) {
    forwardCalls++;
    return super.forward(from: from);
  }

  @override
  TickerFuture reverse({double? from}) {
    reverseCalls++;
    return super.reverse(from: from);
  }
}

void main() {
  Future<T> runFakeAsync<T>(Future<T> Function(FakeAsync time) f) async {
    return FakeAsync().run((FakeAsync time) async {
      bool pump = true;
      final Future<T> future = f(time).whenComplete(() => pump = false);
      while (pump) {
        time.flushMicrotasks();
      }
      return future;
    });
  }

  group('Raw Magnifier', () {
    testWidgets('should render with correct focal point and decoration',
        (WidgetTester tester) async {
      final Key appKey = UniqueKey();
      const Size magnifierSize = Size(100, 100);
      const Offset magnifierFocalPoint = Offset(50, 50);
      const Offset magnifierPosition = Offset(200, 200);
      const double magnificationScale = 2;

      await tester.pumpWidget(MaterialApp(
          key: appKey,
          home: Container(
            color: Colors.orange,
            width: double.infinity,
            height: double.infinity,
            child: Stack(
              children: <Widget>[
                Positioned(
                  // Positioned so that it is right in the center of the magnifier
                  // focal point.
                  left: magnifierPosition.dx + magnifierFocalPoint.dx,
                  top: magnifierPosition.dy + magnifierFocalPoint.dy,
                  child: Container(
                    color: Colors.pink,
                    // Since it is the size of the magnifier but over its
                    // magnificationScale, it should take up the whole magnifier.
                    width: (magnifierSize.width * 1.5) / magnificationScale,
                    height: (magnifierSize.height * 1.5) / magnificationScale,
                  ),
                ),
                Positioned(
                  left: magnifierPosition.dx,
                  top: magnifierPosition.dy,
                  child: const RawMagnifier(
                    size: magnifierSize,
                    focalPointOffset: magnifierFocalPoint,
                    magnificationScale: magnificationScale,
                    decoration: MagnifierDecoration(shadows: <BoxShadow>[
                      BoxShadow(
                        spreadRadius: 10,
                        blurRadius: 10,
                        color: Colors.green,
                        offset: Offset(5, 5),
                      ),
                    ]),
                  ),
                ),
              ],
            ),
          )));

      await tester.pumpAndSettle();

      // Should look like an orange screen, with two pink boxes.
      // One pink box is in the magnifier (so has a green shadow) and is double
      // size (from magnification). Also, the magnifier should be slightly orange
      // since it has opacity.
      await expectLater(
        find.byKey(appKey),
        matchesGoldenFile('widgets.magnifier.styled.png'),
      );
    }, skip: kIsWeb);  // [intended] Bdf does not display on web.

    group('transition states', () {
      final AnimationController animationController = AnimationController(
          vsync: const TestVSync(), duration: const Duration(minutes: 2));
      final MagnifierController magnifierController = MagnifierController();

      tearDown(() {
        animationController.value = 0;
        magnifierController.hide();

        magnifierController.removeFromOverlay();
      });

      testWidgets(
          'should immediately remove from overlay on no animation controller',
          (WidgetTester tester) async {
        await runFakeAsync((FakeAsync async) async {
          const RawMagnifier testMagnifier = RawMagnifier(
            size: Size(100, 100),
          );

          await tester.pumpWidget(const MaterialApp(
            home: Placeholder(),
          ));

          final BuildContext context =
              tester.firstElement(find.byType(Placeholder));

          magnifierController.show(
            context: context,
            builder: (BuildContext context) => testMagnifier,
          );

          WidgetsBinding.instance.scheduleFrame();
          await tester.pump();

          expect(magnifierController.overlayEntry, isNot(isNull));

          magnifierController.hide();
          WidgetsBinding.instance.scheduleFrame();
          await tester.pump();

          expect(magnifierController.overlayEntry, isNull);
        });
      });

      testWidgets('should update shown based on animation status',
          (WidgetTester tester) async {
        await runFakeAsync((FakeAsync async) async {
          final MagnifierController magnifierController =
              MagnifierController(animationController: animationController);

          const RawMagnifier testMagnifier = RawMagnifier(
            size: Size(100, 100),
          );

          await tester.pumpWidget(const MaterialApp(
            home: Placeholder(),
          ));

          final BuildContext context =
              tester.firstElement(find.byType(Placeholder));

          magnifierController.show(
            context: context,
            builder: (BuildContext context) => testMagnifier,
          );

          WidgetsBinding.instance.scheduleFrame();
          await tester.pump();

          // No time has passed, so the animation controller has not completed.
          expect(magnifierController.animationController?.status,
              AnimationStatus.forward);
          expect(magnifierController.shown, true);

          async.elapse(animationController.duration!);
          await tester.pumpAndSettle();

          expect(magnifierController.animationController?.status,
              AnimationStatus.completed);
          expect(magnifierController.shown, true);

          magnifierController.hide();

          WidgetsBinding.instance.scheduleFrame();
          await tester.pump();

          expect(magnifierController.animationController?.status,
              AnimationStatus.reverse);
          expect(magnifierController.shown, false);

          async.elapse(animationController.duration!);
          await tester.pumpAndSettle();

          expect(magnifierController.animationController?.status,
              AnimationStatus.dismissed);
          expect(magnifierController.shown, false);
        });
      });
    });
  });

  group('magnifier controller', () {
    final MagnifierController magnifierController = MagnifierController();

    tearDown(() {
      magnifierController.removeFromOverlay();
    });

    group('show', () {
      testWidgets('should insert below below widget', (WidgetTester tester) async {
        await tester.pumpWidget(const MaterialApp(
          home: Text('text'),
        ));

        final BuildContext context = tester.firstElement(find.byType(Text));

        final Widget fakeMagnifier = Placeholder(key: UniqueKey());
        final Widget fakeBefore = Placeholder(key: UniqueKey());

        final OverlayEntry fakeBeforeOverlayEntry =
            OverlayEntry(builder: (_) => fakeBefore);

        Overlay.of(context).insert(fakeBeforeOverlayEntry);
        magnifierController.show(
            context: context,
            builder: (_) => fakeMagnifier,
            below: fakeBeforeOverlayEntry);

        WidgetsBinding.instance.scheduleFrame();
        await tester.pumpAndSettle();

        final Iterable<Element> allOverlayChildren = find
            .descendant(
                of: find.byType(Overlay), matching: find.byType(Placeholder))
            .evaluate();

        // Expect the magnifier to be the first child, even though it was inserted
        // after the fakeBefore.
        expect(allOverlayChildren.last.widget.key, fakeBefore.key);
        expect(allOverlayChildren.first.widget.key, fakeMagnifier.key);
      });

      testWidgets('should insert newly built widget without animating out if overlay != null',
          (WidgetTester tester) async {
        await runFakeAsync((FakeAsync async) async {
          final _MockAnimationController animationController =
              _MockAnimationController();

          const RawMagnifier testMagnifier = RawMagnifier(
            size: Size(100, 100),
          );
          const RawMagnifier testMagnifier2 = RawMagnifier(
            size: Size(100, 100),
          );

          await tester.pumpWidget(const MaterialApp(
            home: Placeholder(),
          ));

          final BuildContext context =
              tester.firstElement(find.byType(Placeholder));

          magnifierController.show(
            context: context,
            builder: (BuildContext context) => testMagnifier,
          );

          WidgetsBinding.instance.scheduleFrame();
          await tester.pump();

          async.elapse(animationController.duration!);
          await tester.pumpAndSettle();

          magnifierController.show(context: context, builder: (_) => testMagnifier2);

          WidgetsBinding.instance.scheduleFrame();
          await tester.pump();

          expect(animationController.reverseCalls, 0,
              reason:
                  'should not have called reverse on animation controller due to force remove');

          expect(find.byWidget(testMagnifier2), findsOneWidget);
        });
      });
    });

    group('shift within bounds', () {
      final List<Rect> boundsRects = <Rect>[
        const Rect.fromLTRB(0, 0, 100, 100),
        const Rect.fromLTRB(0, 0, 100, 100),
        const Rect.fromLTRB(0, 0, 100, 100),
        const Rect.fromLTRB(0, 0, 100, 100),
      ];
      final List<Rect> inputRects = <Rect>[
        const Rect.fromLTRB(-100, -100, -80, -80),
        const Rect.fromLTRB(0, 0, 20, 20),
        const Rect.fromLTRB(110, 0, 120, 10),
        const Rect.fromLTRB(110, 110, 120, 120)
      ];
      final List<Rect> outputRects = <Rect>[
        const Rect.fromLTRB(0, 0, 20, 20),
        const Rect.fromLTRB(0, 0, 20, 20),
        const Rect.fromLTRB(90, 0, 100, 10),
        const Rect.fromLTRB(90, 90, 100, 100)
      ];

      for (int i = 0; i < boundsRects.length; i++) {
        test(
            'should shift ${inputRects[i]} to ${outputRects[i]} for bounds ${boundsRects[i]}',
            () {
          final Rect outputRect = MagnifierController.shiftWithinBounds(
              bounds: boundsRects[i], rect: inputRects[i]);
          expect(outputRect, outputRects[i]);
        });
      }
    });
  });
}
