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

class TestItem extends StatelessWidget {
  const TestItem({ super.key, required this.item, this.width, this.height });
  final int item;
  final double? width;
  final double? height;
  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      alignment: Alignment.center,
      child: Text('Item $item', textDirection: TextDirection.ltr),
    );
  }
}

Widget buildFrame({ int? count, double? width, double? height, Axis? scrollDirection, Key? prototypeKey }) {
  return Directionality(
    textDirection: TextDirection.ltr,
    child: CustomScrollView(
      scrollDirection: scrollDirection ?? Axis.vertical,
      slivers: <Widget>[
        SliverPrototypeExtentList(
          prototypeItem: TestItem(item: -1, width: width, height: height, key: prototypeKey),
          delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) => TestItem(item: index),
            childCount: count,
          ),
        ),
      ],
    ),
  );
}

void main() {
  testWidgets('SliverPrototypeExtentList vertical scrolling basics', (WidgetTester tester) async {
    await tester.pumpWidget(buildFrame(count: 20, height: 100.0));

    // The viewport is 600 pixels high, lazily created items are 100 pixels high.
    for (int i = 0; i < 6; i += 1) {
      final Finder item = find.widgetWithText(Container, 'Item $i');
      expect(item, findsOneWidget);
      expect(tester.getTopLeft(item).dy, i * 100.0);
      expect(tester.getSize(item).height, 100.0);
    }
    for (int i = 7; i < 20; i += 1) {
      expect(find.text('Item $i'), findsNothing);
    }

    // Fling scroll to the end.
    await tester.fling(find.text('Item 2'), const Offset(0.0, -200.0), 5000.0);
    await tester.pumpAndSettle();

    for (int i = 19; i >= 14; i -= 1) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    for (int i = 13; i >= 0; i -= 1) {
      expect(find.text('Item $i'), findsNothing);
    }
  });

  testWidgets('SliverPrototypeExtentList horizontal scrolling basics', (WidgetTester tester) async {
    await tester.pumpWidget(buildFrame(count: 20, width: 100.0, scrollDirection: Axis.horizontal));

    // The viewport is 800 pixels wide, lazily created items are 100 pixels wide.
    for (int i = 0; i < 8; i += 1) {
      final Finder item = find.widgetWithText(Container, 'Item $i');
      expect(item, findsOneWidget);
      expect(tester.getTopLeft(item).dx, i * 100.0);
      expect(tester.getSize(item).width, 100.0);
    }
    for (int i = 9; i < 20; i += 1) {
      expect(find.text('Item $i'), findsNothing);
    }

    // Fling scroll to the end.
    await tester.fling(find.text('Item 3'), const Offset(-200.0, 0.0), 5000.0);
    await tester.pumpAndSettle();

    for (int i = 19; i >= 12; i -= 1) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    for (int i = 11; i >= 0; i -= 1) {
      expect(find.text('Item $i'), findsNothing);
    }
  });

  testWidgets('SliverPrototypeExtentList change the prototype item', (WidgetTester tester) async {
    await tester.pumpWidget(buildFrame(count: 10, height: 60.0));

    // The viewport is 600 pixels high, each of the 10 items is 60 pixels high
    for (int i = 0; i < 10; i += 1) {
      expect(find.text('Item $i'), findsOneWidget);
    }

    await tester.pumpWidget(buildFrame(count: 10, height: 120.0));

    // Now the items are 120 pixels high, so only 5 fit.
    for (int i = 0; i < 5; i += 1) {
      expect(find.text('Item $i'), findsOneWidget);
    }
    for (int i = 5; i < 10; i += 1) {
      expect(find.text('Item $i'), findsNothing);
    }

    await tester.pumpWidget(buildFrame(count: 10, height: 60.0));

    // Now they all fit again
    for (int i = 0; i < 10; i += 1) {
      expect(find.text('Item $i'), findsOneWidget);
    }
  });

  testWidgets('SliverPrototypeExtentList first item is also the prototype', (WidgetTester tester) async {
    final List<Widget> items = List<Widget>.generate(10, (int index) {
      return TestItem(key: ValueKey<int>(index), item: index, height: index == 0 ? 60.0 : null);
    }).toList();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: CustomScrollView(
          slivers: <Widget>[
            SliverPrototypeExtentList(
              prototypeItem: items[0],
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) => items[index],
                childCount: 10,
              ),
            ),
          ],
        ),
      ),
    );

    // Item 0 exists in the list and as the prototype item.
    expect(tester.widgetList(find.text('Item 0', skipOffstage: false)).length, 2);

    for (int i = 1; i < 10; i += 1) {
      expect(find.text('Item $i'), findsOneWidget);
    }
  });

  testWidgets('SliverPrototypeExtentList prototypeItem paint transform is zero.', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/67117
    // This test ensures that the SliverPrototypeExtentList does not cause an
    // assertion error when calculating the paint transform of its prototypeItem.
    // The paint transform of the prototypeItem should be zero, since it is not visible.
    final GlobalKey prototypeKey = GlobalKey();
    await tester.pumpWidget(buildFrame(count: 20, height: 100.0, prototypeKey: prototypeKey));

    final RenderObject scrollView = tester.renderObject(find.byType(CustomScrollView));
    final RenderObject prototype = prototypeKey.currentContext!.findRenderObject()!;

    expect(prototype.getTransformTo(scrollView), Matrix4.zero());
  });
}
