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

void main() {
  testWidgets(
      'DynamicGridView generates children and checks if they are layed out',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 95 : 180,
        child: Text('Item $index'),
      ),
    );
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView(
            gridDelegate: const SliverGridDelegateWithWrapping(),
            children: children,
          ),
        ),
      ),
    );

    // Check that the children are in the tree
    for (int i = 0; i < 10; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    // Check that the children are in the right position
    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(95.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(275.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(370.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 4')), const Offset(550.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 5')), const Offset(0.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 6')), const Offset(180.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 7')), const Offset(275.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 8')), const Offset(455.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 9')), const Offset(550.0, 100.0));
  });

  testWidgets(
      'Test for wrap that generates children and checks if they are layed out',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 95 : 180,
        child: Text('Item $index'),
      ),
    );
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.wrap(
            children: children,
          ),
        ),
      ),
    );
    for (int i = 0; i < 10; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    // Check that the children are in the right position
    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(95.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(275.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(370.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 4')), const Offset(550.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 5')), const Offset(0.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 6')), const Offset(180.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 7')), const Offset(275.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 8')), const Offset(455.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 9')), const Offset(550.0, 100.0));
  });

  testWidgets('Test for wrap to be laying child dynamically',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      20,
      (int index) => SizedBox(
        height: index.isEven ? 1000 : 50,
        width: index.isEven ? 95 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.builder(
            itemCount: children.length,
            gridDelegate: const SliverGridDelegateWithWrapping(),
            itemBuilder: (BuildContext context, int index) => children[index],
          ),
        ),
      ),
    );
    for (int i = 0; i < 5; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    // Check that the children are in the right position
    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(95.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(275.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(370.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 4')), const Offset(550.0, 0.0));
    expect(find.text('Item 5'), findsNothing);
    await tester.scrollUntilVisible(find.text('Item 19'), 500.0);
    await tester.pumpAndSettle();

    expect(find.text('Item 18'), findsOneWidget);
    expect(tester.getTopLeft(find.text('Item 18')), const Offset(455.0, 0.0));

    expect(find.text('Item 0'), findsNothing);
    expect(find.text('Item 1'), findsNothing);
    expect(find.text('Item 2'), findsNothing);
    expect(find.text('Item 3'), findsNothing);
  });

  testWidgets(
      'Test for DynamicGridView.wrap to scrollDirection Axis.horizontal',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      20,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.wrap(
            scrollDirection: Axis.horizontal,
            children: children,
          ),
        ),
      ),
    );
    for (int i = 0; i < 20; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    // Check that the children are in the right position
    double dy = 0, dx = 0;
    for (int i = 0; i < 20; i++) {
      if (dy >= 600.0) {
        dy = 0.0;
        dx += 180.0;
      }
      expect(tester.getTopLeft(find.text('Item $i')), Offset(dx, dy));
      dy += i.isEven ? 100 : 50;
    }
  });

  testWidgets('Test DynamicGridView.builder for GridView.reverse to true',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.builder(
            reverse: true,
            itemCount: children.length,
            gridDelegate: const SliverGridDelegateWithWrapping(),
            itemBuilder: (BuildContext context, int index) => children[index],
          ),
        ),
      ),
    );
    for (int i = 0; i < 10; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    double dx = 0.0, dy = 600.0;
    for (int i = 0; i < 10; i++) {
      if (dx >= 600.0) {
        dx = 0.0;
        dy -= 100.0;
      }
      expect(tester.getBottomLeft(find.text('Item $i')), Offset(dx, dy));
      dx += i.isEven ? 100 : 180;
    }
  });

  testWidgets('DynamicGridView.wrap for GridView.reverse to true',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      20,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.wrap(
            reverse: true,
            children: children,
          ),
        ),
      ),
    );
    for (int i = 0; i < 20; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    // Check that the children are in the right position
    double dx = 0.0, dy = 600.0;
    for (int i = 0; i < 20; i++) {
      if (dx >= 600.0) {
        dx = 0.0;
        dy -= 100.0;
      }
      expect(tester.getBottomLeft(find.text('Item $i')), Offset(dx, dy));
      dx += i.isEven ? 100 : 180;
    }
  });

  testWidgets('DynamicGridView.wrap dismiss keyboard onDrag test',
      (WidgetTester tester) async {
    final List<FocusNode> focusNodes =
        List<FocusNode>.generate(50, (int i) => FocusNode());

    await tester.pumpWidget(
      textFieldBoilerplate(
        child: GridView.extent(
          padding: EdgeInsets.zero,
          maxCrossAxisExtent: 300,
          keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
          children: focusNodes.map((FocusNode focusNode) {
            return Container(
              height: 50,
              color: Colors.green,
              child: TextField(
                focusNode: focusNode,
                style: const TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );

    final Finder finder = find.byType(TextField).first;
    final TextField textField = tester.widget(finder);
    await tester.showKeyboard(finder);
    expect(textField.focusNode!.hasFocus, isTrue);

    await tester.drag(finder, const Offset(0.0, -40.0));
    await tester.pumpAndSettle();
    expect(textField.focusNode!.hasFocus, isFalse);
  });

  testWidgets('ChildMainAxisExtent & childCrossAxisExtent are respected',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        key: Key(index.toString()),
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.builder(
            gridDelegate: const SliverGridDelegateWithWrapping(
              childMainAxisExtent: 150,
              childCrossAxisExtent: 200,
            ),
            itemCount: children.length,
            itemBuilder: (BuildContext context, int index) => children[index],
          ),
        ),
      ),
    );

    for (int i = 0; i < 10; i++) {
      final Size sizeOfCurrent = tester.getSize(find.byKey(Key('$i')));
      expect(sizeOfCurrent.width, equals(200));
      expect(sizeOfCurrent.height, equals(150));
    }
    // Check that the children are in the right position
    double dy = 0, dx = 0;
    for (int i = 0; i < 10; i++) {
      if (dx > 600.0) {
        dx = 0.0;
        dy += 150.0;
      }
      expect(tester.getTopLeft(find.text('Item $i')), Offset(dx, dy));
      dx += 200;
    }
  });

  testWidgets('ChildMainAxisExtent is respected', (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        key: Key(index.toString()),
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.builder(
            gridDelegate: const SliverGridDelegateWithWrapping(
              childMainAxisExtent: 200,
            ),
            itemCount: children.length,
            itemBuilder: (BuildContext context, int index) => children[index],
          ),
        ),
      ),
    );

    for (int i = 0; i < 10; i++) {
      final Size sizeOfCurrent = tester.getSize(find.byKey(Key('$i')));
      expect(sizeOfCurrent.height, equals(200));
    }
    // Check that the children are in the right position
    double dy = 0, dx = 0;
    for (int i = 0; i < 10; i++) {
      if (dx >= 600.0) {
        dx = 0.0;
        dy += 200.0;
      }
      expect(tester.getTopLeft(find.text('Item $i')), Offset(dx, dy));
      dx += i.isEven ? 100 : 180;
    }
  });

  testWidgets('ChildCrossAxisExtent is respected', (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        key: Key(index.toString()),
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.builder(
            gridDelegate: const SliverGridDelegateWithWrapping(
              childCrossAxisExtent: 150,
            ),
            itemCount: children.length,
            itemBuilder: (BuildContext context, int index) => children[index],
          ),
        ),
      ),
    );

    for (int i = 0; i < 10; i++) {
      final Size sizeOfCurrent = tester.getSize(find.byKey(Key('$i')));
      expect(sizeOfCurrent.width, equals(150));
    }
    // Check that the children are in the right position
    double dy = 0, dx = 0;
    for (int i = 0; i < 10; i++) {
      if (dx >= 750.0) {
        dx = 0.0;
        dy += 100.0;
      }
      expect(tester.getTopLeft(find.text('Item $i')), Offset(dx, dy));
      dx += 150;
    }
  });

  testWidgets('Test wrap to see nothing affected if elements are deleted.',
      (WidgetTester tester) async {
    late StateSetter stateSetter;
    final List<Widget> children = List<Widget>.generate(
      10,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
            stateSetter = setState;
            return DynamicGridView.builder(
              gridDelegate: const SliverGridDelegateWithWrapping(),
              itemCount: children.length,
              itemBuilder: (BuildContext context, int index) => children[index],
            );
          }),
        ),
      ),
    );
    // See if the children are in the tree.
    for (int i = 0; i < 10; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    // See if they are layed properly.
    double dx = 0.0, dy = 0.0;
    for (int i = 0; i < 10; i++) {
      if (dx >= 600) {
        dx = 0.0;
        dy += 100;
      }
      expect(tester.getTopLeft(find.text('Item $i')), Offset(dx, dy));
      dx += i.isEven ? 100 : 180;
    }
    stateSetter(() {
      // Remove children
      children.removeAt(0);
      children.removeAt(8);
      children.removeAt(5);
    });

    await tester.pump();

    // See if the proper widgets are in the tree.
    expect(find.text('Item 0'), findsNothing);
    expect(find.text('Item 6'), findsNothing);
    expect(find.text('Item 9'), findsNothing);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 3'), findsOneWidget);
    expect(find.text('Item 4'), findsOneWidget);
    expect(find.text('Item 5'), findsOneWidget);
    expect(find.text('Item 7'), findsOneWidget);
    expect(find.text('Item 8'), findsOneWidget);

    // See if the proper widgets are in the tree.
    expect(tester.getTopLeft(find.text('Item 1')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(180.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(280.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 4')), const Offset(460.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 5')), const Offset(560.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 7')), const Offset(0.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 8')), const Offset(180.0, 100.0));
  });

  testWidgets('Test wrap in Axis.vertical direction',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      5,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.builder(
            itemCount: children.length,
            gridDelegate: const SliverGridDelegateWithWrapping(),
            itemBuilder: (BuildContext context, int index) => children[index],
          ),
        ),
      ),
    );

    // Change the size of the screen
    await tester.binding.setSurfaceSize(const Size(500, 100));
    await tester.pumpAndSettle();
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(100.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(280.0, 0.0));
    expect(find.text('Item 3'), findsNothing);
    expect(find.text('Item 4'), findsNothing);
    await tester.binding.setSurfaceSize(const Size(560, 100));
    await tester.pumpAndSettle();
    expect(find.text('Item 3'), findsOneWidget);
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(380.0, 0.0));
    expect(find.text('Item 4'), findsNothing);
    await tester.binding.setSurfaceSize(const Size(280, 100));
    // resets the screen to its original size after the test end
    addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
    await tester.pumpAndSettle();
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(100.0, 0.0));
    expect(find.text('Item 2'), findsNothing);
    expect(find.text('Item 3'), findsNothing);
    expect(find.text('Item 4'), findsNothing);
  });

  testWidgets('Test wrap in Axis.horizontal direction',
      (WidgetTester tester) async {
    final List<Widget> children = List<Widget>.generate(
      5,
      (int index) => SizedBox(
        height: index.isEven ? 100 : 50,
        width: index.isEven ? 100 : 180,
        child: Text('Item $index'),
      ),
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: DynamicGridView.wrap(
            scrollDirection: Axis.horizontal,
            children: children,
          ),
        ),
      ),
    );

    // Change the size of the screen
    await tester.binding.setSurfaceSize(const Size(180, 150));
    await tester.pumpAndSettle();

    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(0.0, 100.0));

    expect(find.text('Item 2'), findsNothing);
    expect(find.text('Item 3'), findsNothing);

    await tester.binding.setSurfaceSize(const Size(180, 400));
    await tester.pumpAndSettle();

    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 3'), findsOneWidget);
    expect(find.text('Item 4'), findsOneWidget);

    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(0.0, 100.0));
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(0.0, 150.0));
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(0.0, 250.0));
    expect(tester.getTopLeft(find.text('Item 4')), const Offset(0.0, 300.0));

    await tester.binding.setSurfaceSize(const Size(560, 100));
    // resets the screen to its original size after the test end
    addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
    await tester.pumpAndSettle();

    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 3'), findsOneWidget);
    expect(find.text('Item 4'), findsNothing);

    expect(tester.getTopLeft(find.text('Item 0')), Offset.zero);
    expect(tester.getTopLeft(find.text('Item 1')), const Offset(100.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 2')), const Offset(280.0, 0.0));
    expect(tester.getTopLeft(find.text('Item 3')), const Offset(380.0, 0.0));
  });
}

Widget textFieldBoilerplate({required Widget child}) {
  return MaterialApp(
    home: Localizations(
      locale: const Locale('en', 'US'),
      delegates: <LocalizationsDelegate<dynamic>>[
        WidgetsLocalizationsDelegate(),
        MaterialLocalizationsDelegate(),
      ],
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(size: Size(800.0, 600.0)),
          child: Center(
            child: Material(
              child: child,
            ),
          ),
        ),
      ),
    ),
  );
}

class MaterialLocalizationsDelegate
    extends LocalizationsDelegate<MaterialLocalizations> {
  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<MaterialLocalizations> load(Locale locale) =>
      DefaultMaterialLocalizations.load(locale);

  @override
  bool shouldReload(MaterialLocalizationsDelegate old) => false;
}

class WidgetsLocalizationsDelegate
    extends LocalizationsDelegate<WidgetsLocalizations> {
  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<WidgetsLocalizations> load(Locale locale) =>
      DefaultWidgetsLocalizations.load(locale);

  @override
  bool shouldReload(WidgetsLocalizationsDelegate old) => false;
}
