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

const TextStyle testFont = TextStyle(
  color: Color(0xFF00FF00),
  fontFamily: 'Ahem',
);

Future<void> pumpTest(WidgetTester tester, TargetPlatform platform) async {
  await tester.pumpWidget(Container());
  await tester.pumpWidget(MaterialApp(
    theme: ThemeData(
      platform: platform,
    ),
    home: ColoredBox(
      color: const Color(0xFF111111),
      child: ListView.builder(
        dragStartBehavior: DragStartBehavior.down,
        itemBuilder: (BuildContext context, int index) {
          return Text('$index', style: testFont);
        },
      ),
    ),
  ));
}

const double dragOffset = 213.82;

void main() {
  testWidgets('Flings on different platforms', (WidgetTester tester) async {
    double getCurrentOffset() {
      return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
    }

    await pumpTest(tester, TargetPlatform.android);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(const Duration(seconds: 5));
    final double androidResult = getCurrentOffset();
    // Regression test for https://github.com/flutter/flutter/issues/83632
    // Before changing these values, ensure the fling results in a distance that
    // makes sense. See issue for more context.
    expect(androidResult, greaterThan(394.0));
    expect(androidResult, lessThan(395.0));

    await pumpTest(tester, TargetPlatform.linux);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(const Duration(seconds: 5));
    final double linuxResult = getCurrentOffset();

    await pumpTest(tester, TargetPlatform.windows);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(const Duration(seconds: 5));
    final double windowsResult = getCurrentOffset();

    await pumpTest(tester, TargetPlatform.iOS);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    // Scroll starts ease into the scroll on iOS.
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
    await tester.pump(const Duration(seconds: 5));
    final double iOSResult = getCurrentOffset();

    await pumpTest(tester, TargetPlatform.macOS);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    // Scroll starts ease into the scroll on iOS.
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
    await tester.pump(const Duration(seconds: 5));
    final double macOSResult = getCurrentOffset();

    expect(androidResult, lessThan(iOSResult)); // iOS is slipperier than Android
    expect(macOSResult, lessThan(iOSResult)); // iOS is slipperier than macOS
    expect(macOSResult, lessThan(androidResult)); // Android is slipperier than macOS
    expect(linuxResult, lessThan(iOSResult)); // iOS is slipperier than Linux
    expect(macOSResult, lessThan(linuxResult)); // Linux is slipperier than macOS
    expect(windowsResult, lessThan(iOSResult)); // iOS is slipperier than Windows
    expect(macOSResult, lessThan(windowsResult)); // Windows is slipperier than macOS
    expect(windowsResult, equals(androidResult));
    expect(windowsResult, equals(androidResult));
    expect(linuxResult, equals(androidResult));
    expect(linuxResult, equals(androidResult));
  });

  testWidgets('fling and tap to stop', (WidgetTester tester) async {
    final List<String> log = <String>[];
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          dragStartBehavior: DragStartBehavior.down,
          children: List<Widget>.generate(250, (int i) => GestureDetector(
            onTap: () { log.add('tap $i'); },
            child: Text('$i', style: testFont),
          )),
        ),
      ),
    );

    expect(log, equals(<String>[]));
    await tester.tap(find.byType(Scrollable));
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21']));
    await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21']));
    await tester.tap(find.byType(Scrollable)); // should stop the fling but not tap anything
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21']));
    await tester.tap(find.byType(Scrollable));
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21', 'tap 35']));
  });

  testWidgets('fling and wait and tap', (WidgetTester tester) async {
    final List<String> log = <String>[];
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          dragStartBehavior: DragStartBehavior.down,
          children: List<Widget>.generate(250, (int i) => GestureDetector(
            onTap: () { log.add('tap $i'); },
            child: Text('$i', style: testFont),
          )),
        ),
      ),
    );

    expect(log, equals(<String>[]));
    await tester.tap(find.byType(Scrollable));
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21']));
    await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21']));
    await tester.pump(const Duration(seconds: 50)); // long wait, so the fling will have ended at the end of it
    expect(log, equals(<String>['tap 21']));
    await tester.tap(find.byType(Scrollable));
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, equals(<String>['tap 21', 'tap 48']));
  });
}
