// 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'])
library;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  final Offset basicOffset = Offset(CupertinoMagnifier.kDefaultSize.width / 2,
       CupertinoMagnifier.kDefaultSize.height - CupertinoMagnifier.kMagnifierAboveFocalPoint);
  const Rect reasonableTextField = Rect.fromLTRB(0, 100, 200, 200);
  final MagnifierController magnifierController = MagnifierController();

  // Make sure that your gesture in magnifierInfo is within the line in magnifierInfo,
  // or else the magnifier status will stay hidden and this will not complete.
  Future<void> showCupertinoMagnifier(
    BuildContext context,
    WidgetTester tester,
    ValueNotifier<MagnifierInfo> magnifierInfo,
  ) async {
    final Future<void> magnifierShown = magnifierController.show(
        context: context,
        builder: (_) => CupertinoTextMagnifier(
              controller: magnifierController,
              magnifierInfo: magnifierInfo,
            ));

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

    await magnifierShown;
  }

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

  group('CupertinoTextEditingMagnifier', () {
    group('position', () {
      Offset getMagnifierPosition(WidgetTester tester) {
        final AnimatedPositioned animatedPositioned =
            tester.firstWidget(find.byType(AnimatedPositioned));
        return Offset(
            animatedPositioned.left ?? 0, animatedPositioned.top ?? 0);
      }

      testWidgets('should be at gesture position if does not violate any positioning rules', (WidgetTester tester) async {
        final Key fakeTextFieldKey = UniqueKey();
        final Key outerKey = UniqueKey();

        await tester.pumpWidget(
          ColoredBox(
            key: outerKey,
            color: const Color.fromARGB(255, 0, 255, 179),
            child: MaterialApp(
              home: Center(
                child: Container(
                  key: fakeTextFieldKey,
                  width: 10,
                  height: 10,
                  color: Colors.red,
                  child: const Placeholder(),
                ),
              ),
            ),
          ),
        );
        final BuildContext context = tester.element(find.byType(Placeholder));

        // Magnifier should be positioned directly over the red square.
        final RenderBox tapPointRenderBox =
            tester.firstRenderObject(find.byKey(fakeTextFieldKey)) as RenderBox;
        final Rect fakeTextFieldRect =
            tapPointRenderBox.localToGlobal(Offset.zero) & tapPointRenderBox.size;

        final ValueNotifier<MagnifierInfo> magnifier =
            ValueNotifier<MagnifierInfo>(
          MagnifierInfo(
            currentLineBoundaries: fakeTextFieldRect,
            fieldBounds: fakeTextFieldRect,
            caretRect: fakeTextFieldRect,
            // The tap position is dragBelow units below the text field.
            globalGesturePosition: fakeTextFieldRect.center,
          ),
        );

        await showCupertinoMagnifier(context, tester, magnifier);

        // Should show two red squares; original, and one in the magnifier,
        // directly ontop of one another.
        await expectLater(
          find.byKey(outerKey),
          matchesGoldenFile('cupertino_magnifier.position.default.png'),
        );
      });

      testWidgets('should never horizontally be outside of Screen Padding', (WidgetTester tester) async {
        await tester.pumpWidget(
          const MaterialApp(
            color: Color.fromARGB(7, 0, 129, 90),
            home: Placeholder(),
          ),
        );

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

        await showCupertinoMagnifier(
          context,
          tester,
          ValueNotifier<MagnifierInfo>(
            MagnifierInfo(
              currentLineBoundaries: reasonableTextField,
              fieldBounds: reasonableTextField,
              caretRect: reasonableTextField,
              // The tap position is far out of the right side of the app.
              globalGesturePosition:
                  Offset(MediaQuery.sizeOf(context).width + 100, 0),
            ),
          ),
        );

        // Should be less than the right edge, since we have padding.
        expect(getMagnifierPosition(tester).dx,
            lessThan(MediaQuery.sizeOf(context).width));
      });

      testWidgets('should have some vertical drag', (WidgetTester tester) async {
        final double dragPositionBelowTextField = reasonableTextField.center.dy + 30;

        await tester.pumpWidget(
          const MaterialApp(
            color: Color.fromARGB(7, 0, 129, 90),
            home: Placeholder(),
          ),
        );

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

        await showCupertinoMagnifier(
          context,
          tester,
          ValueNotifier<MagnifierInfo>(
            MagnifierInfo(
              currentLineBoundaries: reasonableTextField,
              fieldBounds: reasonableTextField,
              caretRect: reasonableTextField,
              // The tap position is dragBelow units below the text field.
              globalGesturePosition: Offset(
                  MediaQuery.sizeOf(context).width / 2,
                  dragPositionBelowTextField),
            ),
          ),
        );

        // The magnifier Y should be greater than the text field, since we "dragged" it down.
        expect(getMagnifierPosition(tester).dy + basicOffset.dy,
            greaterThan(reasonableTextField.center.dy));
        expect(getMagnifierPosition(tester).dy + basicOffset.dy,
            lessThan(dragPositionBelowTextField));
      });
    });

    group('status', () {
      testWidgets('should hide if gesture is far below the text field', (WidgetTester tester) async {
        await tester.pumpWidget(
          const MaterialApp(
            color: Color.fromARGB(7, 0, 129, 90),
            home: Placeholder(),
          ),
        );

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

        final ValueNotifier<MagnifierInfo> magnifierinfo =
            ValueNotifier<MagnifierInfo>(
          MagnifierInfo(
            currentLineBoundaries: reasonableTextField,
            fieldBounds: reasonableTextField,
            caretRect: reasonableTextField,
            // The tap position is dragBelow units below the text field.
            globalGesturePosition: Offset(
                MediaQuery.sizeOf(context).width / 2, reasonableTextField.top),
          ),
        );

        // Show the magnifier initally, so that we get it in a not hidden state.
        await showCupertinoMagnifier(context, tester, magnifierinfo);

        // Move the gesture to one that should hide it.
        magnifierinfo.value = MagnifierInfo(
            currentLineBoundaries: reasonableTextField,
            fieldBounds: reasonableTextField,
            caretRect: reasonableTextField,
            globalGesturePosition: magnifierinfo.value.globalGesturePosition + const Offset(0, 100),
        );
        await tester.pumpAndSettle();

        expect(magnifierController.shown, false);
        expect(magnifierController.overlayEntry, isNotNull);
      });

      testWidgets('should re-show if gesture moves back up',
          (WidgetTester tester) async {
        await tester.pumpWidget(
          const MaterialApp(
            color: Color.fromARGB(7, 0, 129, 90),
            home: Placeholder(),
          ),
        );

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

        final ValueNotifier<MagnifierInfo> magnifierInfo =
            ValueNotifier<MagnifierInfo>(
          MagnifierInfo(
            currentLineBoundaries: reasonableTextField,
            fieldBounds: reasonableTextField,
            caretRect: reasonableTextField,
            // The tap position is dragBelow units below the text field.
            globalGesturePosition: Offset(MediaQuery.sizeOf(context).width / 2, reasonableTextField.top),
          ),
        );

        // Show the magnifier initally, so that we get it in a not hidden state.
        await showCupertinoMagnifier(context, tester, magnifierInfo);

        // Move the gesture to one that should hide it.
        magnifierInfo.value = MagnifierInfo(
            currentLineBoundaries: reasonableTextField,
            fieldBounds: reasonableTextField,
            caretRect: reasonableTextField,
            globalGesturePosition:
                magnifierInfo.value.globalGesturePosition + const Offset(0, 100));
        await tester.pumpAndSettle();

        expect(magnifierController.shown, false);
        expect(magnifierController.overlayEntry, isNotNull);

        // Return the gesture to one that shows it.
        magnifierInfo.value = MagnifierInfo(
            currentLineBoundaries: reasonableTextField,
            fieldBounds: reasonableTextField,
            caretRect: reasonableTextField,
            globalGesturePosition: Offset(MediaQuery.sizeOf(context).width / 2,
                reasonableTextField.top));
        await tester.pumpAndSettle();

        expect(magnifierController.shown, true);
        expect(magnifierController.overlayEntry, isNotNull);
      });
    });
  });
}
