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

class TestSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
  TestSliverPersistentHeaderDelegate(this._maxExtent);

  final double _maxExtent;

  @override
  double get maxExtent => _maxExtent;

  @override
  double get minExtent => 16.0;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Column(
      children: <Widget>[
        Container(height: minExtent),
        Expanded(child: Container()),
      ],
    );
  }

  @override
  bool shouldRebuild(TestSliverPersistentHeaderDelegate oldDelegate) => false;
}

class TestBehavior extends ScrollBehavior {
  const TestBehavior();

  @override
  Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
    return GlowingOverscrollIndicator(
      axisDirection: details.direction,
      color: const Color(0xFFFFFFFF),
      child: child,
    );
  }
}

class TestScrollPhysics extends ClampingScrollPhysics {
  const TestScrollPhysics({ ScrollPhysics? parent }) : super(parent: parent);

  @override
  TestScrollPhysics applyTo(ScrollPhysics? ancestor) {
    return TestScrollPhysics(parent: parent?.applyTo(ancestor) ?? ancestor);
  }

  @override
  Tolerance get tolerance => const Tolerance(velocity: 20.0, distance: 1.0);
}

class TestViewportScrollPosition extends ScrollPositionWithSingleContext {
  TestViewportScrollPosition({
    required ScrollPhysics physics,
    required ScrollContext context,
    ScrollPosition? oldPosition,
  }) : super(physics: physics, context: context, oldPosition: oldPosition);

  @override
  bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
    expect(minScrollExtent, moreOrLessEquals(-3895.0));
    expect(maxScrollExtent, moreOrLessEquals(8575.0));
    return super.applyContentDimensions(minScrollExtent, maxScrollExtent);
  }
}

void main() {
  testWidgets('Evil test of sliver features - 1', (WidgetTester tester) async {
    final GlobalKey centerKey = GlobalKey();
    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: ScrollConfiguration(
            behavior: const TestBehavior(),
            child: Scrollbar(
              child: Scrollable(
                physics: const TestScrollPhysics(),
                viewportBuilder: (BuildContext context, ViewportOffset offset) {
                  return Viewport(
                    anchor: 0.25,
                    offset: offset,
                    center: centerKey,
                    slivers: <Widget>[
                      SliverToBoxAdapter(child: Container(height: 5.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(150.0), pinned: true),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPadding(
                        padding: const EdgeInsets.all(50.0),
                        sliver: SliverToBoxAdapter(child: Container(height: 520.0)),
                      ),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(150.0), floating: true),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(key: centerKey, child: Container(height: 520.0)), // ------------------------ CENTER ------------------------
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(150.0), pinned: true),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPadding(
                        padding: const EdgeInsets.all(50.0),
                        sliver: SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0), pinned: true),
                      ),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0), pinned: true),
                      SliverToBoxAdapter(child: Container(height: 5.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0), pinned: true),
                      SliverToBoxAdapter(child: Container(height: 5.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0), pinned: true),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0), pinned: true),
                      SliverToBoxAdapter(child: Container(height: 5.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0), pinned: true),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(150.0), floating: true),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(150.0), floating: true),
                      SliverToBoxAdapter(child: Container(height: 5.0)),
                      SliverList(
                        delegate: SliverChildListDelegate(<Widget>[
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                          Container(height: 50.0),
                        ]),
                      ),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0)),
                      SliverPersistentHeader(delegate: TestSliverPersistentHeaderDelegate(250.0)),
                      SliverPadding(
                        padding: const EdgeInsets.symmetric(horizontal: 50.0),
                        sliver: SliverToBoxAdapter(child: Container(height: 520.0)),
                      ),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(child: Container(height: 520.0)),
                      SliverToBoxAdapter(child: Container(height: 5.0)),
                    ],
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
    final ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;

    position.animateTo(10000.0, curve: Curves.linear, duration: const Duration(minutes: 1));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pumpAndSettle(const Duration(milliseconds: 122));

    position.animateTo(-10000.0, curve: Curves.linear, duration: const Duration(minutes: 1));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pumpAndSettle(const Duration(milliseconds: 122));

    position.animateTo(10000.0, curve: Curves.linear, duration: const Duration(minutes: 1));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pumpAndSettle(const Duration(milliseconds: 122));

    position.animateTo(-10000.0, curve: Curves.linear, duration: const Duration(seconds: 1));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pumpAndSettle(const Duration(milliseconds: 122));

    position.animateTo(10000.0, curve: Curves.linear, duration: const Duration(seconds: 1));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pumpAndSettle(const Duration(milliseconds: 122));

  });

  testWidgets('Removing offscreen items above and rescrolling does not crash', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: CustomScrollView(
        cacheExtent: 0.0,
        slivers: <Widget>[
          SliverFixedExtentList(
            itemExtent: 100.0,
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  color: Colors.blue,
                  child: Text(index.toString()),
                );
              },
              childCount: 30,
            ),
          ),
        ],
      ),
    ));

    await tester.drag(find.text('5'), const Offset(0.0, -500.0));
    await tester.pump();

    // Screen is 600px high. Moved bottom item 500px up. It's now at the top.
    expect(tester.getTopLeft(find.widgetWithText(Container, '5')).dy, 0.0);
    expect(tester.getBottomLeft(find.widgetWithText(Container, '10')).dy, 600.0);

    // Stop returning the first 3 items.
    await tester.pumpWidget(MaterialApp(
      home: CustomScrollView(
        cacheExtent: 0.0,
        slivers: <Widget>[
          SliverFixedExtentList(
            itemExtent: 100.0,
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                if (index > 3) {
                  return Container(
                    color: Colors.blue,
                    child: Text(index.toString()),
                  );
                }
                return null;
              },
              childCount: 30,
            ),
          ),
        ],
      ),
    ));

    await tester.drag(find.text('5'), const Offset(0.0, 400.0));
    await tester.pump();

    // Move up by 4 items, meaning item 1 would have been at the top but
    // 0 through 3 no longer exist, so item 4, 3 items down, is the first one.
    // Item 4 is also shifted to the top.
    expect(tester.getTopLeft(find.widgetWithText(Container, '4')).dy, 0.0);

    // Because the screen is still 600px, item 9 is now visible at the bottom instead
    // of what's supposed to be item 6 had we not re-shifted.
    expect(tester.getBottomLeft(find.widgetWithText(Container, '9')).dy, 600.0);
  });
}
