// 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.

// This file contains a wacky demonstration of creating a custom ScrollPosition
// setup. It's testing that we don't regress the factoring of the
// ScrollPosition/ScrollActivity logic into a state where you can no longer
// implement this, e.g. by oversimplifying it or overfitting it to the features
// built into the framework itself.

import 'dart:collection';
import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

class LinkedScrollController extends ScrollController {
  LinkedScrollController({ this.before, this.after });

  LinkedScrollController? before;
  LinkedScrollController? after;

  ScrollController? _parent;

  void setParent(ScrollController? newParent) {
    if (_parent != null) {
      positions.forEach(_parent!.detach);
    }
    _parent = newParent;
    if (_parent != null) {
      positions.forEach(_parent!.attach);
    }
  }

  @override
  void attach(ScrollPosition position) {
    assert(position is LinkedScrollPosition, 'A LinkedScrollController must only be used with LinkedScrollPositions.');
    final LinkedScrollPosition linkedPosition = position as LinkedScrollPosition;
    assert(linkedPosition.owner == this, 'A LinkedScrollPosition cannot change controllers once created.');
    super.attach(position);
    _parent?.attach(position);
  }

  @override
  void detach(ScrollPosition position) {
    super.detach(position);
    _parent?.detach(position);
  }

  @override
  void dispose() {
    if (_parent != null) {
      positions.forEach(_parent!.detach);
    }
    super.dispose();
  }

  @override
  LinkedScrollPosition createScrollPosition(ScrollPhysics physics, ScrollContext context, ScrollPosition? oldPosition) {
    return LinkedScrollPosition(
      this,
      physics: physics,
      context: context,
      initialPixels: initialScrollOffset,
      oldPosition: oldPosition,
    );
  }

  bool get canLinkWithBefore => before != null && before!.hasClients;

  bool get canLinkWithAfter => after != null && after!.hasClients;

  Iterable<LinkedScrollActivity> linkWithBefore(LinkedScrollPosition driver) {
    assert(canLinkWithBefore);
    return before!.link(driver);
  }

  Iterable<LinkedScrollActivity> linkWithAfter(LinkedScrollPosition driver) {
    assert(canLinkWithAfter);
    return after!.link(driver);
  }

  Iterable<LinkedScrollActivity> link(LinkedScrollPosition driver) sync* {
    assert(hasClients);
    for (final LinkedScrollPosition position in positions.cast<LinkedScrollPosition>()) {
      yield position.link(driver);
    }
  }

  @override
  void debugFillDescription(List<String> description) {
    super.debugFillDescription(description);
    if (before != null && after != null) {
      description.add('links: ⬌');
    } else if (before != null) {
      description.add('links: ⬅');
    } else if (after != null) {
      description.add('links: ➡');
    } else {
      description.add('links: none');
    }
  }

}

class LinkedScrollPosition extends ScrollPositionWithSingleContext {
  LinkedScrollPosition(
    this.owner, {
    required super.physics,
    required super.context,
    required double super.initialPixels,
    super.oldPosition,
  }) : assert(owner != null);

  final LinkedScrollController owner;

  Set<LinkedScrollActivity>? _beforeActivities;
  Set<LinkedScrollActivity>? _afterActivities;

  @override
  void beginActivity(ScrollActivity? newActivity) {
    if (newActivity == null) {
      return;
    }
    if (_beforeActivities != null) {
      for (final LinkedScrollActivity activity in _beforeActivities!) {
        activity.unlink(this);
      }
      _beforeActivities!.clear();
    }
    if (_afterActivities != null) {
      for (final LinkedScrollActivity activity in _afterActivities!) {
        activity.unlink(this);
      }
      _afterActivities!.clear();
    }
    super.beginActivity(newActivity);
  }

  @override
  void applyUserOffset(double delta) {
    updateUserScrollDirection(delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse);
    final double value = pixels - physics.applyPhysicsToUserOffset(this, delta);

    if (value == pixels) {
      return;
    }

    double beforeOverscroll = 0.0;
    if (owner.canLinkWithBefore && (value < minScrollExtent)) {
      final double delta = value - minScrollExtent;
      _beforeActivities ??= HashSet<LinkedScrollActivity>();
      _beforeActivities!.addAll(owner.linkWithBefore(this));
      for (final LinkedScrollActivity activity in _beforeActivities!) {
        beforeOverscroll = math.min(activity.moveBy(delta), beforeOverscroll);
      }
      assert(beforeOverscroll <= 0.0);
    }

    double afterOverscroll = 0.0;
    if (owner.canLinkWithAfter && (value > maxScrollExtent)) {
      final double delta = value - maxScrollExtent;
      _afterActivities ??= HashSet<LinkedScrollActivity>();
      _afterActivities!.addAll(owner.linkWithAfter(this));
      for (final LinkedScrollActivity activity in _afterActivities!) {
        afterOverscroll = math.max(activity.moveBy(delta), afterOverscroll);
      }
      assert(afterOverscroll >= 0.0);
    }

    assert(beforeOverscroll == 0.0 || afterOverscroll == 0.0);

    final double localOverscroll = setPixels(value.clamp(
      owner.canLinkWithBefore ? minScrollExtent : -double.infinity,
      owner.canLinkWithAfter ? maxScrollExtent : double.infinity,
    ));

    assert(localOverscroll == 0.0 || (beforeOverscroll == 0.0 && afterOverscroll == 0.0));
  }

