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

import 'rendering_tester.dart';

void main() {
  test('RenderSliverFixedExtentList layout test - rounding error', () {
    final List<RenderBox> children = <RenderBox>[
      RenderSizedBox(const Size(400.0, 100.0)),
      RenderSizedBox(const Size(400.0, 100.0)),
      RenderSizedBox(const Size(400.0, 100.0)),
    ];
    final TestRenderSliverBoxChildManager childManager = TestRenderSliverBoxChildManager(
      children: children,
    );
    final RenderViewport root = RenderViewport(
      axisDirection: AxisDirection.down,
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 0,
      children: <RenderSliver>[
        childManager.createRenderSliverFillViewport(),
      ],
    );
    layout(root);
    expect(children[0].attached, true);
    expect(children[1].attached, false);

    root.offset = ViewportOffset.fixed(600);
    pumpFrame();
    expect(children[0].attached, false);
    expect(children[1].attached, true);

    // Simulate double precision error.
    root.offset = ViewportOffset.fixed(1199.999999999998);
    pumpFrame();
    expect(children[1].attached, false);
    expect(children[2].attached, true);
  });

  group('getMaxChildIndexForScrollOffset', () {
    // Regression test for https://github.com/flutter/flutter/issues/68182

    const double genericItemExtent = 600.0;
    const double extraValueToNotHaveRoundingIssues = 0.0000001; // 6 zeros
    const double extraValueToHaveRoundingIssues = 0.00000001; // 7 zeros

    test('should be 0 when item extent is 0', () {
      const double offsetValueWhichDoesntCare = 1234;
      final int actual = testGetMaxChildIndexForScrollOffset(offsetValueWhichDoesntCare, 0);
      expect(actual, 0);
    });

    test('should be 0 when offset is 0', () {
      final int actual = testGetMaxChildIndexForScrollOffset(0, genericItemExtent);
      expect(actual, 0);
    });

    test('should be 0 when offset is equal to item extent', () {
      final int actual = testGetMaxChildIndexForScrollOffset(genericItemExtent, genericItemExtent);
      expect(actual, 0);
    });

    test('should be 1 when offset is greater than item extent', () {
      final int actual = testGetMaxChildIndexForScrollOffset(genericItemExtent + 1, genericItemExtent);
      expect(actual, 1);
    });

    test('should be 1 when offset is slightly greater than item extent', () {
      final int actual = testGetMaxChildIndexForScrollOffset(
        genericItemExtent + extraValueToNotHaveRoundingIssues,
        genericItemExtent,
      );
      expect(actual, 1);
    });

    test('should be 4 when offset is four times and a half greater than item extent', () {
      final int actual = testGetMaxChildIndexForScrollOffset(genericItemExtent * 4.5, genericItemExtent);
      expect(actual, 4);
    });

    test('should be 5 when offset is 6 times greater than item extent', () {
      const double anotherGenericItemExtent = 414.0;
      final int actual = testGetMaxChildIndexForScrollOffset(
        anotherGenericItemExtent * 6,
        anotherGenericItemExtent,
      );
      expect(actual, 5);
    });

    test('should be 5 when offset is 6 times greater than a specific item extent where the division will return more than 13 zero decimals', () {
      const double itemExtentSpecificForAProblematicScreenSize = 411.42857142857144;
      final int actual = testGetMaxChildIndexForScrollOffset(
        itemExtentSpecificForAProblematicScreenSize * 6 + extraValueToHaveRoundingIssues,
        itemExtentSpecificForAProblematicScreenSize,
      );
      expect(actual, 5);
    });

    test('should be 0 when offset is 0.00000001 times greater than item extent where the division will return more than 13 zero decimals', () {
      final int actual = testGetMaxChildIndexForScrollOffset(
        genericItemExtent + extraValueToHaveRoundingIssues,
        genericItemExtent,
      );
      expect(actual, 0);
    });
  });
}

int testGetMaxChildIndexForScrollOffset(double scrollOffset, double itemExtent) {
  final TestRenderSliverFixedExtentBoxAdaptor renderSliver = TestRenderSliverFixedExtentBoxAdaptor();
  return renderSliver.getMaxChildIndexForScrollOffset(scrollOffset, itemExtent);
}

class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager {
  TestRenderSliverBoxChildManager({
    required this.children,
  });

  RenderSliverMultiBoxAdaptor? _renderObject;
  List<RenderBox> children;

  RenderSliverFillViewport createRenderSliverFillViewport() {
    assert(_renderObject == null);
    _renderObject = RenderSliverFillViewport(
      childManager: this,
    );
    return _renderObject! as RenderSliverFillViewport;
  }

  int? _currentlyUpdatingChildIndex;

  @override
  void createChild(int index, { required RenderBox? after }) {
    if (index < 0 || index >= children.length)
      return;
    try {
      _currentlyUpdatingChildIndex = index;
      _renderObject!.insert(children[index], after: after);
    } finally {
      _currentlyUpdatingChildIndex = null;
    }
  }

  @override
  void removeChild(RenderBox child) {
    _renderObject!.remove(child);
  }

  @override
  double estimateMaxScrollOffset(
    SliverConstraints constraints, {
    int? firstIndex,
    int? lastIndex,
    double? leadingScrollOffset,
    double? trailingScrollOffset,
  }) {
    assert(lastIndex! >= firstIndex!);
    return children.length * (trailingScrollOffset! - leadingScrollOffset!) / (lastIndex! - firstIndex! + 1);
  }

  @override
  int get childCount => children.length;

  @override
  void didAdoptChild(RenderBox child) {
    assert(_currentlyUpdatingChildIndex != null);
    final SliverMultiBoxAdaptorParentData childParentData = child.parentData! as SliverMultiBoxAdaptorParentData;
    childParentData.index = _currentlyUpdatingChildIndex;
  }

  @override
  void setDidUnderflow(bool value) { }
}

class TestRenderSliverFixedExtentBoxAdaptor extends RenderSliverFixedExtentBoxAdaptor {
  TestRenderSliverFixedExtentBoxAdaptor()
    :super(childManager: TestRenderSliverBoxChildManager(children: <RenderBox>[]));

  @override
  // ignore: unnecessary_overrides
  int getMaxChildIndexForScrollOffset(double scrollOffset, double itemExtent) {
    return super.getMaxChildIndexForScrollOffset(scrollOffset, itemExtent);
  }

  @override
  double get itemExtent => throw UnimplementedError();
}
