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

ScrollController _controller = ScrollController(
  initialScrollOffset: 110.0,
);

class ThePositiveNumbers extends StatelessWidget {
  const ThePositiveNumbers({
    Key? key,
    required this.from,
  }) : super(key: key);
  final int from;
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      key: const PageStorageKey<String>('ThePositiveNumbers'),
      itemExtent: 100.0,
      controller: _controller,
      itemBuilder: (BuildContext context, int index) {
        return Text('${index + from}', key: ValueKey<int>(index));
      },
    );
  }
}

Future<void> performTest(WidgetTester tester, bool maintainState) async {
  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
  await tester.pumpWidget(
    Directionality(
      textDirection: TextDirection.ltr,
      child: Navigator(
        key: navigatorKey,
        onGenerateRoute: (RouteSettings settings) {
          if (settings.name == '/') {
            return MaterialPageRoute<void>(
              settings: settings,
              builder: (_) => const ThePositiveNumbers(from: 0),
              maintainState: maintainState,
            );
          } else if (settings.name == '/second') {
            return MaterialPageRoute<void>(
              settings: settings,
              builder: (_) => const ThePositiveNumbers(from: 10000),
              maintainState: maintainState,
            );
          }
          return null;
        },
      ),
    ),
  );

  // we're 600 pixels high, each item is 100 pixels high, scroll position is
  // 110.0, so we should have 7 items, 1..7.
  expect(find.text('0'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('1'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('2'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('3'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('4'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('5'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('6'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('7'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('8'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('100'), findsNothing, reason: 'with maintainState: $maintainState');

  tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(1000.0);
  await tester.pump(const Duration(seconds: 1));

  // we're 600 pixels high, each item is 100 pixels high, scroll position is
  // 1000, so we should have exactly 6 items, 10..15.

  expect(find.text('0'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('1'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('8'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('9'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('11'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('12'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('13'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('14'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('15'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('16'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('100'), findsNothing, reason: 'with maintainState: $maintainState');

  navigatorKey.currentState!.pushNamed('/second');
  await tester.pump(); // navigating always takes two frames, one to start...
  await tester.pump(const Duration(seconds: 1)); // ...and one to end the transition

  // the second list is now visible, starting at 10001
  expect(find.text('0'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('1'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('11'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10000'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10001'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10002'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10003'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10004'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10005'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10006'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10007'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('10008'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10010'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10100'), findsNothing, reason: 'with maintainState: $maintainState');

  navigatorKey.currentState!.pop();
  await tester.pump(); // again, navigating always takes two frames

  // Ensure we don't clamp the scroll offset even during the navigation.
  // https://github.com/flutter/flutter/issues/4883
  final ScrollableState state = tester.state(find.byType(Scrollable).first);
  expect(state.position.pixels, equals(1000.0), reason: 'with maintainState: $maintainState');

  await tester.pump(const Duration(seconds: 1));

  // we're 600 pixels high, each item is 100 pixels high, scroll position is
  // 1000, so we should have exactly 6 items, 10..15.

  expect(find.text('0'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('1'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('8'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('9'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('10'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('11'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('12'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('13'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('14'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('15'), findsOneWidget, reason: 'with maintainState: $maintainState');
  expect(find.text('16'), findsNothing, reason: 'with maintainState: $maintainState');
  expect(find.text('100'), findsNothing, reason: 'with maintainState: $maintainState');
}

void main() {
  testWidgets("ScrollPosition jumpTo() doesn't call notifyListeners twice", (WidgetTester tester) async {
    int count = 0;
    await tester.pumpWidget(MaterialApp(
      home: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return Text('$index', textDirection: TextDirection.ltr);
        },
      ),
    ));

    final ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;
    position.addListener(() {
      count++;
    });
    position.jumpTo(100);

    expect(count, 1);
  });

  testWidgets('whether we remember our scroll position', (WidgetTester tester) async {
    await performTest(tester, true);
    await performTest(tester, false);
  });

  testWidgets('scroll alignment is honored by ensureVisible', (WidgetTester tester) async {
    final List<int> items = List<int>.generate(11, (int index) => index).toList();
    final List<FocusNode> nodes = List<FocusNode>.generate(11, (int index) => FocusNode(debugLabel: 'Item ${index + 1}')).toList();
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: ListView(
          controller: controller,
          children: items.map<Widget>((int item) {
            return Focus(
              key: ValueKey<int>(item),
              focusNode: nodes[item],
              child: Container(height: 110),
            );
          }).toList(),
        ),
      ),
    );

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(0))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtStart,
    );
    expect(controller.position.pixels, equals(0.0));

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(1))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtStart,
    );
    expect(controller.position.pixels, equals(0.0));

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(1))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
    );
    expect(controller.position.pixels, equals(0.0));

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(4))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtStart,
    );
    expect(controller.position.pixels, equals(0.0));

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(5))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtStart,
    );
    expect(controller.position.pixels, equals(0.0));

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(5))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
    );
    expect(controller.position.pixels, equals(60.0));

    controller.position.ensureVisible(
      tester.renderObject(find.byKey(const ValueKey<int>(0))),
      alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtStart,
    );
    expect(controller.position.pixels, equals(0.0));
  });

  testWidgets('jumpTo recommends deferred loading', (WidgetTester tester) async {
    int loadedWithDeferral = 0;
    int buildCount = 0;
    const double height = 500;
    await tester.pumpWidget(MaterialApp(
      home: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          buildCount += 1;
          if (Scrollable.recommendDeferredLoadingForContext(context)) {
            loadedWithDeferral += 1;
          }
          return const SizedBox(height: height);
        },
      ),
    ));

    // The two visible on screen should have loaded without deferral.
    expect(buildCount, 2);
    expect(loadedWithDeferral, 0);

    final ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;
    position.jumpTo(height * 100);
    await tester.pump();

    // All but the first two that were loaded normally should have gotten a
    // recommendation to defer.
    expect(buildCount, 102);
    expect(loadedWithDeferral, 100);

    position.jumpTo(height * 102);
    await tester.pump();

    // The smaller jump should not have recommended deferral.
    expect(buildCount, 104);
    expect(loadedWithDeferral, 100);
  });
}