  void _userMoved(ScrollDirection direction) {
    updateUserScrollDirection(direction);
  }

  LinkedScrollActivity link(LinkedScrollPosition driver) {
    if (this.activity is! LinkedScrollActivity) {
      beginActivity(LinkedScrollActivity(this));
    }
    final LinkedScrollActivity? activity = this.activity as LinkedScrollActivity?;
    activity!.link(driver);
    return activity;
  }

  void unlink(LinkedScrollActivity activity) {
    if (_beforeActivities != null) {
      _beforeActivities!.remove(activity);
    }
    if (_afterActivities != null) {
      _afterActivities!.remove(activity);
    }
  }

  @override
  void debugFillDescription(List<String> description) {
    super.debugFillDescription(description);
    description.add('owner: $owner');
  }
}

class LinkedScrollActivity extends ScrollActivity {
  LinkedScrollActivity(
    LinkedScrollPosition super.delegate,
  );

  @override
  LinkedScrollPosition get delegate => super.delegate as LinkedScrollPosition;

  final Set<LinkedScrollPosition> drivers = HashSet<LinkedScrollPosition>();

  void link(LinkedScrollPosition driver) {
    drivers.add(driver);
  }

  void unlink(LinkedScrollPosition driver) {
    drivers.remove(driver);
    if (drivers.isEmpty) {
      delegate.goIdle();
    }
  }

  @override
  bool get shouldIgnorePointer => true;

  @override
  bool get isScrolling => true;

  // LinkedScrollActivity is not self-driven but moved by calls to the [moveBy]
  // method.
  @override
  double get velocity => 0.0;

  double moveBy(double delta) {
    assert(drivers.isNotEmpty);
    ScrollDirection? commonDirection;
    for (final LinkedScrollPosition driver in drivers) {
      commonDirection ??= driver.userScrollDirection;
      if (driver.userScrollDirection != commonDirection) {
        commonDirection = ScrollDirection.idle;
      }
    }

    if (commonDirection != null) {
      delegate._userMoved(commonDirection);
    }
    return delegate.setPixels(delegate.pixels + delta);
  }

  @override
  void dispose() {
    for (final LinkedScrollPosition driver in drivers) {
      driver.unlink(this);
    }
    super.dispose();
  }
}

class Test extends StatefulWidget {
  const Test({ super.key });
  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  late LinkedScrollController _beforeController;
  late LinkedScrollController _afterController;

  @override
  void initState() {
    super.initState();
    _beforeController = LinkedScrollController();
    _afterController = LinkedScrollController(before: _beforeController);
    _beforeController.after = _afterController;
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _beforeController.setParent(PrimaryScrollController.of(context));
    _afterController.setParent(PrimaryScrollController.of(context));
  }

  @override
  void dispose() {
    _beforeController.dispose();
    _afterController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Column(
        children: <Widget>[
          Expanded(
            child: ListView(
              controller: _beforeController,
              children: <Widget>[
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello A')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello B')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello C')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello D')),
                ),
              ],
            ),
          ),
          const Divider(),
          Expanded(
            child: ListView(
              controller: _afterController,
              children: <Widget>[
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 1')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 2')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 3')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 4')),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  testWidgets('LinkedScrollController - 1', (WidgetTester tester) async {
    await tester.pumpWidget(const Test());
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.fling(find.text('Hello A'), const Offset(0.0, -50.0), 10000.0);
    await tester.pumpAndSettle();
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello D'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello D'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 4'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello D'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello A'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello A'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 4'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 1'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 1'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsOneWidget);
  });
  testWidgets('LinkedScrollController - 2', (WidgetTester tester) async {
    await tester.pumpWidget(const Test());
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    final TestGesture gestureTop = await tester.startGesture(const Offset(200.0, 150.0));
    final TestGesture gestureBottom = await tester.startGesture(const Offset(600.0, 450.0));
    await tester.pump(const Duration(seconds: 1));
    await gestureTop.moveBy(const Offset(0.0, -270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, -270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsOneWidget);
    expect(find.text('Hello 4'), findsNothing);
    await gestureTop.moveBy(const Offset(0.0, -270.0));
    await gestureBottom.moveBy(const Offset(0.0, -270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsNothing);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello 2'), findsNothing);
    expect(find.text('Hello 3'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await gestureTop.moveBy(const Offset(0.0, 270.0));
    await gestureBottom.moveBy(const Offset(0.0, 270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsOneWidget);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureTop.moveBy(const Offset(0.0, -270.0));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 60));
  });
}
