// 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 'dart:ui';

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

void main() {
  testWidgets('CarouselView defaults', (WidgetTester tester) async {
    final theme = ThemeData();
    final ColorScheme colorScheme = theme.colorScheme;

    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Finder carouselViewMaterial = find
        .descendant(of: find.byType(CarouselView), matching: find.byType(Material))
        .first;

    final Material material = tester.widget<Material>(carouselViewMaterial);
    expect(material.clipBehavior, Clip.antiAlias);
    expect(material.color, colorScheme.surface);
    expect(material.elevation, 0.0);
    expect(
      material.shape,
      const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0))),
    );
  });

  testWidgets('CarouselView items customization', (WidgetTester tester) async {
    final Key key = UniqueKey();
    final theme = ThemeData();

    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: Scaffold(
          body: CarouselView(
            padding: const EdgeInsets.all(20.0),
            backgroundColor: Colors.amber,
            elevation: 10.0,
            shape: const StadiumBorder(),
            overlayColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
              if (states.contains(WidgetState.pressed)) {
                return Colors.yellow;
              }
              if (states.contains(WidgetState.hovered)) {
                return Colors.red;
              }
              if (states.contains(WidgetState.focused)) {
                return Colors.purple;
              }
              return null;
            }),
            itemExtent: 200,
            children: List<Widget>.generate(10, (int index) {
              if (index == 0) {
                return Center(
                  key: key,
                  child: Center(child: Text('Item $index')),
                );
              }
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Finder carouselViewMaterial = find
        .descendant(of: find.byType(CarouselView), matching: find.byType(Material))
        .first;

    expect(
      tester.getSize(carouselViewMaterial).width,
      200 - 20 - 20,
    ); // Padding is 20 on both side.
    final Material material = tester.widget<Material>(carouselViewMaterial);
    expect(material.color, Colors.amber);
    expect(material.elevation, 10.0);
    expect(material.shape, const StadiumBorder());

    RenderObject inkFeatures = tester.allRenderObjects.firstWhere(
      (RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures',
    );

    // On hovered.
    final TestGesture gesture = await hoverPointerOverCarouselItem(tester, key);
    await tester.pumpAndSettle();
    expect(inkFeatures, paints..rect(color: Colors.red.withOpacity(1.0)));

    // On pressed.
    await tester.pumpAndSettle();
    await gesture.down(tester.getCenter(find.byKey(key)));
    await tester.pumpAndSettle();
    inkFeatures = tester.allRenderObjects.firstWhere(
      (RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures',
    );
    expect(
      inkFeatures,
      paints
        ..rect()
        ..rect(color: Colors.yellow.withOpacity(1.0)),
    );

    await tester.pumpAndSettle();
    await gesture.up();
    await gesture.removePointer();

    // On focused.
    final Element inkWellElement = tester.element(
      find.descendant(of: carouselViewMaterial, matching: find.byType(InkWell)),
    );
    expect(inkWellElement.widget, isA<InkWell>());
    final inkWell = inkWellElement.widget as InkWell;

    const WidgetState state = WidgetState.focused;

    // Check overlay color in focused state.
    expect(inkWell.overlayColor?.resolve(<WidgetState>{state}), Colors.purple);
  });

  testWidgets('CarouselView respects onTap', (WidgetTester tester) async {
    final keys = List<Key>.generate(10, (_) => UniqueKey());
    final theme = ThemeData();
    var tapIndex = 0;

    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: Scaffold(
          body: CarouselView(
            itemExtent: 50,
            onTap: (int index) {
              tapIndex = index;
            },
            children: List<Widget>.generate(10, (int index) {
              return Center(key: keys[index], child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Finder item1 = find.byKey(keys[1]);
    await tester.tap(find.ancestor(of: item1, matching: find.byType(Stack)));
    await tester.pump();
    expect(tapIndex, 1);

    final Finder item2 = find.byKey(keys[2]);
    await tester.tap(find.ancestor(of: item2, matching: find.byType(Stack)));
    await tester.pump();
    expect(tapIndex, 2);
  });

  testWidgets('CarouselView layout (Uncontained layout)', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 250,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.sizeOf(tester.element(find.byType(CarouselView)));
    expect(viewportSize, const Size(800, 600));

    expect(find.text('Item 0'), findsOneWidget);
    final Rect rect0 = tester.getRect(getItem(0));
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 250.0, 600.0));

    expect(find.text('Item 1'), findsOneWidget);
    final Rect rect1 = tester.getRect(getItem(1));
    expect(rect1, const Rect.fromLTRB(250.0, 0.0, 500.0, 600.0));

    expect(find.text('Item 2'), findsOneWidget);
    final Rect rect2 = tester.getRect(getItem(2));
    expect(rect2, const Rect.fromLTRB(500.0, 0.0, 750.0, 600.0));

    expect(find.text('Item 3'), findsOneWidget);
    final Rect rect3 = tester.getRect(getItem(3));
    expect(rect3, const Rect.fromLTRB(750.0, 0.0, 800.0, 600.0));

    expect(find.text('Item 4'), findsNothing);
  });

  testWidgets('CarouselView.weighted layout', (WidgetTester tester) async {
    Widget buildCarouselView({required List<int> weights}) {
      return MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: weights,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildCarouselView(weights: <int>[4, 3, 2, 1]));

    final Size viewportSize = MediaQuery.of(tester.element(find.byType(CarouselView))).size;
    expect(viewportSize, const Size(800, 600));

    expect(find.text('Item 0'), findsOneWidget);
    Rect rect0 = tester.getRect(getItem(0));
    // Item width is 4/10 of the viewport.
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 320.0, 600.0));

    expect(find.text('Item 1'), findsOneWidget);
    Rect rect1 = tester.getRect(getItem(1));
    // Item width is 3/10 of the viewport.
    expect(rect1, const Rect.fromLTRB(320.0, 0.0, 560.0, 600.0));

    expect(find.text('Item 2'), findsOneWidget);
    final Rect rect2 = tester.getRect(getItem(2));
    // Item width is 2/10 of the viewport.
    expect(rect2, const Rect.fromLTRB(560.0, 0.0, 720.0, 600.0));

    expect(find.text('Item 3'), findsOneWidget);
    final Rect rect3 = tester.getRect(getItem(3));
    // Item width is 1/10 of the viewport.
    expect(rect3, const Rect.fromLTRB(720.0, 0.0, 800.0, 600.0));

    expect(find.text('Item 4'), findsNothing);

    // Test shorter weight list.
    await tester.pumpWidget(buildCarouselView(weights: <int>[7, 1]));
    await tester.pumpAndSettle();
    expect(viewportSize, const Size(800, 600));

    expect(find.text('Item 0'), findsOneWidget);
    rect0 = tester.getRect(getItem(0));
    // Item width is 7/8 of the viewport.
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 700.0, 600.0));

    expect(find.text('Item 1'), findsOneWidget);
    rect1 = tester.getRect(getItem(1));
    // Item width is 1/8 of the viewport.
    expect(rect1, const Rect.fromLTRB(700.0, 0.0, 800.0, 600.0));

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

  testWidgets('CarouselController initialItem', (WidgetTester tester) async {
    final controller = CarouselController(initialItem: 5);
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            controller: controller,
            itemExtent: 400,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.sizeOf(tester.element(find.byType(CarouselView)));
    expect(viewportSize, const Size(800, 600));

    expect(find.text('Item 5'), findsOneWidget);
    final Rect rect5 = tester.getRect(getItem(5));
    // Item width is 400.
    expect(rect5, const Rect.fromLTRB(0.0, 0.0, 400.0, 600.0));

    expect(find.text('Item 6'), findsOneWidget);
    final Rect rect6 = tester.getRect(getItem(6));
    // Item width is 400.
    expect(rect6, const Rect.fromLTRB(400.0, 0.0, 800.0, 600.0));

    expect(find.text('Item 4'), findsNothing);
    expect(find.text('Item 7'), findsNothing);
  });

  testWidgets('CarouselView.weighted respects CarouselController.initialItem', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController(initialItem: 5);
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            controller: controller,
            flexWeights: const <int>[7, 1],
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.of(tester.element(find.byType(CarouselView))).size;
    expect(viewportSize, const Size(800, 600));

    expect(find.text('Item 5'), findsOneWidget);
    final Rect rect5 = tester.getRect(getItem(5));
    // Item width is 7/8 of the viewport.
    expect(rect5, const Rect.fromLTRB(0.0, 0.0, 700.0, 600.0));

    expect(find.text('Item 6'), findsOneWidget);
    final Rect rect6 = tester.getRect(getItem(6));
    // Item width is 1/8 of the viewport.
    expect(rect6, const Rect.fromLTRB(700.0, 0.0, 800.0, 600.0));

    expect(find.text('Item 4'), findsNothing);
    expect(find.text('Item 7'), findsNothing);
  });

  testWidgets('The initialItem should be the first item with expanded size(max extent)', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController(initialItem: 5);
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            controller: controller,
            flexWeights: const <int>[1, 8, 1],
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.of(tester.element(find.byType(CarouselView))).size;
    expect(viewportSize, const Size(800, 600));

    // Item 5 should have be the expanded item.
    expect(find.text('Item 5'), findsOneWidget);
    final Rect rect5 = tester.getRect(getItem(5));
    // Item width is 8/10 of the viewport.
    expect(rect5, const Rect.fromLTRB(80.0, 0.0, 720.0, 600.0));

    expect(find.text('Item 6'), findsOneWidget);
    final Rect rect6 = tester.getRect(getItem(6));
    // Item width is 1/10 of the viewport.
    expect(rect6, const Rect.fromLTRB(720.0, 0.0, 800.0, 600.0));

    expect(find.text('Item 4'), findsOneWidget);
    final Rect rect4 = tester.getRect(getItem(4));
    // Item width is 1/10 of the viewport.
    expect(rect4, const Rect.fromLTRB(0.0, 0.0, 80.0, 600.0));

    expect(find.text('Item 7'), findsNothing);
  });

  testWidgets('CarouselView respects itemSnapping', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemSnapping: true,
            itemExtent: 300,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    void checkOriginalExpectations() {
      expect(getItem(0), findsOneWidget);
      expect(getItem(1), findsOneWidget);
      expect(getItem(2), findsOneWidget);
      expect(getItem(3), findsNothing);
    }

    checkOriginalExpectations();

    // Snap back to the original item.
    await tester.drag(getItem(0), const Offset(-150, 0));
    await tester.pumpAndSettle();

    checkOriginalExpectations();

    // Snap back to the original item.
    await tester.drag(getItem(0), const Offset(100, 0));
    await tester.pumpAndSettle();

    checkOriginalExpectations();

    // Snap to the next item.
    await tester.drag(getItem(0), const Offset(-200, 0));
    await tester.pumpAndSettle();

    expect(getItem(0), findsNothing);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
  });

  testWidgets('CarouselView.weighted respects itemSnapping', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            itemSnapping: true,
            consumeMaxWeight: false,
            flexWeights: const <int>[1, 7],
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    void checkOriginalExpectations() {
      expect(getItem(0), findsOneWidget);
      expect(getItem(1), findsOneWidget);
      expect(getItem(2), findsNothing);
    }

    checkOriginalExpectations();

    // Snap back to the original item.
    await tester.drag(getItem(0), const Offset(-20, 0));
    await tester.pumpAndSettle();

    checkOriginalExpectations();

    // Snap back to the original item.
    await tester.drag(getItem(0), const Offset(50, 0));
    await tester.pumpAndSettle();

    checkOriginalExpectations();

    // Snap to the next item.
    await tester.drag(getItem(0), const Offset(-70, 0));
    await tester.pumpAndSettle();

    expect(getItem(0), findsNothing);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsNothing);
  });

  testWidgets('CarouselView respect itemSnapping when fling', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemSnapping: true,
            itemExtent: 300,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    // Show item 0, 1, and 2.
    expect(getItem(0), findsOneWidget);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsNothing);

    // Snap to the next item. Show item 1, 2 and 3.
    await tester.fling(getItem(0), const Offset(-100, 0), 800);
    await tester.pumpAndSettle();

    expect(getItem(0), findsNothing);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsNothing);

    // Snap to the next item. Show item 2, 3 and 4.
    await tester.fling(getItem(1), const Offset(-100, 0), 800);
    await tester.pumpAndSettle();

    expect(getItem(0), findsNothing);
    expect(getItem(1), findsNothing);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsOneWidget);
    expect(getItem(5), findsNothing);

    // Fling back to the previous item. Show item 1, 2 and 3.
    await tester.fling(getItem(2), const Offset(100, 0), 800);
    await tester.pumpAndSettle();

    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsNothing);
  });

  testWidgets('CarouselView.weighted respect itemSnapping when fling', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            itemSnapping: true,
            consumeMaxWeight: false,
            flexWeights: const <int>[1, 8, 1],
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('$index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    Finder getItem(int index) => find.descendant(
      of: find.byType(CarouselView),
      matching: find.ancestor(of: find.text('$index'), matching: find.byType(Padding)),
    );

    // Show item 0, 1, and 2.
    expect(getItem(0), findsOneWidget);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsNothing);

    // Should snap to item 2 because of a long drag(-100). Show item 2, 3 and 4.
    await tester.fling(getItem(0), const Offset(-100, 0), 800);
    await tester.pumpAndSettle();

    expect(getItem(0), findsNothing);
    expect(getItem(1), findsNothing);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsOneWidget);

    // Fling to the next item (item 3). Show item 3, 4 and 5.
    await tester.fling(getItem(2), const Offset(-50, 0), 800);
    await tester.pumpAndSettle();

    expect(getItem(2), findsNothing);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsOneWidget);
    expect(getItem(5), findsOneWidget);

    // Fling back to the previous item. Show item 2, 3 and 4.
    await tester.fling(getItem(3), const Offset(50, 0), 800);
    await tester.pumpAndSettle();

    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsOneWidget);
    expect(getItem(5), findsNothing);
  });

  testWidgets('CarouselView respects scrollingDirection: Axis.vertical', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            padding: EdgeInsets.zero,
            scrollDirection: Axis.vertical,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getItem(0), findsOneWidget);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsNothing);
    final Rect rect0 = tester.getRect(getItem(0));
    // Item width is 200 of the viewport.
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0));

    // Simulate a scroll up
    await tester.drag(
      find.byType(CarouselView),
      const Offset(0, -200),
      kind: PointerDeviceKind.trackpad,
    );
    await tester.pumpAndSettle();
    expect(getItem(0), findsNothing);
    expect(getItem(3), findsOneWidget);
  });

  testWidgets('CarouselView.weighted respects scrollingDirection: Axis.vertical', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[3, 2, 1],
            padding: EdgeInsets.zero,
            scrollDirection: Axis.vertical,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getItem(0), findsOneWidget);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsNothing);
    final Rect rect0 = tester.getRect(getItem(0));
    // Item width is 3/6 of the viewport.
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 800.0, 300.0));

    // Simulate a scroll up
    await tester.drag(
      find.byType(CarouselView),
      const Offset(0, -300),
      kind: PointerDeviceKind.trackpad,
    );
    await tester.pumpAndSettle();
    expect(getItem(0), findsNothing);
    expect(getItem(3), findsOneWidget);
  });

  testWidgets(
    'CarouselView.weighted respects scrollingDirection: Axis.vertical + itemSnapping: true',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView.weighted(
              itemSnapping: true,
              flexWeights: const <int>[3, 2, 1],
              scrollDirection: Axis.vertical,
              children: List<Widget>.generate(10, (int index) {
                return Center(child: Text('Item $index'));
              }),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();

      expect(getItem(0), findsOneWidget);
      expect(getItem(1), findsOneWidget);
      expect(getItem(2), findsOneWidget);
      expect(getItem(3), findsNothing);
      final Rect rect0 = tester.getRect(getItem(0));
      // Item width is 3/6 of the viewport.
      expect(rect0, const Rect.fromLTRB(0.0, 0.0, 800.0, 300.0));

      // Simulate a scroll up but less than half of the leading item, the leading
      // item should go back to the original position because itemSnapping is set
      // to true.
      await tester.drag(
        find.byType(CarouselView),
        const Offset(0, -149),
        kind: PointerDeviceKind.trackpad,
      );
      await tester.pumpAndSettle();
      expect(getItem(0), findsOneWidget);
      expect(getItem(1), findsOneWidget);
      expect(getItem(2), findsOneWidget);
      expect(getItem(3), findsNothing);

      // Simulate a scroll up more than half of the leading item, the leading
      // item continue to scrolling and will disappear when animation ends because
      // itemSnapping is set to true.
      await tester.drag(
        find.byType(CarouselView),
        const Offset(0, -151),
        kind: PointerDeviceKind.trackpad,
      );
      await tester.pumpAndSettle();
      expect(getItem(0), findsNothing);
      expect(getItem(3), findsOneWidget);
    },
  );

  testWidgets('CarouselView respects reverse', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            reverse: true,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getItem(0), findsOneWidget);
    final Rect rect0 = tester.getRect(getItem(0));
    // Item 0 should be placed on the end of the screen.
    expect(rect0, const Rect.fromLTRB(600.0, 0.0, 800.0, 600.0));

    expect(getItem(1), findsOneWidget);
    final Rect rect1 = tester.getRect(getItem(1));
    // Item 1 should be placed before item 0.
    expect(rect1, const Rect.fromLTRB(400.0, 0.0, 600.0, 600.0));

    expect(getItem(2), findsOneWidget);
    final Rect rect2 = tester.getRect(getItem(2));
    // Item 2 should be placed before item 1.
    expect(rect2, const Rect.fromLTRB(200.0, 0.0, 400.0, 600.0));

    expect(getItem(3), findsOneWidget);
    final Rect rect3 = tester.getRect(getItem(3));
    // Item 3 should be placed before item 2.
    expect(rect3, const Rect.fromLTRB(0.0, 0.0, 200.0, 600.0));
  });

  testWidgets('CarouselView.weighted respects reverse', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[4, 3, 2, 1],
            reverse: true,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getItem(0), findsOneWidget);
    final Rect rect0 = tester.getRect(getItem(0));
    // Item 0 should be placed on the end of the screen.
    const int item0Width = 80 * 4;
    expect(rect0, const Rect.fromLTRB(800.0 - item0Width, 0.0, 800.0, 600.0));

    expect(getItem(1), findsOneWidget);
    final Rect rect1 = tester.getRect(getItem(1));
    // Item 1 should be placed before item 0.
    const int item1Width = 80 * 3;
    expect(
      rect1,
      const Rect.fromLTRB(800.0 - item0Width - item1Width, 0.0, 800.0 - item0Width, 600.0),
    );

    expect(getItem(2), findsOneWidget);
    final Rect rect2 = tester.getRect(getItem(2));
    // Item 2 should be placed before item 1.
    const int item2Width = 80 * 2;
    expect(
      rect2,
      const Rect.fromLTRB(
        800.0 - item0Width - item1Width - item2Width,
        0.0,
        800.0 - item0Width - item1Width,
        600.0,
      ),
    );

    expect(getItem(3), findsOneWidget);
    final Rect rect3 = tester.getRect(getItem(3));
    // Item 3 should be placed before item 2.
    expect(
      rect3,
      const Rect.fromLTRB(0.0, 0.0, 800.0 - item0Width - item1Width - item2Width, 600.0),
    );
  });

  testWidgets('CarouselView.weighted respects reverse + vertical scroll direction', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            reverse: true,
            flexWeights: const <int>[4, 3, 2, 1],
            scrollDirection: Axis.vertical,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getItem(0), findsOneWidget);
    final Rect rect0 = tester.getRect(getItem(0));
    // Item 0 should be placed on the end of the screen.
    const int item0Height = 60 * 4;
    expect(rect0, const Rect.fromLTRB(0.0, 600.0 - item0Height, 800.0, 600.0));

    expect(getItem(1), findsOneWidget);
    final Rect rect1 = tester.getRect(getItem(1));
    // Item 1 should be placed before item 0.
    const int item1Height = 60 * 3;
    expect(
      rect1,
      const Rect.fromLTRB(0.0, 600.0 - item0Height - item1Height, 800.0, 600.0 - item0Height),
    );

    expect(getItem(2), findsOneWidget);
    final Rect rect2 = tester.getRect(getItem(2));
    // Item 2 should be placed before item 1.
    const int item2Height = 60 * 2;
    expect(
      rect2,
      const Rect.fromLTRB(
        0.0,
        600.0 - item0Height - item1Height - item2Height,
        800.0,
        600.0 - item0Height - item1Height,
      ),
    );

    expect(getItem(3), findsOneWidget);
    final Rect rect3 = tester.getRect(getItem(3));
    // Item 3 should be placed before item 2.
    expect(
      rect3,
      const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0 - item0Height - item1Height - item2Height),
    );
  });

  testWidgets('CarouselView.weighted respects reverse + vertical scroll direction + itemSnapping', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            reverse: true,
            flexWeights: const <int>[4, 3, 2, 1],
            scrollDirection: Axis.vertical,
            itemSnapping: true,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getItem(0), findsOneWidget);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsNothing);
    final Rect rect0 = tester.getRect(getItem(0));
    // Item height is 4/10 of the viewport.
    expect(rect0, const Rect.fromLTRB(0.0, 360.0, 800.0, 600.0));

    // Simulate a scroll down but less than half of the leading item, the leading
    // item should go back to the original position because itemSnapping is set
    // to true.
    await tester.drag(
      find.byType(CarouselView),
      const Offset(0, 240 / 2 - 1),
      kind: PointerDeviceKind.trackpad,
    );
    await tester.pumpAndSettle();
    expect(getItem(0), findsOneWidget);
    expect(getItem(1), findsOneWidget);
    expect(getItem(2), findsOneWidget);
    expect(getItem(3), findsOneWidget);
    expect(getItem(4), findsNothing);

    // Simulate a scroll down more than half of the leading item, the leading
    // item continue to scrolling and will disappear when animation ends because
    // itemSnapping is set to true.
    await tester.drag(
      find.byType(CarouselView),
      const Offset(0, 240 / 2 + 1),
      kind: PointerDeviceKind.trackpad,
    );
    await tester.pumpAndSettle();
    expect(getItem(0), findsNothing);
    expect(getItem(4), findsOneWidget);
  });

  testWidgets('CarouselView respects shrinkExtent', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 350,
            shrinkExtent: 300,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    final Rect rect0 = tester.getRect(getItem(0));
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 350.0, 600.0));

    final Rect rect1 = tester.getRect(getItem(1));
    expect(rect1, const Rect.fromLTRB(350.0, 0.0, 700.0, 600.0));

    final Rect rect2 = tester.getRect(getItem(2));
    // The extent of item 2 is 300, and only 100 is on screen.
    expect(rect2, const Rect.fromLTRB(700.0, 0.0, 1000.0, 600.0));

    await tester.drag(
      find.byType(CarouselView),
      const Offset(-50, 0),
      kind: PointerDeviceKind.trackpad,
    );
    await tester.pump();
    // The item 0 should be pinned and has a size change from 350 to 50.
    expect(tester.getRect(getItem(0)), const Rect.fromLTRB(0.0, 0.0, 300.0, 600.0));
    // Keep dragging to left, extent of item 0 won't change (still 300) and part of item 0 will
    // be off screen.
    await tester.drag(
      find.byType(CarouselView),
      const Offset(-50, 0),
      kind: PointerDeviceKind.trackpad,
    );
    await tester.pump();
    expect(tester.getRect(getItem(0)), const Rect.fromLTRB(-50, 0.0, 250, 600));
  });

  testWidgets('CarouselView.weighted respects consumeMaxWeight', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[1, 2, 4, 2, 1],
            itemSnapping: true,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    // The initial item is item 0. To make sure the layout stays the same, the
    // first item should be placed at the middle of the screen and there are some
    // white space as if there are two more shinked items before the first item.
    final Rect rect0 = tester.getRect(getItem(0));
    expect(rect0, const Rect.fromLTRB(240.0, 0.0, 560.0, 600.0));

    for (var i = 0; i < 7; i++) {
      await tester.drag(find.byType(CarouselView), const Offset(-80.0, 0.0));
      await tester.pumpAndSettle();
    }

    // After scrolling the carousel 7 times, the last item(item 9) should be on
    // the end of the screen.
    expect(getItem(9), findsOneWidget);
    expect(tester.getRect(getItem(9)), const Rect.fromLTRB(720.0, 0.0, 800.0, 600.0));

    // Keep snapping twice. Item 9 should be fully expanded to the max size.
    for (var i = 0; i < 2; i++) {
      await tester.drag(find.byType(CarouselView), const Offset(-80.0, 0.0));
      await tester.pumpAndSettle();
    }
    expect(getItem(9), findsOneWidget);
    expect(tester.getRect(getItem(9)), const Rect.fromLTRB(240.0, 0.0, 560.0, 600.0));
  });

  testWidgets('The initialItem stays when the flexWeights is updated', (WidgetTester tester) async {
    final controller = CarouselController(initialItem: 3);
    addTearDown(controller.dispose);

    Widget buildCarousel(List<int> flexWeights) {
      return MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            controller: controller,
            flexWeights: flexWeights,
            itemSnapping: true,
            children: List<Widget>.generate(20, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildCarousel(<int>[1, 1, 6, 1, 1]));
    await tester.pumpAndSettle();

    expect(find.text('Item 0'), findsNothing);
    for (var i = 1; i <= 5; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    Rect rect3 = tester.getRect(getItem(3));
    expect(rect3.center.dx, 400.0);
    expect(rect3.center.dy, 300.0);

    expect(find.text('Item 6'), findsNothing);

    await tester.pumpWidget(buildCarousel(<int>[7, 1]));
    await tester.pumpAndSettle();

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

    rect3 = tester.getRect(getItem(3));
    expect(rect3, const Rect.fromLTRB(0.0, 0.0, 700.0, 600.0));
    final Rect rect4 = tester.getRect(getItem(4));
    expect(rect4, const Rect.fromLTRB(700.0, 0.0, 800.0, 600.0));
  });

  testWidgets('The item that currently occupies max weight stays when the flexWeights is updated', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController(initialItem: 3);
    addTearDown(controller.dispose);

    Widget buildCarousel(List<int> flexWeights) {
      return MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            controller: controller,
            flexWeights: flexWeights,
            itemSnapping: true,
            children: List<Widget>.generate(20, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildCarousel(<int>[1, 1, 6, 1, 1]));
    await tester.pumpAndSettle();
    // Item 3 is centered.
    final Rect rect3 = tester.getRect(getItem(3));
    expect(rect3.center.dx, 400.0);
    expect(rect3.center.dy, 300.0);

    // Simulate scroll to right and show item 4 to be the centered max item.
    await tester.drag(find.byType(CarouselView), const Offset(-80.0, 0.0));
    await tester.pumpAndSettle();

    expect(find.text('Item 1'), findsNothing);
    for (var i = 2; i <= 6; i++) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    Rect rect4 = tester.getRect(getItem(4));
    expect(rect4.center.dx, 400.0);
    expect(rect4.center.dy, 300.0);

    await tester.pumpWidget(buildCarousel(<int>[7, 1]));
    await tester.pumpAndSettle();

    rect4 = tester.getRect(getItem(4));
    expect(rect4, const Rect.fromLTRB(0.0, 0.0, 700.0, 600.0));
    final Rect rect5 = tester.getRect(getItem(5));
    expect(rect5, const Rect.fromLTRB(700.0, 0.0, 800.0, 600.0));
  });

  testWidgets('The initialItem stays when the itemExtent is updated', (WidgetTester tester) async {
    final controller = CarouselController(initialItem: 3);
    addTearDown(controller.dispose);

    Widget buildCarousel(double itemExtent) {
      return MaterialApp(
        home: Scaffold(
          body: CarouselView(
            controller: controller,
            itemExtent: itemExtent,
            itemSnapping: true,
            children: List<Widget>.generate(20, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildCarousel(234.0));
    await tester.pumpAndSettle();

    Offset rect3BottomRight = tester.getRect(getItem(3)).bottomRight;
    expect(rect3BottomRight.dx, 234.0);
    expect(rect3BottomRight.dy, 600.0);

    await tester.pumpWidget(buildCarousel(400.0));
    await tester.pumpAndSettle();

    rect3BottomRight = tester.getRect(getItem(3)).bottomRight;
    expect(rect3BottomRight.dx, 400.0);
    expect(rect3BottomRight.dy, 600.0);

    await tester.pumpWidget(buildCarousel(100.0));
    await tester.pumpAndSettle();

    rect3BottomRight = tester.getRect(getItem(3)).bottomRight;
    expect(rect3BottomRight.dx, 100.0);
    expect(rect3BottomRight.dy, 600.0);
  });

  testWidgets(
    'While scrolling, one extra item will show at the end of the screen during items transition',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView.weighted(
              flexWeights: const <int>[1, 2, 4, 2, 1],
              consumeMaxWeight: false,
              children: List<Widget>.generate(10, (int index) {
                return Center(child: Text('Item $index'));
              }),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();

      for (var i = 0; i < 5; i++) {
        expect(getItem(i), findsOneWidget);
      }

      // Drag the first item to the middle. So the progress for the first item size change
      // is 50%, original width is 80.
      await tester.drag(getItem(0), const Offset(-40.0, 0.0), kind: PointerDeviceKind.trackpad);
      await tester.pump();
      expect(tester.getRect(getItem(0)).width, 40.0);

      // The size of item 1 is changing to the size of item 0, so the size of item 1
      // now should be item1.originalExtent - 50% * (item1.extent - item0.extent).
      // Item1 originally should be 2/(1+2+4+2+1) * 800 = 160.0.
      expect(tester.getRect(getItem(1)).width, 160 - 0.5 * (160 - 80));

      // The extent of item 2 should be: item2.originalExtent - 50% * (item2.extent - item1.extent).
      // the extent of item 2 originally should be 4/(1+2+4+2+1) * 800 = 320.0.
      expect(tester.getRect(getItem(2)).width, 320 - 0.5 * (320 - 160));

      // The extent of item 3 should be: item3.originalExtent + 50% * (item2.extent - item3.extent).
      // the extent of item 3 originally should be 2/(1+2+4+2+1) * 800 = 160.0.
      expect(tester.getRect(getItem(3)).width, 160 + 0.5 * (320 - 160));

      // The extent of item 4 should be: item4.originalExtent + 50% * (item3.extent - item4.extent).
      // the extent of item 4 originally should be 1/(1+2+4+2+1) * 800 = 80.0.
      expect(tester.getRect(getItem(4)).width, 80 + 0.5 * (160 - 80));

      // The sum of the first 5 items during transition is less than the screen width.
      double sum = 0;
      for (var i = 0; i < 5; i++) {
        sum += tester.getRect(getItem(i)).width;
      }
      expect(sum, lessThan(MediaQuery.of(tester.element(find.byType(CarouselView))).size.width));
      final double difference =
          MediaQuery.of(tester.element(find.byType(CarouselView))).size.width - sum;

      // One more item should show on screen to fill the rest of the viewport.
      expect(getItem(5), findsOneWidget);
      expect(tester.getRect(getItem(5)).width, difference);
    },
  );

  testWidgets('Updating CarouselView does not cause exception', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/152787
    var isLight = true;
    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return MaterialApp(
            theme: Theme.of(
              context,
            ).copyWith(brightness: isLight ? Brightness.light : Brightness.dark),
            home: Scaffold(
              appBar: AppBar(
                actions: <Widget>[
                  Switch(
                    value: isLight,
                    onChanged: (bool value) {
                      setState(() {
                        isLight = value;
                      });
                    },
                  ),
                ],
              ),
              body: CarouselView(
                itemExtent: 100,
                children: List<Widget>.generate(10, (int index) {
                  return Center(child: Text('Item $index'));
                }),
              ),
            ),
          );
        },
      ),
    );
    await tester.pumpAndSettle();
    await tester.tap(find.byType(Switch));
    await tester.pumpAndSettle();

    // No exception.
    expect(tester.takeException(), isNull);
  });

  testWidgets('The shrinkExtent should keep the same when the item is tapped', (
    WidgetTester tester,
  ) async {
    final children = List<Widget>.generate(20, (int index) {
      return Center(child: Text('Item $index'));
    });

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return MaterialApp(
            home: Scaffold(
              body: Center(
                child: ConstrainedBox(
                  constraints: const BoxConstraints(maxHeight: 200),
                  child: CarouselView(
                    itemExtent: 330,
                    onTap: (int idx) => setState(() {}),
                    children: children,
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );

    await tester.pumpAndSettle();

    expect(tester.getRect(getItem(0)).width, 330.0);

    final Finder item1 = find.text('Item 1');
    await tester.tap(find.ancestor(of: item1, matching: find.byType(Stack)));

    await tester.pumpAndSettle();

    expect(tester.getRect(getItem(0)).width, 330.0);
    expect(tester.getRect(getItem(1)).width, 330.0);
    // This should be less than 330.0 because the item is shrunk; width is 800.0 - 330.0 - 330.0
    expect(tester.getRect(getItem(2)).width, 140.0);
  });

  testWidgets('CarouselView onTap is clickable', (WidgetTester tester) async {
    var tappedIndex = -1;
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 350,
            onTap: (int index) {
              tappedIndex = index;
            },
            children: List<Widget>.generate(3, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

    final Finder carouselItem = find.text('Item 1');
    await tester.tap(carouselItem, warnIfMissed: false);
    await tester.pumpAndSettle();

    // Verify that the onTap callback was called with the correct index.
    expect(tappedIndex, 1);

    // Tap another item.
    final Finder anotherCarouselItem = find.text('Item 2');
    await tester.tap(anotherCarouselItem, warnIfMissed: false);
    await tester.pumpAndSettle();

    // Verify that the onTap callback was called with the new index.
    expect(tappedIndex, 2);
  });

  testWidgets('CarouselView with enableSplash true - children are not directly interactive', (
    WidgetTester tester,
  ) async {
    var buttonPressed = false;
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 350,
            children: List<Widget>.generate(3, (int index) {
              return Center(
                child: ElevatedButton(
                  onPressed: () => buttonPressed = true,
                  child: Text('Button $index'),
                ),
              );
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    await tester.tap(find.text('Button 1'), warnIfMissed: false);
    expect(buttonPressed, isFalse);
  });

  testWidgets('CarouselView with enableSplash false - children are directly interactive', (
    WidgetTester tester,
  ) async {
    var buttonPressed = false;
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 350,
            enableSplash: false,
            children: List<Widget>.generate(3, (int index) {
              return Center(
                child: ElevatedButton(
                  onPressed: () => buttonPressed = true,
                  child: Text('Button $index'),
                ),
              );
            }),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    await tester.tap(find.text('Button 1'));
    expect(buttonPressed, isTrue);
  });

  testWidgets(
    'CarouselView with enableSplash false - container is clickable without triggering children onTap',
    (WidgetTester tester) async {
      var tappedIndex = -1;
      var buttonPressed = false;
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView(
              itemExtent: 350,
              enableSplash: false,
              onTap: (int index) {
                tappedIndex = index;
              },
              children: List<Widget>.generate(3, (int index) {
                return Column(
                  children: <Widget>[
                    Text('Item $index'),
                    ElevatedButton(
                      onPressed: () => buttonPressed = true,
                      child: Text('Button $index'),
                    ),
                  ],
                );
              }),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();

      final Finder carouselItem = find.text('Item 1');
      await tester.tap(carouselItem, warnIfMissed: false);
      await tester.pumpAndSettle();

      expect(tappedIndex, 1);
      expect(buttonPressed, false);

      final Finder anotherCarouselItem = find.text('Item 2');
      await tester.tap(anotherCarouselItem, warnIfMissed: false);
      await tester.pumpAndSettle();

      expect(tappedIndex, 2);
      expect(buttonPressed, false);

      await tester.tap(find.text('Button 1'), warnIfMissed: false);
      expect(buttonPressed, isTrue);
    },
  );

  // Regression test for https://github.com/flutter/flutter/issues/160679
  testWidgets('CarouselView does not crash if itemExtent is zero', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: SizedBox(
            width: 100,
            child: CarouselView(
              itemExtent: 0,
              children: <Widget>[Container(color: Colors.red, width: 100, height: 100)],
            ),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  // Regression test for https://github.com/flutter/flutter/issues/166067.
  testWidgets('CarouselView should not crash when using PageStorageKey', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return const <Widget>[SliverAppBar()];
            },
            body: CustomScrollView(
              key: const PageStorageKey<String>('key1'),
              slivers: <Widget>[
                SliverToBoxAdapter(
                  child: ConstrainedBox(
                    constraints: const BoxConstraints(maxHeight: 50),
                    child: CarouselView.weighted(
                      flexWeights: const <int>[1, 2],
                      consumeMaxWeight: false,
                      children: List<Widget>.generate(20, (int index) {
                        return ColoredBox(
                          color: Colors.primaries[index % Colors.primaries.length].withValues(
                            alpha: 0.8,
                          ),
                          child: const SizedBox.expand(),
                        );
                      }),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  // Regression test for https://github.com/flutter/flutter/issues/160679.
  testWidgets('Does not crash when parent size is zero', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: SizedBox(
            width: 0,
            child: CarouselView(itemExtent: 40.0, children: <Widget>[FlutterLogo()]),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  testWidgets('itemExtent can be set to double.infinity', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: CarouselView(itemExtent: double.infinity, children: <Widget>[FlutterLogo()]),
        ),
      ),
    );

    // Item extent is clamped to screen size.
    final Size logoSize = tester.getSize(find.byType(FlutterLogo));
    const itemHorizontalPadding = 8.0; // Default padding.
    expect(logoSize.width, 800.0 - itemHorizontalPadding);
  });

  // Regression test for https://github.com/flutter/flutter/issues/163436.
  testWidgets('Does not crash when initial viewport dimension is zero and itemExtent is fixed', (
    WidgetTester tester,
  ) async {
    await tester.binding.setSurfaceSize(Size.zero);
    addTearDown(() => tester.binding.setSurfaceSize(null));

    const fixedItemExtent = 60.0;
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: CarouselView(itemExtent: fixedItemExtent, children: <Widget>[FlutterLogo()]),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  // Regression test for https://github.com/flutter/flutter/issues/163436.
  testWidgets('Does not crash when initial viewport dimension is zero and itemExtent is infinite', (
    WidgetTester tester,
  ) async {
    await tester.binding.setSurfaceSize(Size.zero);
    addTearDown(() => tester.binding.setSurfaceSize(null));

    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: CarouselView(itemExtent: double.infinity, children: <Widget>[FlutterLogo()]),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  // Regression test for https://github.com/flutter/flutter/issues/163436.
  testWidgets('itemExtent is applied when viewport dimension is updated', (
    WidgetTester tester,
  ) async {
    addTearDown(() => tester.binding.setSurfaceSize(null));

    const itemExtent = 60.0;
    var showScrollbars = false;

    Future<void> updateSurfaceSizeAndPump(Size size) async {
      await tester.binding.setSurfaceSize(size);

      // At startup, a warm-up frame can be produced before the Flutter engine has reported the
      // initial view metrics. As a result, the first frame can be produced with a size of zero.
      // This leads to several instances of _CarouselPosition being created and
      // _CarouselPosition.absorb to be called.
      // To correctly simulate this behavior in the test environment, one solution is to
      // update the ScrollConfiguration. For instance by changing the ScrollBehavior.scrollbars
      // value on each build.
      showScrollbars = !showScrollbars;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Center(
              child: ScrollConfiguration(
                behavior: const ScrollBehavior().copyWith(scrollbars: showScrollbars),
                child: const CarouselView(
                  itemExtent: itemExtent,
                  children: <Widget>[FlutterLogo()],
                ),
              ),
            ),
          ),
        ),
      );
    }

    // Simulate an initial zero viewport dimension.
    await updateSurfaceSizeAndPump(Size.zero);
    await updateSurfaceSizeAndPump(const Size(500, 400));

    final Size logoSize = tester.getSize(find.byType(FlutterLogo));
    const itemHorizontalPadding = 8.0; // Default padding.
    expect(logoSize.width, itemExtent - itemHorizontalPadding);
  });

  // Regression test for https://github.com/flutter/flutter/issues/167621.
  testWidgets('CarouselView.weighted does not crash when parent size is zero', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: SizedBox(
            width: 0,
            child: CarouselView.weighted(
              flexWeights: <int>[1, 2],
              children: <Widget>[FlutterLogo(), FlutterLogo()],
            ),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  // Regression test for https://github.com/flutter/flutter/issues/167621.
  testWidgets('CarouselView.weighted does not crash when initial viewport dimension is zero', (
    WidgetTester tester,
  ) async {
    await tester.binding.setSurfaceSize(Size.zero);
    addTearDown(() => tester.binding.setSurfaceSize(null));

    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: <int>[1, 2],
            children: <Widget>[FlutterLogo(), FlutterLogo()],
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  // Regression test for https://github.com/flutter/flutter/issues/167621.
  testWidgets('CarouselView.weigted weigths are applied when viewport dimension is updated', (
    WidgetTester tester,
  ) async {
    addTearDown(() => tester.binding.setSurfaceSize(null));
    final controller = CarouselController(initialItem: 1);
    addTearDown(controller.dispose);

    const firstWeight = 2;
    const secondWeight = 3;
    var showScrollbars = false;

    Future<void> updateSurfaceSizeAndPump(Size size) async {
      await tester.binding.setSurfaceSize(size);

      // At startup, a warm-up frame can be produced before the Flutter engine has reported the
      // initial view metrics. As a result, the first frame can be produced with a size of zero.
      // This leads to several instances of _CarouselPosition being created and
      // _CarouselPosition.absorb to be called.
      // To correctly simulate this behavior in the test environment, one solution is to
      // update the ScrollConfiguration. For instance by changing the ScrollBehavior.scrollbars
      // value on each build.
      showScrollbars = !showScrollbars;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Center(
              child: ScrollConfiguration(
                behavior: const ScrollBehavior().copyWith(scrollbars: showScrollbars),
                child: CarouselView.weighted(
                  controller: controller,
                  flexWeights: const <int>[firstWeight, secondWeight],
                  children: List<Widget>.generate(20, (int index) {
                    return Center(child: Text('Item $index'));
                  }),
                ),
              ),
            ),
          ),
        ),
      );
    }

    // Simulate an initial zero viewport dimension.
    await updateSurfaceSizeAndPump(Size.zero);
    const double surfaceWidth = 500;
    await updateSurfaceSizeAndPump(const Size(surfaceWidth, 400));

    const int totalWeight = firstWeight + secondWeight;

    expect(find.text('Item 0'), findsOne);
    expect(find.text('Item 1'), findsOne);

    final double firstItemWidth = tester.getRect(getItem(0)).width;
    expect(firstItemWidth, surfaceWidth * firstWeight / totalWeight);
    final double secondItemWidth = tester.getRect(getItem(1)).width;
    expect(secondItemWidth, surfaceWidth * secondWeight / totalWeight);
  });

  testWidgets('CarouselView.builder creates items lazily', (WidgetTester tester) async {
    final builtItems = <int>[];

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.builder(
            itemExtent: 300.0,
            itemCount: 1000,
            itemBuilder: (BuildContext context, int index) {
              builtItems.add(index);
              return Container(
                color: Colors.blue[index % 9 * 100],
                child: Center(child: Text('Item $index')),
              );
            },
          ),
        ),
      ),
    );

    // Only visible items should be built initially.
    expect(builtItems.length, lessThan(10));
    expect(builtItems, contains(0));
    expect(builtItems, contains(1));

    // Scroll to a far item.
    await tester.drag(find.byType(CarouselView), const Offset(-2000.0, 0.0));
    await tester.pumpAndSettle();

    // Clear built items to see what's built after scrolling.
    builtItems.clear();

    // Force rebuild by scrolling a bit more.
    await tester.drag(find.byType(CarouselView), const Offset(-300.0, 0.0));
    await tester.pump();

    // Should have built new items, not the initial ones.
    expect(builtItems, isNotEmpty);
    expect(builtItems.every((int index) => index > 3), isTrue);
  });

  group('CarouselController.animateToItem', () {
    testWidgets('CarouselView.weighted horizontal, not reversed, flexWeights [7,1]', (
      WidgetTester tester,
    ) async {
      await runCarouselTest(
        tester: tester,
        flexWeights: <int>[7, 1],
        numberOfChildren: 20,
        scrollDirection: Axis.horizontal,
        reverse: false,
      );
    });

    testWidgets('CarouselView.weighted horizontal, reversed, flexWeights [7,1]', (
      WidgetTester tester,
    ) async {
      await runCarouselTest(
        tester: tester,
        flexWeights: <int>[7, 1],
        numberOfChildren: 20,
        scrollDirection: Axis.horizontal,
        reverse: true,
      );
    });

    testWidgets('CarouselView.weighted vertical, not reversed, flexWeights [7,1]', (
      WidgetTester tester,
    ) async {
      await runCarouselTest(
        tester: tester,
        flexWeights: <int>[7, 1],
        numberOfChildren: 20,
        scrollDirection: Axis.vertical,
        reverse: false,
      );
    });

    testWidgets('CarouselView.weighted vertical, reversed, flexWeights [7,1]', (
      WidgetTester tester,
    ) async {
      await runCarouselTest(
        tester: tester,
        flexWeights: <int>[7, 1],
        numberOfChildren: 20,
        scrollDirection: Axis.vertical,
        reverse: true,
      );
    });

    testWidgets(
      'CarouselView.weighted horizontal, not reversed, flexWeights [1,7] and consumeMaxWeight false',
      (WidgetTester tester) async {
        await runCarouselTest(
          tester: tester,
          flexWeights: <int>[1, 7],
          numberOfChildren: 20,
          scrollDirection: Axis.horizontal,
          reverse: false,
          consumeMaxWeight: false,
        );
      },
    );

    testWidgets('CarouselView.weighted horizontal, reversed, flexWeights [1,7]', (
      WidgetTester tester,
    ) async {
      await runCarouselTest(
        tester: tester,
        flexWeights: <int>[1, 7],
        numberOfChildren: 20,
        scrollDirection: Axis.horizontal,
        reverse: true,
      );
    });

    testWidgets(
      'CarouselView.weighted vertical, not reversed, flexWeights [1,7] and consumeMaxWeight false',
      (WidgetTester tester) async {
        await runCarouselTest(
          tester: tester,
          flexWeights: <int>[1, 7],
          numberOfChildren: 20,
          scrollDirection: Axis.vertical,
          consumeMaxWeight: false,
          reverse: false,
        );
      },
    );

    testWidgets(
      'CarouselView.weighted vertical, reversed, flexWeights [1,7] and consumeMaxWeight false',
      (WidgetTester tester) async {
        await runCarouselTest(
          tester: tester,
          flexWeights: <int>[1, 7],
          numberOfChildren: 20,
          scrollDirection: Axis.vertical,
          consumeMaxWeight: false,
          reverse: true,
        );
      },
    );

    testWidgets(
      'CarouselView.weighted vertical, reversed, flexWeights [1,7] and consumeMaxWeight',
      (WidgetTester tester) async {
        await runCarouselTest(
          tester: tester,
          flexWeights: <int>[1, 7],
          numberOfChildren: 20,
          scrollDirection: Axis.vertical,
          reverse: true,
        );
      },
    );

    testWidgets('CarouselView.weightedBuilder creates items lazily with flex weights', (
      WidgetTester tester,
    ) async {
      final builtItems = <int>[];

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView.weightedBuilder(
              flexWeights: const <int>[2, 3, 1],
              itemCount: 1000,
              itemBuilder: (BuildContext context, int index) {
                builtItems.add(index);
                return Container(
                  color: Colors.blue[index % 9 * 100],
                  child: Center(child: Text('Item $index')),
                );
              },
            ),
          ),
        ),
      );

      // Only visible items should be built initially.
      expect(builtItems.length, lessThan(10));
      expect(builtItems, contains(0));
      expect(builtItems, contains(1));

      // Scroll to a far item.
      await tester.drag(find.byType(CarouselView), const Offset(-2000.0, 0.0));
      await tester.pumpAndSettle();

      // Clear built items to see what's built after scrolling.
      builtItems.clear();

      // Force rebuild by scrolling a bit more.
      await tester.drag(find.byType(CarouselView), const Offset(-300.0, 0.0));
      await tester.pump();

      // Should have built new items, not the initial ones.
      expect(builtItems, isNotEmpty);
      expect(builtItems.every((int index) => index > 3), isTrue);
    });

    testWidgets('CarouselView horizontal, not reversed', (WidgetTester tester) async {
      await runCarouselTest(
        tester: tester,
        numberOfChildren: 20,
        scrollDirection: Axis.horizontal,
        reverse: false,
      );
    });

    testWidgets('CarouselView horizontal, reversed', (WidgetTester tester) async {
      await runCarouselTest(
        tester: tester,
        numberOfChildren: 10,
        scrollDirection: Axis.horizontal,
        reverse: true,
      );
    });

    testWidgets('CarouselView vertical, not reversed', (WidgetTester tester) async {
      await runCarouselTest(
        tester: tester,
        numberOfChildren: 10,
        scrollDirection: Axis.vertical,
        reverse: false,
      );
    });

    testWidgets('CarouselView vertical, reversed', (WidgetTester tester) async {
      await runCarouselTest(
        tester: tester,
        numberOfChildren: 10,
        scrollDirection: Axis.vertical,
        reverse: true,
      );
    });

    testWidgets('CarouselView positions items correctly', (WidgetTester tester) async {
      const numberOfChildren = 5;
      final controller = CarouselController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView.weighted(
              flexWeights: const <int>[2, 3, 1],
              controller: controller,
              itemSnapping: true,
              children: List<Widget>.generate(numberOfChildren, (int index) {
                return Center(child: Text('Item $index'));
              }),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();

      // Get the RenderBox of the CarouselView to determine its position and boundaries.
      final RenderBox carouselBox = tester.renderObject(find.byType(CarouselView));
      final Offset carouselPos = carouselBox.localToGlobal(Offset.zero);
      final double carouselLeft = carouselPos.dx;
      final double carouselRight = carouselLeft + carouselBox.size.width;

      for (var i = 0; i < numberOfChildren; i++) {
        controller.animateToItem(i, curve: Curves.easeInOut);
        await tester.pumpAndSettle();

        expect(find.text('Item $i'), findsOneWidget);

        // Get the item's RenderBox and determine its position.
        final RenderBox itemBox = tester.renderObject(find.text('Item $i'));
        final Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size;

        // Validate that the item is positioned within the CarouselView boundaries.
        expect(itemRect.left, greaterThanOrEqualTo(carouselLeft));
        expect(itemRect.right, lessThanOrEqualTo(carouselRight));
      }
    });

    testWidgets('CarouselView infinite', (WidgetTester tester) async {
      final controller = CarouselController();
      addTearDown(controller.dispose);

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView(
              itemExtent: 200,
              infinite: true,
              controller: controller,
              children: List<Widget>.generate(3, (int index) {
                return Center(child: Text('Item $index'));
              }),
            ),
          ),
        ),
      );

      // Verify animating to an index beyond the array length.
      controller.animateToItem(5);
      await tester.pumpAndSettle();

      // Should show last item 2 times based on size.
      expect(find.textContaining('Item 2'), findsAtLeastNWidgets(2));
    });
  });

  testWidgets('CarouselView infinite scrolling', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            infinite: true,
            children: List<Widget>.generate(3, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.sizeOf(tester.element(find.byType(CarouselView)));
    expect(viewportSize, const Size(800, 600));

    // Initial state: viewport is 800 wide, each item is 200 wide.
    // Visible items: Item 0 at [0-200], Item 1 at [200-400], Item 2 at [400-600], Item 0 at [600-800] (wraps).
    expect(find.text('Item 0'), findsNWidgets(2)); // Item 0 appears twice due to wrap.
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);

    Rect rect0 = tester.getRect(getItem(0).first);
    expect(rect0, const Rect.fromLTRB(0.0, 0.0, 200.0, 600.0));
    Rect rect1 = tester.getRect(getItem(1).first);
    expect(rect1, const Rect.fromLTRB(200.0, 0.0, 400.0, 600.0));
    Rect rect2 = tester.getRect(getItem(2).first);
    expect(rect2, const Rect.fromLTRB(400.0, 0.0, 600.0, 600.0));

    // Scroll forward by 400 pixels (dragging left).
    await tester.drag(find.byType(CarouselView), const Offset(-400, 0));
    await tester.pumpAndSettle();

    // After scrolling 400 pixels:
    // Visible items: Item 2 at [0-200], Item 0 at [200-400], Item 1 at [400-600], Item 2 at [600-800].
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsNWidgets(2)); // Item 2 appears twice.

    rect2 = tester.getRect(getItem(2).first);
    expect(rect2, const Rect.fromLTRB(0.0, 0.0, 200.0, 600.0));
    rect0 = tester.getRect(getItem(0).first);
    expect(rect0, const Rect.fromLTRB(200.0, 0.0, 400.0, 600.0));
    rect1 = tester.getRect(getItem(1).first);
    expect(rect1, const Rect.fromLTRB(400.0, 0.0, 600.0, 600.0));
  });

  testWidgets('CarouselView infinite scrolling supports bidirectional scrolling', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            infinite: true,
            children: List<Widget>.generate(3, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

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

    final double initialItem0Left = tester.getRect(getItem(0).first).left;

    await tester.drag(find.byType(CarouselView), const Offset(200, 0));
    await tester.pumpAndSettle();

    // After scrolling backward, Item 2 should now appear twice.
    expect(find.text('Item 2'), findsNWidgets(2));
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);

    final double afterItem2Left = tester.getRect(getItem(2).first).left;
    expect(afterItem2Left, moreOrLessEquals(initialItem0Left, epsilon: 10.0));

    await tester.drag(find.byType(CarouselView), const Offset(-200, 0));
    await tester.pumpAndSettle();

    // Should be back to initial state.
    expect(find.text('Item 0'), findsNWidgets(2));
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
  });

  testWidgets('CarouselView.weighted infinite scrolling', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[1, 2, 1],
            infinite: true,
            children: List<Widget>.generate(3, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.sizeOf(tester.element(find.byType(CarouselView)));
    expect(viewportSize, const Size(800, 600));

    // With flexWeights [1, 2, 1], total weight = 4, viewport = 800.
    // Item widths: small = 1/4 * 800 = 200, large = 2/4 * 800 = 400.
    // With consumeMaxWeight (default true), Item 0 is placed at the max weight position (index 1).
    // With infinite scrolling, items wrap to fill the entire viewport:
    // Item 2 (small) at [0, 200], Item 0 (large) at [200, 600], Item 1 (small) at [600, 800].
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget); // Wraps to fill the padding area

    final Rect rect2 = tester.getRect(getItem(2).first);
    expect(rect2, const Rect.fromLTRB(0.0, 0.0, 200.0, 600.0));
    final Rect rect0 = tester.getRect(getItem(0).first);
    expect(rect0, const Rect.fromLTRB(200.0, 0.0, 600.0, 600.0));
    final Rect rect1 = tester.getRect(getItem(1).first);
    expect(rect1, const Rect.fromLTRB(600.0, 0.0, 800.0, 600.0));

    // Scroll forward by 400 pixels (one large item width).
    await tester.drag(find.byType(CarouselView), const Offset(-400, 0));
    await tester.pumpAndSettle();

    // After scrolling, items shift and cycle infinitely.
    // With only 3 items and infinite scroll, items wrap around.
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
  });

  testWidgets('CarouselView.weighted with hero layout (1,7,1) and infinite scrolling', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[1, 7, 1],
            infinite: true,
            children: List<Widget>.generate(6, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.sizeOf(tester.element(find.byType(CarouselView)));
    expect(viewportSize, const Size(800, 600));

    // With flexWeights [1, 7, 1], total weight = 9, viewport = 800.
    // Item widths: small ≈ 88.89, large ≈ 622.22.
    // With consumeMaxWeight (default true), Item 0 is placed at the max weight position (index 1).
    // Initial layout: [padding small] Item 0 (large), Item 1 (small).
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsNothing);

    // Verify Item 0 is in the large/hero position with correct width.
    final Rect rect0 = tester.getRect(getItem(0).first);
    expect(rect0.left, moreOrLessEquals(800.0 / 9, epsilon: 0.1)); // ~88.89
    expect(rect0.width, moreOrLessEquals(800.0 * 7 / 9, epsilon: 0.1)); // ~622.22

    // Scroll forward - should continue infinitely and show different items.
    await tester.drag(find.byType(CarouselView), const Offset(-622, 0));
    await tester.pumpAndSettle();

    // After scrolling, later items should be visible.
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);

    // Scroll backward to return to initial position.
    await tester.drag(find.byType(CarouselView), const Offset(622, 0));
    await tester.pumpAndSettle();

    // Should show Item 0 again in the hero position.
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);

    // Scroll backward beyond initial position - should work due to infinite.
    // This tests true bidirectional infinite scrolling.
    await tester.drag(find.byType(CarouselView), const Offset(200, 0));
    await tester.pumpAndSettle();

    // After scrolling backward, items from the "end" of the list should appear
    // (wrapping around). With 6 items, scrolling backward from Item 0 shows Item 5.
    expect(find.text('Item 5'), findsOneWidget);
  });

  testWidgets('CarouselView.weighted with multi-browse layout and infinite scrolling', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[1, 2, 3, 2, 1],
            infinite: true,
            consumeMaxWeight: false,
            children: List<Widget>.generate(10, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final Size viewportSize = MediaQuery.sizeOf(tester.element(find.byType(CarouselView)));
    expect(viewportSize, const Size(800, 600));

    // With flexWeights [1, 2, 3, 2, 1] and consumeMaxWeight = false, multiple items are visible.
    // Items have varying widths based on the weight cycle.
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);

    // Scroll forward by one item worth (first item extent = 800 * 1/9 ≈ 88.89 pixels).
    await tester.drag(find.byType(CarouselView), const Offset(-89, 0));
    await tester.pumpAndSettle();

    // Items should have shifted, with later items now visible.
    expect(find.text('Item 1'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 3'), findsOneWidget);

    // Scroll backward beyond initial position (should still work due to infinite).
    await tester.drag(find.byType(CarouselView), const Offset(200, 0));
    await tester.pumpAndSettle();
    expect(find.text('Item 0'), findsOneWidget);
  });

  testWidgets('CarouselView infinite leadingItem wraps correctly when scrolling forwards', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController();
    addTearDown(controller.dispose);
    final reportedIndices = <int>[];

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            itemSnapping: true,
            infinite: true,
            controller: controller,
            onIndexChanged: (int index) {
              reportedIndices.add(index);
            },
            children: List<Widget>.generate(5, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final int initialItem = controller.leadingItem;

    // Scroll forward by dragging left. Each 200px drag moves one item.
    // We'll scroll through all items and verify the leadingItem wraps correctly.
    for (var i = 1; i <= 7; i++) {
      await tester.drag(find.byType(CarouselView), const Offset(-200, 0));
      await tester.pumpAndSettle();
      // The leadingItem should wrap to [0, itemCount - 1] range.
      expect(controller.leadingItem, (initialItem + i) % 5);
    }

    // Verify the onIndexChanged callback was invoked with correct wrapped indices.
    expect(reportedIndices.length, greaterThanOrEqualTo(7));
    for (final index in reportedIndices) {
      expect(index, inInclusiveRange(0, 4));
    }
  });

  testWidgets('CarouselView infinite leadingItem wraps correctly when scrolling backwards', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController();
    addTearDown(controller.dispose);
    final reportedIndices = <int>[];

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            itemSnapping: true,
            infinite: true,
            controller: controller,
            onIndexChanged: (int index) {
              reportedIndices.add(index);
            },
            children: List<Widget>.generate(5, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final int initialItem = controller.leadingItem;

    // Scroll backward by dragging right. Each 200px drag moves one item backwards.
    // We'll scroll backward through items and verify the leadingItem wraps correctly.
    for (var i = 1; i <= 7; i++) {
      await tester.drag(find.byType(CarouselView), const Offset(200, 0));
      await tester.pumpAndSettle();
      // When scrolling backwards, wrap negative indices to positive.
      // (initialItem - i) % 5 handles wrapping for negative values in Dart.
      final int expectedItem = ((initialItem - i) % 5 + 5) % 5;
      expect(controller.leadingItem, expectedItem);
    }

    // Verify the onIndexChanged callback was invoked with correct wrapped indices.
    expect(reportedIndices.length, greaterThanOrEqualTo(7));
    for (final index in reportedIndices) {
      expect(index, inInclusiveRange(0, 4));
    }
  });

  testWidgets('CarouselView infinite animateToItem scrolls forward to next item', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            itemSnapping: true,
            infinite: true,
            controller: controller,
            children: List<Widget>.generate(5, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final double initialOffset = controller.offset;
    final int initialItem = controller.leadingItem;

    // Animate forward by one item. The offset should increase (scroll forward),
    // not decrease (scroll backward).
    controller.animateToItem(
      initialItem + 1,
      duration: const Duration(milliseconds: 200),
      curve: Curves.linear,
    );
    await tester.pumpAndSettle();

    expect(controller.leadingItem, equals((initialItem + 1) % 5));
    expect(controller.offset, greaterThan(initialOffset));
  });

  testWidgets('CarouselView.weighted infinite animateToItem scrolls forward to next item', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[1, 7, 1],
            itemSnapping: true,
            infinite: true,
            controller: controller,
            children: List<Widget>.generate(5, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    final double initialOffset = controller.offset;

    // With consumeMaxWeight and [1,7,1], animateToItem(1) places item 1 in the
    // max-weight position. This is one item forward from initial (item 0 in hero).
    // The offset should increase (scroll forward), not decrease (scroll backward).
    controller.animateToItem(1, duration: const Duration(milliseconds: 200), curve: Curves.linear);
    await tester.pumpAndSettle();

    expect(controller.offset, greaterThan(initialOffset));
    // Item 1 should now be visible in the hero position.
    expect(find.text('Item 1'), findsOneWidget);
  });

  testWidgets('CarouselView infinite animateToItem scrolls forward even to item just behind', (
    WidgetTester tester,
  ) async {
    final controller = CarouselController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 200,
            itemSnapping: true,
            infinite: true,
            controller: controller,
            children: List<Widget>.generate(5, (int index) {
              return Center(child: Text('Item $index'));
            }),
          ),
        ),
      ),
    );

    // First scroll forward to item 2.
    controller.animateToItem(2, duration: const Duration(milliseconds: 200), curve: Curves.linear);
    await tester.pumpAndSettle();
    expect(controller.leadingItem, equals(2));

    final double offsetAtItem2 = controller.offset;

    // Now animate to item 1 which is just behind. In infinite mode this should
    // scroll forward through items 3 → 4 → 0 → 1, not backward.
    controller.animateToItem(1, duration: const Duration(milliseconds: 200), curve: Curves.linear);
    await tester.pumpAndSettle();

    expect(controller.leadingItem, equals(1));
    expect(controller.offset, greaterThan(offsetAtItem2));
  });

  testWidgets(
    'CarouselView.weighted infinite animateToItem scrolls forward even to item just behind',
    (WidgetTester tester) async {
      final controller = CarouselController();
      addTearDown(controller.dispose);

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView.weighted(
              flexWeights: const <int>[1, 7, 1],
              itemSnapping: true,
              infinite: true,
              controller: controller,
              children: List<Widget>.generate(5, (int index) {
                return Center(child: Text('Item $index'));
              }),
            ),
          ),
        ),
      );

      // First scroll forward to item 2 (in hero position).
      controller.animateToItem(
        2,
        duration: const Duration(milliseconds: 200),
        curve: Curves.linear,
      );
      await tester.pumpAndSettle();

      final double offsetAtItem2 = controller.offset;

      // Now animate to item 1 which is just behind. In infinite mode this should
      // scroll forward through the remaining items, not backward.
      controller.animateToItem(
        1,
        duration: const Duration(milliseconds: 200),
        curve: Curves.linear,
      );
      await tester.pumpAndSettle();

      expect(controller.offset, greaterThan(offsetAtItem2));
      expect(find.text('Item 1'), findsOneWidget);
    },
  );

  group('CarouselView onIndexChanged callback', () {
    Widget buildCarousel({
      required CarouselController controller,
      ValueChanged<int>? onIndexChanged,
      bool weighted = false,
      bool reverse = false,
      bool itemSnapping = false,
      List<int>? flexWeights,
      int itemCount = 6,
    }) {
      return MaterialApp(
        home: Scaffold(
          body: weighted
              ? CarouselView.weighted(
                  flexWeights: flexWeights!,
                  reverse: reverse,
                  itemSnapping: itemSnapping,
                  controller: controller,
                  onIndexChanged: onIndexChanged,
                  children: List.generate(itemCount, (i) => Text('Item $i')),
                )
              : CarouselView(
                  itemExtent: 300,
                  reverse: reverse,
                  itemSnapping: itemSnapping,
                  controller: controller,
                  onIndexChanged: onIndexChanged,
                  children: List.generate(itemCount, (i) => Text('Item $i')),
                ),
        ),
      );
    }

    testWidgets('CarouselView shows correct item after animation', (tester) async {
      final controller = CarouselController();
      addTearDown(controller.dispose);
      var leadingIndex = 0;

      await tester.pumpWidget(
        buildCarousel(controller: controller, onIndexChanged: (i) => leadingIndex = i),
      );
      await tester.pumpAndSettle();

      controller.animateToItem(
        3,
        duration: const Duration(milliseconds: 200),
        curve: Curves.linear,
      );
      await tester.pumpAndSettle();

      expect(controller.leadingItem, equals(3));
      expect(leadingIndex, equals(3));

      controller.animateToItem(
        1,
        duration: const Duration(milliseconds: 200),
        curve: Curves.linear,
      );
      await tester.pumpAndSettle();
      expect(controller.leadingItem, equals(1));
      expect(leadingIndex, equals(1));
    });

    testWidgets(
      'CarouselView.weighted shows correct item after animation with symmetric flexWeights',
      (tester) async {
        final controller = CarouselController();
        addTearDown(controller.dispose);
        var leadingIndex = 0;

        await tester.pumpWidget(
          buildCarousel(
            weighted: true,
            flexWeights: const [2, 5, 2],
            controller: controller,
            onIndexChanged: (i) => leadingIndex = i,
          ),
        );
        await tester.pumpAndSettle();

        // Animate the carousel so item 4 is placed in the first position with max weight (5)
        // in `flexWeights`, resulting in item 3 as the leading item.
        controller.animateToItem(
          4,
          duration: const Duration(milliseconds: 200),
          curve: Curves.linear,
        );
        await tester.pumpAndSettle();

        expect(controller.leadingItem, equals(3));
        expect(leadingIndex, equals(3));
        expect(find.text('Item 3'), findsOneWidget);
      },
    );

    testWidgets(
      'CarouselView.weighted shows correct item after animation with asymmetric flexWeights',
      (tester) async {
        final controller = CarouselController();
        addTearDown(controller.dispose);
        var leadingIndex = 0;

        await tester.pumpWidget(
          buildCarousel(
            weighted: true,
            flexWeights: const [1, 2, 3, 4],
            controller: controller,
            onIndexChanged: (i) => leadingIndex = i,
          ),
        );
        await tester.pumpAndSettle();

        controller.animateToItem(
          2,
          duration: const Duration(milliseconds: 200),
          curve: Curves.linear,
        );
        await tester.pumpAndSettle();

        expect(controller.leadingItem, equals(0));
        expect(leadingIndex, equals(0));
      },
    );

    testWidgets('CarouselView shows the correct item after dragging', (tester) async {
      final controller = CarouselController();
      addTearDown(controller.dispose);
      var leadingIndex = 0;

      await tester.pumpWidget(
        buildCarousel(
          weighted: true,
          flexWeights: const [2, 5, 2],
          itemSnapping: true,
          itemCount: 5,
          controller: controller,
          onIndexChanged: (i) => leadingIndex = i,
        ),
      );
      await tester.pumpAndSettle();

      await tester.drag(find.byType(CarouselView), const Offset(-300, 0));
      await tester.pumpAndSettle();

      expect(controller.leadingItem, equals(1));
      expect(leadingIndex, equals(1));
    });

    testWidgets('CarouselView with reverse=true reports correct leading item after animation', (
      tester,
    ) async {
      final controller = CarouselController();
      addTearDown(controller.dispose);
      var leadingIndex = 0;

      await tester.pumpWidget(
        buildCarousel(
          reverse: true,
          controller: controller,
          onIndexChanged: (i) => leadingIndex = i,
        ),
      );
      await tester.pumpAndSettle();

      controller.animateToItem(
        2,
        duration: const Duration(milliseconds: 200),
        curve: Curves.linear,
      );
      await tester.pumpAndSettle();

      expect(controller.leadingItem, equals(2));
      expect(leadingIndex, equals(2));
    });

    testWidgets('CarouselView.weighted with reverse=true reports correct leading item after drag', (
      tester,
    ) async {
      final controller = CarouselController();
      addTearDown(controller.dispose);
      var leadingIndex = 0;

      await tester.pumpWidget(
        buildCarousel(
          weighted: true,
          reverse: true,
          itemSnapping: true,
          itemCount: 5,
          flexWeights: const [2, 5, 2],
          controller: controller,
          onIndexChanged: (i) => leadingIndex = i,
        ),
      );
      await tester.pumpAndSettle();

      await tester.drag(find.byType(CarouselView), const Offset(300, 0));
      await tester.pumpAndSettle();

      expect(controller.leadingItem, equals(1));
      expect(leadingIndex, equals(1));
    });
  });

  group('CarouselView item clipBehavior', () {
    testWidgets('CarouselView Item clipBehavior defaults to Clip.antiAlias', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView(
              itemExtent: 350,
              children: List<Widget>.generate(3, (int index) {
                return Text('Item $index');
              }),
            ),
          ),
        ),
      );

      final Material material = tester.firstWidget<Material>(
        find.ancestor(of: find.text('Item 0'), matching: find.byType(Material)),
      );

      expect(material.clipBehavior, Clip.antiAlias);
    });

    testWidgets('CarouselView.weighted Item clipBehavior defaults to Clip.antiAlias', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: CarouselView.weighted(
              flexWeights: const <int>[1, 1, 1],
              children: List<Widget>.generate(3, (int index) {
                return Text('Item $index');
              }),
            ),
          ),
        ),
      );

      final Material material = tester.firstWidget<Material>(
        find.ancestor(of: find.text('Item 0'), matching: find.byType(Material)),
      );

      expect(material.clipBehavior, Clip.antiAlias);
    });

    testWidgets('CarouselView Item clipBehavior respects theme', (WidgetTester tester) async {
      final theme = ThemeData(
        carouselViewTheme: const CarouselViewThemeData(itemClipBehavior: Clip.hardEdge),
      );
      await tester.pumpWidget(
        MaterialApp(
          theme: theme,
          home: Scaffold(
            body: CarouselView(
              itemExtent: 350,
              children: List<Widget>.generate(3, (int index) {
                return Text('Item $index');
              }),
            ),
          ),
        ),
      );

      final Material material = tester.firstWidget<Material>(
        find.ancestor(of: find.text('Item 0'), matching: find.byType(Material)),
      );

      expect(material.clipBehavior, Clip.hardEdge);
    });

    testWidgets('CarouselView.weighted item clipBehavior respects theme', (
      WidgetTester tester,
    ) async {
      final theme = ThemeData(
        carouselViewTheme: const CarouselViewThemeData(itemClipBehavior: Clip.hardEdge),
      );
      await tester.pumpWidget(
        MaterialApp(
          theme: theme,
          home: Scaffold(
            body: CarouselView.weighted(
              flexWeights: const <int>[1, 1, 1],
              children: List<Widget>.generate(3, (int index) {
                return Text('Item $index');
              }),
            ),
          ),
        ),
      );

      final Material material = tester.firstWidget<Material>(
        find.ancestor(of: find.text('Item 0'), matching: find.byType(Material)),
      );

      expect(material.clipBehavior, Clip.hardEdge);
    });
  });

  testWidgets('CarouselView item clipBehavior respects custom itemClipBehavior', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 350,
            itemClipBehavior: Clip.hardEdge,
            children: List<Widget>.generate(3, (int index) {
              return Text('Item $index');
            }),
          ),
        ),
      ),
    );

    final Material material = tester.firstWidget<Material>(
      find.ancestor(of: find.text('Item 0'), matching: find.byType(Material)),
    );

    expect(material.clipBehavior, Clip.hardEdge);
  });

  testWidgets('CarouselView.weighted item clipBehavior respects custom itemClipBehavior', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: CarouselView.weighted(
            flexWeights: const <int>[1, 1, 1],
            itemClipBehavior: Clip.hardEdge,
            children: List<Widget>.generate(3, (int index) {
              return Text('Item $index');
            }),
          ),
        ),
      ),
    );

    final Material material = tester.firstWidget<Material>(
      find.ancestor(of: find.text('Item 0'), matching: find.byType(Material)),
    );

    expect(material.clipBehavior, Clip.hardEdge);
  });

  testWidgets('scrolls correctly in RTL', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Directionality(
          textDirection: TextDirection.rtl,
          child: Scaffold(
            body: CarouselView(
              itemExtent: 600.0,
              children: [
                Center(key: ValueKey(0), child: Text('Item 0')),
                Center(key: ValueKey(1), child: Text('Item 1')),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

    final Finder item0 = find.byKey(const ValueKey(0));
    final double before = tester.getCenter(item0).dx;

    await tester.drag(find.byType(CarouselView), const Offset(500, 0));
    await tester.pumpAndSettle();

    final double after = tester.getCenter(item0).dx;
    expect(after, greaterThan(before));

    final ScrollableState scrollable = tester.state(find.byType(Scrollable));
    expect(scrollable.axisDirection, AxisDirection.left);
  });

  testWidgets('scrolls correctly in RTL with reverse', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Directionality(
          textDirection: TextDirection.rtl,
          child: Scaffold(
            body: CarouselView(
              reverse: true,
              itemExtent: 600.0,
              children: [
                Center(key: ValueKey(0), child: Text('Item 0')),
                Center(key: ValueKey(1), child: Text('Item 1')),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

    final Finder item0 = find.byKey(const ValueKey(0));
    final double before = tester.getCenter(item0).dx;

    await tester.drag(find.byType(CarouselView), const Offset(-500, 0));
    await tester.pumpAndSettle();

    final double after = tester.getCenter(item0).dx;
    expect(after, lessThan(before));

    final ScrollableState scrollable = tester.state(find.byType(Scrollable));
    expect(scrollable.axisDirection, AxisDirection.right);
  });

  testWidgets('snaps back to item boundary after partial scroll', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: CarouselView(
            itemExtent: 600.0,
            itemSnapping: true,
            children: [
              SizedBox(key: ValueKey(0), width: 600, height: 600),
              SizedBox(key: ValueKey(1), width: 600, height: 600),
            ],
          ),
        ),
      ),
    );

    await tester.drag(find.byType(CarouselView), const Offset(-100, 0));

    await tester.pumpAndSettle();

    final ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;

    expect(position.pixels, 0.0);
  });
}

Finder getItem(int index) {
  return find.descendant(
    of: find.byType(CarouselView),
    matching: find.ancestor(of: find.text('Item $index'), matching: find.byType(Padding)),
  );
}

Future<TestGesture> hoverPointerOverCarouselItem(WidgetTester tester, Key key) async {
  final Offset center = tester.getCenter(find.byKey(key));
  final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);

  // On hovered.
  await gesture.addPointer();
  await gesture.moveTo(center);
  return gesture;
}

