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

import '../rendering/mock_canvas.dart';

class TestCanvas implements Canvas {
  final List<Invocation> invocations = <Invocation>[];

  @override
  void noSuchMethod(Invocation invocation) {
    invocations.add(invocation);
  }
}

Widget _buildBoilerplate({
  TextDirection textDirection = TextDirection.ltr,
  EdgeInsets padding = EdgeInsets.zero,
  required Widget child,
}) {
  return Directionality(
    textDirection: textDirection,
    child: MediaQuery(
      data: MediaQueryData(padding: padding),
      child: child,
    ),
  );
}

void main() {
  testWidgets("Scrollbar doesn't show when tapping list", (WidgetTester tester) async {
    await tester.pumpWidget(
      _buildBoilerplate(
        child: Center(
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: const Color(0xFFFFFF00))
            ),
            height: 200.0,
            width: 300.0,
            child: Scrollbar(
              child: ListView(
                children: <Widget>[
                  Container(height: 40.0, child: const Text('0')),
                  Container(height: 40.0, child: const Text('1')),
                  Container(height: 40.0, child: const Text('2')),
                  Container(height: 40.0, child: const Text('3')),
                  Container(height: 40.0, child: const Text('4')),
                  Container(height: 40.0, child: const Text('5')),
                  Container(height: 40.0, child: const Text('6')),
                  Container(height: 40.0, child: const Text('7')),
                ],
              ),
            ),
          ),
        ),
      ),
    );

    SchedulerBinding.instance!.debugAssertNoTransientCallbacks('Building a list with a scrollbar triggered an animation.');
    await tester.tap(find.byType(ListView));
    SchedulerBinding.instance!.debugAssertNoTransientCallbacks('Tapping a block with a scrollbar triggered an animation.');
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.drag(find.byType(ListView), const Offset(0.0, -10.0));
    expect(SchedulerBinding.instance!.transientCallbackCount, greaterThan(0));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
  });

  testWidgets('ScrollbarPainter does not divide by zero', (WidgetTester tester) async {
    await tester.pumpWidget(
      _buildBoilerplate(child: Container(
        height: 200.0,
        width: 300.0,
        child: Scrollbar(
          child: ListView(
            children: <Widget>[
              Container(height: 40.0, child: const Text('0')),
            ],
          ),
        ),
      )),
    );

    final CustomPaint custom = tester.widget(find.descendant(
      of: find.byType(Scrollbar),
      matching: find.byType(CustomPaint),
    ).first);
    final dynamic scrollPainter = custom.foregroundPainter;
    // Dragging makes the scrollbar first appear.
    await tester.drag(find.text('0'), const Offset(0.0, -10.0));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));

    final ScrollMetrics metrics = FixedScrollMetrics(
      minScrollExtent: 0.0,
      maxScrollExtent: 0.0,
      pixels: 0.0,
      viewportDimension: 100.0,
      axisDirection: AxisDirection.down,
    );
    scrollPainter.update(metrics, AxisDirection.down);

    final TestCanvas canvas = TestCanvas();
    scrollPainter.paint(canvas, const Size(10.0, 100.0));

    // Scrollbar is not supposed to draw anything if there isn't enough content.
    expect(canvas.invocations.isEmpty, isTrue);
  });

  testWidgets('Adaptive scrollbar', (WidgetTester tester) async {
    Widget viewWithScroll(TargetPlatform platform) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(
            platform: platform
          ),
          child: const Scrollbar(
            child: SingleChildScrollView(
              child: SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll(TargetPlatform.android));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    // Scrollbar fully showing
    await tester.pump(const Duration(milliseconds: 500));
    expect(find.byType(Scrollbar), paints..rect());

    await tester.pumpWidget(viewWithScroll(TargetPlatform.iOS));
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView))
    );
    await gesture.moveBy(const Offset(0.0, -10.0));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.byType(Scrollbar), paints..rrect());
    expect(find.byType(CupertinoScrollbar), paints..rrect());
    await gesture.up();
    await tester.pumpAndSettle();

    await tester.pumpWidget(viewWithScroll(TargetPlatform.macOS));
    await gesture.down(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -10.0));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.byType(Scrollbar), paints..rrect());
    expect(find.byType(CupertinoScrollbar), paints..rrect());
  });

  testWidgets('Scrollbar passes controller to CupertinoScrollbar', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll(TargetPlatform? platform) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(
            platform: platform
          ),
          child: Scrollbar(
            controller: controller,
            child: const SingleChildScrollView(
              child: SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll(debugDefaultTargetPlatformOverride));
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView))
    );
    await gesture.moveBy(const Offset(0.0, -10.0));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.byType(CupertinoScrollbar), paints..rrect());
    final CupertinoScrollbar scrollbar = find.byType(CupertinoScrollbar).evaluate().first.widget as CupertinoScrollbar;
    expect(scrollbar.controller, isNotNull);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('When isAlwaysShown is true, must pass a controller',
      (WidgetTester tester) async {
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            isAlwaysShown: true,
            child: const SingleChildScrollView(
              child: SizedBox(
                width: 4000.0,
                height: 4000.0,
              ),
            ),
          ),
        ),
      );
    }

    expect(() async {
      await tester.pumpWidget(viewWithScroll());
    }, throwsAssertionError);
  });

  testWidgets('When isAlwaysShown is true, must pass a controller that is attached to a scroll view',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            isAlwaysShown: true,
            controller: controller,
            child: const SingleChildScrollView(
              child: SizedBox(
                width: 4000.0,
                height: 4000.0,
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    final dynamic exception = tester.takeException();
    expect(exception, isAssertionError);
  });

  testWidgets('On first render with isAlwaysShown: true, the thumb shows',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            isAlwaysShown: true,
            controller: controller,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(
                width: 4000.0,
                height: 4000.0,
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), paints..rect());
  });

  testWidgets('On first render with isAlwaysShown: false, the thumb is hidden',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            isAlwaysShown: false,
            controller: controller,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(
                width: 4000.0,
                height: 4000.0,
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), isNot(paints..rect()));
  });

  testWidgets(
      'With isAlwaysShown: true, fling a scroll. While it is still scrolling, set isAlwaysShown: false. The thumb should not fade out until the scrolling stops.',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    bool isAlwaysShown = true;
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Theme(
              data: ThemeData(),
              child: Scaffold(
                floatingActionButton: FloatingActionButton(
                  child: const Icon(Icons.threed_rotation),
                  onPressed: () {
                    setState(() {
                      isAlwaysShown = !isAlwaysShown;
                    });
                  },
                ),
                body: Scrollbar(
                  isAlwaysShown: isAlwaysShown,
                  controller: controller,
                  child: SingleChildScrollView(
                    controller: controller,
                    child: const SizedBox(
                      width: 4000.0,
                      height: 4000.0,
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    await tester.fling(
      find.byType(SingleChildScrollView),
      const Offset(0.0, -10.0),
      10,
    );
    expect(find.byType(Scrollbar), paints..rect());

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pumpAndSettle();
    // Scrollbar is not showing after scroll finishes
    expect(find.byType(Scrollbar), isNot(paints..rect()));
  });

  testWidgets(
      'With isAlwaysShown: false, set isAlwaysShown: true. The thumb should be always shown directly',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    bool isAlwaysShown = false;
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Theme(
              data: ThemeData(),
              child: Scaffold(
                floatingActionButton: FloatingActionButton(
                  child: const Icon(Icons.threed_rotation),
                  onPressed: () {
                    setState(() {
                      isAlwaysShown = !isAlwaysShown;
                    });
                  },
                ),
                body: Scrollbar(
                  isAlwaysShown: isAlwaysShown,
                  controller: controller,
                  child: SingleChildScrollView(
                    controller: controller,
                    child: const SizedBox(
                      width: 4000.0,
                      height: 4000.0,
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), isNot(paints..rect()));

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pumpAndSettle();
    // Scrollbar is not showing after scroll finishes
    expect(find.byType(Scrollbar), paints..rect());
  });

  testWidgets(
      'With isAlwaysShown: false, fling a scroll. While it is still scrolling, set isAlwaysShown: true. The thumb should not fade even after the scrolling stops',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    bool isAlwaysShown = false;
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Theme(
              data: ThemeData(),
              child: Scaffold(
                floatingActionButton: FloatingActionButton(
                  child: const Icon(Icons.threed_rotation),
                  onPressed: () {
                    setState(() {
                      isAlwaysShown = !isAlwaysShown;
                    });
                  },
                ),
                body: Scrollbar(
                  isAlwaysShown: isAlwaysShown,
                  controller: controller,
                  child: SingleChildScrollView(
                    controller: controller,
                    child: const SizedBox(
                      width: 4000.0,
                      height: 4000.0,
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), isNot(paints..rect()));
    await tester.fling(
      find.byType(SingleChildScrollView),
      const Offset(0.0, -10.0),
      10,
    );
    expect(find.byType(Scrollbar), paints..rect());

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pump();
    expect(find.byType(Scrollbar), paints..rect());

    // Wait for the timer delay to expire.
    await tester.pump(const Duration(milliseconds: 600)); // _kScrollbarTimeToFade
    await tester.pumpAndSettle();
    // Scrollbar thumb is showing after scroll finishes and timer ends.
    expect(find.byType(Scrollbar), paints..rect());
  });

  testWidgets(
      'Toggling isAlwaysShown while not scrolling fades the thumb in/out. This works even when you have never scrolled at all yet',
      (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    bool isAlwaysShown = true;
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Theme(
              data: ThemeData(),
              child: Scaffold(
                floatingActionButton: FloatingActionButton(
                  child: const Icon(Icons.threed_rotation),
                  onPressed: () {
                    setState(() {
                      isAlwaysShown = !isAlwaysShown;
                    });
                  },
                ),
                body: Scrollbar(
                  isAlwaysShown: isAlwaysShown,
                  controller: controller,
                  child: SingleChildScrollView(
                    controller: controller,
                    child: const SizedBox(
                      width: 4000.0,
                      height: 4000.0,
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    final Finder materialScrollbar = find.byType(Scrollbar);
    expect(materialScrollbar, paints..rect());

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pumpAndSettle();
    expect(materialScrollbar, isNot(paints..rect()));
  });

  testWidgets('Scrollbar respects thickness and radius', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll({Radius? radius}) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            controller: controller,
            thickness: 20,
            radius: radius,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(
                width: 1600.0,
                height: 1200.0,
              ),
            ),
          ),
        ),
      );
    }

    // Scroll a bit to cause the scrollbar thumb to be shown;
    // undo the scroll to put the thumb back at the top.
    await tester.pumpWidget(viewWithScroll());
    const double scrollAmount = 10.0;
    final TestGesture scrollGesture = await tester.startGesture(tester.getCenter(find.byType(SingleChildScrollView)));
    await scrollGesture.moveBy(const Offset(0.0, -scrollAmount));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));
    await scrollGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pump();
    await scrollGesture.up();
    await tester.pump();

    // Long press on the scrollbar thumb and expect it to grow
    expect(find.byType(Scrollbar), paints..rect(
      rect: const Rect.fromLTWH(780, 0, 20, 300),
    ));
    await tester.pumpWidget(viewWithScroll(radius: const Radius.circular(10)));
    expect(find.byType(Scrollbar), paints..rrect(
      rrect: RRect.fromRectAndRadius(const Rect.fromLTWH(780, 0, 20, 300), const Radius.circular(10)),
    ));

    await tester.pumpAndSettle();
  });
}
