// 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/gestures.dart' show DragStartBehavior;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

const List<int> items = <int>[0, 1, 2, 3, 4, 5];

void main() {
  testWidgets('Tap item after scroll - horizontal', (WidgetTester tester) async {
    final List<int> tapped = <int>[];
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox(
            height: 50.0,
            child: ListView(
              dragStartBehavior: DragStartBehavior.down,
              itemExtent: 290.0,
              scrollDirection: Axis.horizontal,
              children: items.map<Widget>((int item) {
                return GestureDetector(
                  onTap: () { tapped.add(item); },
                  dragStartBehavior: DragStartBehavior.down,
                  child: Text('$item'),
                );
              }).toList(),
            ),
          ),
        ),
      ),
    );
    await tester.drag(find.text('2'), const Offset(-280.0, 0.0));
    await tester.pump(const Duration(seconds: 1));
    // screen is 800px wide, and has the following items:
    //  -280..10  = 0
    //    10..300 = 1
    //   300..590 = 2
    //   590..880 = 3
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
    expect(find.text('3'), findsOneWidget);
    expect(find.text('4'), findsNothing);
    expect(find.text('5'), findsNothing);
    expect(tapped, equals(<int>[]));
    await tester.tap(find.text('2'));
    expect(tapped, equals(<int>[2]));
  });

  testWidgets('Tap item after scroll - vertical', (WidgetTester tester) async {
    final List<int> tapped = <int>[];
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox(
            width: 50.0,
            child: ListView(
              dragStartBehavior: DragStartBehavior.down,
              itemExtent: 290.0,
              children: items.map<Widget>((int item) {
                return GestureDetector(
                  onTap: () { tapped.add(item); },
                  dragStartBehavior: DragStartBehavior.down,
                  child: Text('$item'),
                );
              }).toList(),
            ),
          ),
        ),
      ),
    );
    await tester.drag(find.text('1'), const Offset(0.0, -280.0));
    await tester.pump(const Duration(seconds: 1));
    // screen is 600px tall, and has the following items:
    //  -280..10  = 0
    //    10..300 = 1
    //   300..590 = 2
    //   590..880 = 3
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
    expect(find.text('3'), findsOneWidget);
    expect(find.text('4'), findsNothing);
    expect(find.text('5'), findsNothing);
    expect(tapped, equals(<int>[]));
    await tester.tap(find.text('1'));
    expect(tapped, equals(<int>[1]));
    await tester.tap(find.text('3'), warnIfMissed: false);
    expect(tapped, equals(<int>[1])); // the center of the third item is off-screen so it shouldn't get hit
  });

  testWidgets('Padding scroll anchor start', (WidgetTester tester) async {
    final List<int> tapped = <int>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          itemExtent: 290.0,
          padding: const EdgeInsets.fromLTRB(5.0, 20.0, 15.0, 10.0),
          children: items.map<Widget>((int item) {
            return GestureDetector(
              onTap: () { tapped.add(item); },
              child: Text('$item'),
            );
          }).toList(),
        ),
      ),
    );
    await tester.tapAt(const Offset(200.0, 19.0));
    expect(tapped, equals(<int>[]));
    await tester.tapAt(const Offset(200.0, 21.0));
    expect(tapped, equals(<int>[0]));
    await tester.tapAt(const Offset(4.0, 400.0));
    expect(tapped, equals(<int>[0]));
    await tester.tapAt(const Offset(6.0, 400.0));
    expect(tapped, equals(<int>[0, 1]));
    await tester.tapAt(const Offset(800.0 - 14.0, 400.0));
    expect(tapped, equals(<int>[0, 1]));
    await tester.tapAt(const Offset(800.0 - 16.0, 400.0));
    expect(tapped, equals(<int>[0, 1, 1]));
  });

  testWidgets('Padding scroll anchor end', (WidgetTester tester) async {
    final List<int> tapped = <int>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          itemExtent: 290.0,
          reverse: true,
          padding: const EdgeInsets.fromLTRB(5.0, 20.0, 15.0, 10.0),
          children: items.map<Widget>((int item) {
            return GestureDetector(
              onTap: () { tapped.add(item); },
              child: Text('$item'),
            );
          }).toList(),
        ),
      ),
    );
    await tester.tapAt(const Offset(200.0, 600.0 - 9.0));
    expect(tapped, equals(<int>[]));
    await tester.tapAt(const Offset(200.0, 600.0 - 11.0));
    expect(tapped, equals(<int>[0]));
    await tester.tapAt(const Offset(4.0, 200.0));
    expect(tapped, equals(<int>[0]));
    await tester.tapAt(const Offset(6.0, 200.0));
    expect(tapped, equals(<int>[0, 1]));
    await tester.tapAt(const Offset(800.0 - 14.0, 200.0));
    expect(tapped, equals(<int>[0, 1]));
    await tester.tapAt(const Offset(800.0 - 16.0, 200.0));
    expect(tapped, equals(<int>[0, 1, 1]));
  });

  testWidgets('Tap immediately following clamped overscroll', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/5709
    final List<int> tapped = <int>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          itemExtent: 200.0,
          children: items.map<Widget>((int item) {
            return GestureDetector(
              onTap: () { tapped.add(item); },
              child: Text('$item'),
            );
          }).toList(),
        ),
      ),
    );

    await tester.fling(find.text('0'), const Offset(0.0, 400.0), 1000.0);
    final ScrollableState scrollable = tester.state(find.byType(Scrollable));
    expect(scrollable.position.pixels, equals(0.0));

    await tester.tapAt(const Offset(200.0, 100.0));
    expect(tapped, equals(<int>[0]));
  });
}