Future<void> runCarouselTest({
  required WidgetTester tester,
  List<int> flexWeights = const <int>[],
  bool consumeMaxWeight = true,
  required int numberOfChildren,
  required Axis scrollDirection,
  required bool reverse,
}) async {
  final controller = CarouselController();
  addTearDown(controller.dispose);
  await tester.pumpWidget(
    MaterialApp(
      home: Scaffold(
        body: flexWeights.isEmpty
            ? CarouselView(
                scrollDirection: scrollDirection,
                reverse: reverse,
                controller: controller,
                itemSnapping: true,
                itemExtent: 300,
                children: List<Widget>.generate(numberOfChildren, (int index) {
                  return Center(child: Text('Item $index'));
                }),
              )
            : CarouselView.weighted(
                flexWeights: flexWeights,
                scrollDirection: scrollDirection,
                reverse: reverse,
                controller: controller,
                itemSnapping: true,
                consumeMaxWeight: consumeMaxWeight,
                children: List<Widget>.generate(numberOfChildren, (int index) {
                  return Center(child: Text('Item $index'));
                }),
              ),
      ),
    ),
  );

  double realOffset() {
    return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
  }

  // Calculate the index of the middle item.
  // The calculation depends on the scroll direction (normal or reverse).
  // For reverse scrolling, the middle item is calculated taking into account the end of the list,
  // reversing the calculation so that the item that appears in the middle when scrolling is the correct one.
  // For normal scrolling, we simply get the middle item.
  final int middleIndex = reverse
      ? (numberOfChildren - 1 - (numberOfChildren / 2).round())
      : (numberOfChildren / 2).round();

  controller.animateToItem(
    middleIndex,
    duration: const Duration(milliseconds: 100),
    curve: Curves.easeInOut,
  );
  await tester.pumpAndSettle();

  // Verify that the middle item is visible.
  expect(find.text('Item $middleIndex'), findsOneWidget);
  expect(realOffset(), controller.offset);

  // Scroll to the first item.
  controller.animateToItem(0, duration: const Duration(milliseconds: 100), curve: Curves.easeInOut);
  await tester.pumpAndSettle();

  // Verify that the first item is visible.
  expect(find.text('Item 0'), findsOneWidget);
  expect(realOffset(), controller.offset);
}
