// 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() {
  group('DynamicGridView', () {
    testWidgets(
        'DynamicGridView works when using DynamicSliverGridDelegateWithFixedCrossAxisCount',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(400, 100);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView(
              gridDelegate:
                  const DynamicSliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
              ),
              children: List<Widget>.generate(
                50,
                (int index) => SizedBox(
                  height: index % 2 * 20 + 20,
                  child: Text('Index $index'),
                ),
              ),
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 0')), Offset.zero);
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 1')), const Offset(100.0, 0.0));
      expect(find.text('Index 2'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 2')), const Offset(200.0, 0.0));
      expect(find.text('Index 3'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 3')), const Offset(300.0, 0.0));
      expect(find.text('Index 4'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 4')), const Offset(0.0, 20.0));

      expect(find.text('Index 14'), findsNothing);
      expect(find.text('Index 47'), findsNothing);
      expect(find.text('Index 48'), findsNothing);
      expect(find.text('Index 49'), findsNothing);
    });

    testWidgets(
        'DynamicGridView works when using DynamicSliverGridDelegateWithMaxCrossAxisExtent',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(440, 100);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView(
              gridDelegate:
                  const DynamicSliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 100,
              ),
              children: List<Widget>.generate(
                50,
                (int index) => SizedBox(
                  height: index % 2 * 20 + 20,
                  child: Text('Index $index'),
                ),
              ),
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 0')), Offset.zero);
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 1')), const Offset(88.0, 0.0));
      expect(find.text('Index 2'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 2')), const Offset(176.0, 0.0));
      expect(find.text('Index 3'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 3')), const Offset(264.0, 0.0));
      expect(find.text('Index 4'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 4')), const Offset(352.0, 0.0));

      expect(find.text('Index 47'), findsNothing);
      expect(find.text('Index 48'), findsNothing);
      expect(find.text('Index 49'), findsNothing);
    });
  });
  group('DynamicGridView.staggered', () {
    testWidgets('DynamicGridView.staggered works with simple layout',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(400, 100);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView.staggered(
              crossAxisCount: 4,
              children: List<Widget>.generate(
                50,
                (int index) => SizedBox(
                  height: index % 2 * 50 + 20,
                  child: Text('Index $index'),
                ),
              ),
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 0')), Offset.zero);
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 1')), const Offset(100.0, 0.0));
      expect(find.text('Index 2'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 2')), const Offset(200.0, 0.0));
      expect(find.text('Index 3'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 3')), const Offset(300.0, 0.0));
      expect(find.text('Index 4'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 4')), const Offset(0.0, 20.0));
      expect(find.text('Index 5'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 5')),
        const Offset(200.0, 20.0),
      );
      expect(find.text('Index 6'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 6')), const Offset(0.0, 40.0));
      expect(find.text('Index 7'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 7')), const Offset(0.0, 60.0));

      expect(find.text('Index 12'), findsNothing); // 100 - 120
      expect(find.text('Index 47'), findsNothing);
      expect(find.text('Index 48'), findsNothing);
      expect(find.text('Index 49'), findsNothing);
    });
    testWidgets('DynamicGridView.staggered works with a horizontal grid',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(100, 500);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView.staggered(
              crossAxisCount: 4,
              scrollDirection: Axis.horizontal,
              children: List<Widget>.generate(
                50,
                (int index) => SizedBox(
                  width: index % 3 * 50 + 20,
                  child: Text('Index $index'),
                ),
              ),
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 0')), Offset.zero);
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 1')), const Offset(0.0, 125.0));
      expect(find.text('Index 2'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 2')), const Offset(0.0, 250.0));
      expect(find.text('Index 3'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 3')), const Offset(0.0, 375.0));
      expect(find.text('Index 4'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 4')), const Offset(20.0, 0.0));
      expect(find.text('Index 5'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 5')),
        const Offset(20.0, 375.0),
      );
      expect(find.text('Index 6'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 6')),
        const Offset(70.0, 125.0),
      );
      expect(find.text('Index 7'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 7')),
        const Offset(90.0, 0.0),
      );

      expect(find.text('Index 47'), findsNothing);
      expect(find.text('Index 48'), findsNothing);
      expect(find.text('Index 49'), findsNothing);
    });
    testWidgets('DynamicGridView.staggered works with a reversed grid',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(600, 200);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView.staggered(
              crossAxisCount: 4,
              reverse: true,
              children: List<Widget>.generate(
                50,
                (int index) => SizedBox(
                  height: index % 3 * 50 + 20,
                  child: Text('Index $index'),
                ),
              ),
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 0')),
        const Offset(0.0, 200.0),
      );
      expect(find.text('Index 1'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 1')),
        const Offset(150.0, 200.0),
      );
      expect(find.text('Index 2'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 2')),
        const Offset(300.0, 200.0),
      );
      expect(find.text('Index 3'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 3')),
        const Offset(450.0, 200.0),
      );
      expect(find.text('Index 4'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 4')),
        const Offset(0.0, 180.0),
      );
      expect(find.text('Index 5'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 5')),
        const Offset(450.0, 180.0),
      );
      expect(find.text('Index 6'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 6')),
        const Offset(150.0, 130.0),
      );
      expect(find.text('Index 7'), findsOneWidget);
      expect(
        tester.getBottomLeft(find.text('Index 7')),
        const Offset(0.0, 110.0),
      );

      expect(find.text('Index 47'), findsNothing);
      expect(find.text('Index 48'), findsNothing);
      expect(find.text('Index 49'), findsNothing);
    });

    testWidgets('DynamicGridView.staggered deletes children appropriately',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(600, 1000);
      tester.binding.window.devicePixelRatioTestValue = 1.0;
      final List<Widget> children = List<Widget>.generate(
        50,
        (int index) => SizedBox(
          height: index % 3 * 50 + 20,
          child: Text('Index $index'),
        ),
      );
      late StateSetter stateSetter;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
              stateSetter = setState;
              return DynamicGridView.staggered(
                maxCrossAxisExtent: 150,
                children: <Widget>[...children],
              );
            }),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 0')), Offset.zero);
      expect(find.text('Index 7'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 7')), const Offset(0.0, 90.0));
      expect(find.text('Index 8'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 8')),
        const Offset(150.0, 90.0),
      );
      expect(find.text('Index 27'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 27')),
        const Offset(300.0, 420.0),
      );
      expect(find.text('Index 28'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 28')),
        const Offset(300.0, 440.0),
      );
      expect(find.text('Index 32'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 32')),
        const Offset(300.0, 510.0),
      );
      expect(find.text('Index 33'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 33')),
        const Offset(150.0, 540.0),
      );

      stateSetter(() {
        children.removeAt(0);
      });

      await tester.pump();
      expect(find.text('Index 0'), findsNothing);

      expect(
        tester.getTopLeft(find.text('Index 8')),
        const Offset(0.0, 90.0),
      );
      expect(
        tester.getTopLeft(find.text('Index 28')),
        const Offset(150.0, 440.0),
      );
      expect(
        tester.getTopLeft(find.text('Index 33')),
        const Offset(0.0, 540.0),
      );
    });
  });
  group('DynamicGridView.builder', () {
    testWidgets('DynamicGridView.builder works with a staggered layout',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(400, 100);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView.builder(
              gridDelegate:
                  const DynamicSliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
              ),
              itemBuilder: (BuildContext context, int index) => SizedBox(
                height: index % 2 * 50 + 20,
                child: Text('Index $index'),
              ),
              itemCount: 50,
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 0')), Offset.zero);
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 1')), const Offset(100.0, 0.0));
      expect(find.text('Index 2'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 2')), const Offset(200.0, 0.0));
      expect(find.text('Index 3'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 3')), const Offset(300.0, 0.0));
      expect(find.text('Index 4'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 4')), const Offset(0.0, 20.0));
      expect(find.text('Index 5'), findsOneWidget);
      expect(
        tester.getTopLeft(find.text('Index 5')),
        const Offset(200.0, 20.0),
      );
      expect(find.text('Index 6'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 6')), const Offset(0.0, 40.0));
      expect(find.text('Index 7'), findsOneWidget);
      expect(tester.getTopLeft(find.text('Index 7')), const Offset(0.0, 60.0));

      expect(find.text('Index 12'), findsNothing); // 100 - 120
      expect(find.text('Index 47'), findsNothing);
      expect(find.text('Index 48'), findsNothing);
      expect(find.text('Index 49'), findsNothing);
    });

    testWidgets(
        'DynamicGridView.builder works with an infinite grid using a staggered layout',
        (WidgetTester tester) async {
      tester.binding.window.physicalSizeTestValue = const Size(400, 100);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: DynamicGridView.builder(
              gridDelegate:
                  const DynamicSliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
              ),
              itemBuilder: (BuildContext context, int index) => SizedBox(
                height: index % 2 * 50 + 20,
                child: Text('Index $index'),
              ),
            ),
          ),
        ),
      );

      expect(find.text('Index 0'), findsOneWidget);
      expect(find.text('Index 1'), findsOneWidget);
      expect(find.text('Index 2'), findsOneWidget);
      await tester.scrollUntilVisible(find.text('Index 500'), 500.0);
      await tester.pumpAndSettle();
      expect(find.text('Index 501'), findsOneWidget);
      expect(find.text('Index 502'), findsOneWidget);
    });
  });
}
