// 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 'dart:typed_data';

import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';

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

/// Integration tests testing both [CupertinoPageScaffold] and [CupertinoTabScaffold].
void main() {
  testWidgets('Contents are behind translucent bar', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: CupertinoPageScaffold(
          // Default nav bar is translucent.
          navigationBar: CupertinoNavigationBar(
            middle: Text('Title'),
          ),
          child: Center(),
        ),
      ),
    );

    expect(tester.getTopLeft(find.byType(Center)), Offset.zero);
  });

  testWidgets('Opaque bar pushes contents down', (WidgetTester tester) async {
    late BuildContext childContext;
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(viewInsets: EdgeInsets.only(top: 20)),
        child: CupertinoPageScaffold(
          navigationBar: const CupertinoNavigationBar(
            middle: Text('Opaque'),
            backgroundColor: Color(0xFFF8F8F8),
          ),
          child: Builder(
            builder: (BuildContext context) {
              childContext = context;
              return Container();
            },
          ),
        ),
      ),
    ));

    expect(MediaQuery.of(childContext).padding.top, 0);
    // The top of the [Container] is 44 px from the top of the screen because
    // it's pushed down by the opaque navigation bar whose height is 44 px,
    // and the 20 px [MediaQuery] top padding is fully absorbed by the navigation bar.
    expect(tester.getRect(find.byType(Container)), const Rect.fromLTRB(0, 44, 800, 600));
  });

  testWidgets('dark mode and obstruction work', (WidgetTester tester) async {
    const Color dynamicColor = CupertinoDynamicColor.withBrightness(
      color: Color(0xFFF8F8F8),
      darkColor: Color(0xEE333333),
    );

    const CupertinoDynamicColor backgroundColor = CupertinoDynamicColor.withBrightness(
      color: Color(0xFFFFFFFF),
      darkColor: Color(0xFF000000),
    );

    late BuildContext childContext;
    Widget scaffoldWithBrightness(Brightness brightness) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(
            platformBrightness: brightness,
            viewInsets: const EdgeInsets.only(top: 20),
          ),
          child: CupertinoPageScaffold(
            backgroundColor: backgroundColor,
            navigationBar: const CupertinoNavigationBar(
              middle: Text('Title'),
              backgroundColor: dynamicColor,
            ),
            child: Builder(
              builder: (BuildContext context) {
                childContext = context;
                return Container();
              },
            ),
          ),
        ),
      );
    }
    await tester.pumpWidget(scaffoldWithBrightness(Brightness.light));

    expect(MediaQuery.of(childContext).padding.top, 0);
    expect(find.byType(CupertinoPageScaffold), paints..rect(color: backgroundColor.color));

    await tester.pumpWidget(scaffoldWithBrightness(Brightness.dark));

    expect(MediaQuery.of(childContext).padding.top, greaterThan(0));
    expect(find.byType(CupertinoPageScaffold), paints..rect(color: backgroundColor.darkColor));
  });

  testWidgets('Contents padding from viewInsets', (WidgetTester tester) async {
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(viewInsets: EdgeInsets.only(bottom: 100.0)),
        child: CupertinoPageScaffold(
          navigationBar: const CupertinoNavigationBar(
            middle: Text('Opaque'),
            backgroundColor: Color(0xFFF8F8F8),
          ),
          child: Container(),
        ),
      ),
    ));

    expect(tester.getSize(find.byType(Container)).height, 600.0 - 44.0 - 100.0);

    late BuildContext childContext;
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(viewInsets: EdgeInsets.only(bottom: 100.0)),
        child: CupertinoPageScaffold(
          navigationBar: const CupertinoNavigationBar(
            middle: Text('Transparent'),
          ),
          child: Builder(
            builder: (BuildContext context) {
              childContext = context;
              return Container();
            },
          ),
        ),
      ),
    ));

    expect(tester.getSize(find.byType(Container)).height, 600.0 - 100.0);
    // The shouldn't see a media query view inset because it was consumed by
    // the scaffold.
    expect(MediaQuery.of(childContext).viewInsets.bottom, 0);

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(viewInsets: EdgeInsets.only(bottom: 100.0)),
        child: CupertinoPageScaffold(
          navigationBar: const CupertinoNavigationBar(
            middle: Text('Title'),
          ),
          resizeToAvoidBottomInset: false,
          child: Container(),
        ),
      ),
    ));

    expect(tester.getSize(find.byType(Container)).height, 600.0);
  });

  testWidgets('Contents bottom padding are not consumed by viewInsets when resizeToAvoidBottomInset overridden', (WidgetTester tester) async {
    const Widget child = CupertinoPageScaffold(
      resizeToAvoidBottomInset: false,
      navigationBar: CupertinoNavigationBar(
        middle: Text('Opaque'),
        backgroundColor: Color(0xFFF8F8F8),
      ),
      child: Placeholder(),
    );

    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data:  MediaQueryData(viewInsets: EdgeInsets.only(bottom: 20.0)),
          child: child,
        ),
      ),
    );

    final Offset initialPoint = tester.getCenter(find.byType(Placeholder));
    // Consume bottom padding - as if by the keyboard opening
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(
            viewPadding: EdgeInsets.only(bottom: 20),
            viewInsets: EdgeInsets.only(bottom: 300),
          ),
          child: child,
        ),
      ),
    );
    final Offset finalPoint = tester.getCenter(find.byType(Placeholder));
    expect(initialPoint, finalPoint);
  });

  testWidgets('Contents are between opaque bars', (WidgetTester tester) async {
    const Center page1Center = Center();

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            backgroundColor: CupertinoColors.white,
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
                label: 'Tab 1',
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
                label: 'Tab 2',
              ),
            ],
          ),
          tabBuilder: (BuildContext context, int index) {
            return index == 0
                ? const CupertinoPageScaffold(
                  navigationBar: CupertinoNavigationBar(
                    backgroundColor: CupertinoColors.white,
                    middle: Text('Title'),
                  ),
                  child: page1Center,
                )
                : Stack();
          },
        ),
      ),
    );

    expect(tester.getSize(find.byWidget(page1Center)).height, 600.0 - 44.0 - 50.0);
  });

  testWidgets('Contents have automatic sliver padding between translucent bars', (WidgetTester tester) async {
    const SizedBox content = SizedBox(height: 600.0, width: 600.0);

    await tester.pumpWidget(
      CupertinoApp(
        home: MediaQuery(
          data: const MediaQueryData(
            padding: EdgeInsets.symmetric(vertical: 20.0),
          ),
          child: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
                  label: 'Tab 1',
                ),
                BottomNavigationBarItem(
                  icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
                  label: 'Tab 2',
                ),
              ],
            ),
            tabBuilder: (BuildContext context, int index) {
              return index == 0
                  ? CupertinoPageScaffold(
                    navigationBar: const CupertinoNavigationBar(
                      middle: Text('Title'),
                    ),
                    child: ListView(
                      children: const <Widget>[
                        content,
                      ],
                    ),
                  )
                  : Stack();
            },
          ),
        ),
      ),
    );

    // List content automatically padded by nav bar and top media query padding.
    expect(tester.getTopLeft(find.byWidget(content)).dy, 20.0 + 44.0);

    // Overscroll to the bottom.
    await tester.drag(find.byWidget(content), const Offset(0.0, -400.0), warnIfMissed: false); // can't be hit (it's empty) but we're aiming for the list really so it doesn't matter
    // Let it bounce back.
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

    // List content automatically padded by tab bar and bottom media query padding.
    expect(tester.getBottomLeft(find.byWidget(content)).dy, 600 - 20.0 - 50.0);
  });

  testWidgets('iOS independent tab navigation', (WidgetTester tester) async {
    // A full on iOS information architecture app with 2 tabs, and 2 pages
    // in each with independent navigation states.
    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
                label: 'Tab 1',
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
                label: 'Tab 2',
              ),
            ],
          ),
          tabBuilder: (BuildContext context, int index) {
            // For 1-indexed readability.
            ++index;
            return CupertinoTabView(
              builder: (BuildContext context) {
                return CupertinoPageScaffold(
                  navigationBar: CupertinoNavigationBar(
                    middle: Text('Page 1 of tab $index'),
                  ),
                  child: Center(
                    child: CupertinoButton(
                      child: const Text('Next'),
                      onPressed: () {
                        Navigator.of(context).push(
                          CupertinoPageRoute<void>(
                            builder: (BuildContext context) {
                              return CupertinoPageScaffold(
                                navigationBar: CupertinoNavigationBar(
                                  middle: Text('Page 2 of tab $index'),
                                ),
                                child: Center(
                                  child: CupertinoButton(
                                    child: const Text('Back'),
                                    onPressed: () {
                                      Navigator.of(context).pop();
                                    },
                                  ),
                                ),
                              );
                            },
                          ),
                        );
                      },
                    ),
                  ),
                );
              },
            );
          },
        ),
      ),
    );

    expect(find.text('Page 1 of tab 1'), findsOneWidget);
    expect(find.text('Page 1 of tab 2'), findsNothing); // Lazy building so not built yet.

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    expect(find.text('Page 1 of tab 1'), findsNothing); // It's offstage now.
    expect(find.text('Page 1 of tab 1', skipOffstage: false), findsOneWidget);
    expect(find.text('Page 1 of tab 2'), findsOneWidget);

    // Navigate in tab 2.
    await tester.tap(find.text('Next'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));

    expect(find.text('Page 2 of tab 2'), isOnstage);
    expect(find.text('Page 1 of tab 1', skipOffstage: false), isOffstage);

    await tester.tap(find.text('Tab 1'));
    await tester.pump();

    // Independent navigation stacks.
    expect(find.text('Page 1 of tab 1'), isOnstage);
    expect(find.text('Page 2 of tab 2', skipOffstage: false), isOffstage);

    // Navigate in tab 1.
    await tester.tap(find.text('Next'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));

    expect(find.text('Page 2 of tab 1'), isOnstage);
    expect(find.text('Page 2 of tab 2', skipOffstage: false), isOffstage);

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    expect(find.text('Page 2 of tab 2'), isOnstage);
    expect(find.text('Page 2 of tab 1', skipOffstage: false), isOffstage);

    // Pop in tab 2
    await tester.tap(find.text('Back'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));

    expect(find.text('Page 1 of tab 2'), isOnstage);
    expect(find.text('Page 2 of tab 1', skipOffstage: false), isOffstage);
  });

  testWidgets('Decorated with white background by default', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: CupertinoPageScaffold(
          child: Center(),
        ),
      ),
    );

    final DecoratedBox decoratedBox = tester.widgetList(find.byType(DecoratedBox)).elementAt(1) as DecoratedBox;
    expect(decoratedBox.decoration.runtimeType, BoxDecoration);

    final BoxDecoration decoration = decoratedBox.decoration as BoxDecoration;
    expect(decoration.color, isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Overrides background color', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: CupertinoPageScaffold(
          backgroundColor: Color(0xFF010203),
          child: Center(),
        ),
      ),
    );

    final DecoratedBox decoratedBox = tester.widgetList(find.byType(DecoratedBox)).elementAt(1) as DecoratedBox;
    expect(decoratedBox.decoration.runtimeType, BoxDecoration);

    final BoxDecoration decoration = decoratedBox.decoration as BoxDecoration;
    expect(decoration.color, const Color(0xFF010203));
  });

  testWidgets('Lists in CupertinoPageScaffold scroll to the top when status bar tapped', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        builder: (BuildContext context, Widget? child) {
          // Acts as a 20px status bar at the root of the app.
          return MediaQuery(
            data: MediaQuery.of(context).copyWith(padding: const EdgeInsets.only(top: 20)),
            child: child!,
          );
        },
        home: CupertinoPageScaffold(
          // Default nav bar is translucent.
          navigationBar: const CupertinoNavigationBar(
            middle: Text('Title'),
          ),
          child: ListView.builder(
            itemExtent: 50,
            itemBuilder: (BuildContext context, int index) => Text(index.toString()),
          ),
        ),
      ),
    );
    // Top media query padding 20 + translucent nav bar 44.
    expect(tester.getTopLeft(find.text('0')).dy, 64);
    expect(tester.getTopLeft(find.text('6')).dy, 364);

    await tester.fling(
      find.text('5'), // Find some random text on the screen.
      const Offset(0, -200),
      20,
    );

    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.text('6')).dy, moreOrLessEquals(166.833, epsilon: 0.1));
    expect(tester.getTopLeft(find.text('12')).dy, moreOrLessEquals(466.8333333333334, epsilon: 0.1));

    // The media query top padding is 20. Tapping at 20 should do nothing.
    await tester.tapAt(const Offset(400, 20));
    await tester.pumpAndSettle();
    expect(tester.getTopLeft(find.text('6')).dy, moreOrLessEquals(166.833, epsilon: 0.1));
    expect(tester.getTopLeft(find.text('12')).dy, moreOrLessEquals(466.8333333333334, epsilon: 0.1));

    // Tap 1 pixel higher.
    await tester.tapAt(const Offset(400, 19));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));
    expect(tester.getTopLeft(find.text('0')).dy, 64);
    expect(tester.getTopLeft(find.text('6')).dy, 364);
    expect(find.text('12'), findsNothing);
  });

  testWidgets('resizeToAvoidBottomInset is supported even when no navigationBar', (WidgetTester tester) async {
    Widget buildFrame(bool showNavigationBar, bool showKeyboard) {
      return CupertinoApp(
        home: MediaQuery(
          data: MediaQueryData(
            viewPadding: const EdgeInsets.only(bottom: 20),
            viewInsets: EdgeInsets.only(bottom: showKeyboard ? 300 : 20),
          ),
          child: CupertinoPageScaffold(
            navigationBar: showNavigationBar ? const CupertinoNavigationBar(
              middle: Text('Title'),
            ) : null,
            child: const Center(
              child: CupertinoTextField(),
            ),
          ),
        ),
      );
    }

    // When there is a nav bar and no keyboard.
    await tester.pumpWidget(buildFrame(true, false));
    final Offset positionNoInsetWithNavBar = tester.getTopLeft(find.byType(CupertinoTextField));

    // When there is a nav bar and keyboard, the CupertinoTextField moves up.
    await tester.pumpWidget(buildFrame(true, true));
    await tester.pumpAndSettle();
    final Offset positionWithInsetWithNavBar = tester.getTopLeft(find.byType(CupertinoTextField));
    expect(positionWithInsetWithNavBar.dy, lessThan(positionNoInsetWithNavBar.dy));

    // When there is no nav bar and no keyboard, the CupertinoTextField is still
    // centered.
    await tester.pumpWidget(buildFrame(false, false));
    final Offset positionNoInsetNoNavBar = tester.getTopLeft(find.byType(CupertinoTextField));
    expect(positionNoInsetNoNavBar, equals(positionNoInsetWithNavBar));

    // When there is a keyboard but no nav bar, the CupertinoTextField also
    // moves up to the same position as when there is a keyboard and nav bar.
    await tester.pumpWidget(buildFrame(false, true));
    await tester.pumpAndSettle();
    final Offset positionWithInsetNoNavBar = tester.getTopLeft(find.byType(CupertinoTextField));
    expect(positionWithInsetNoNavBar.dy, lessThan(positionNoInsetNoNavBar.dy));
    expect(positionWithInsetNoNavBar, equals(positionWithInsetWithNavBar));
  });

  testWidgets('textScaleFactor is set to 1.0', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Builder(builder: (BuildContext context) {
          return MediaQuery(
            data: MediaQuery.of(context).copyWith(textScaleFactor: 99),
            child: const CupertinoPageScaffold(
              navigationBar: CupertinoNavigationBar(
                middle: Text('middle'),
                leading: Text('leading'),
                trailing: Text('trailing'),
              ),
              child: Text('content'),
            ),
          );
        }),
      ),
    );
    final Iterable<RichText> richTextList = tester.widgetList<RichText>(
      find.descendant(of: find.byType(CupertinoNavigationBar), matching: find.byType(RichText)),
    );

    expect(richTextList.length, greaterThan(0));
    expect(richTextList.any((RichText text) => text.textScaleFactor != 1), isFalse);

    expect(tester.widget<RichText>(find.descendant(of: find.text('content'), matching: find.byType(RichText))).textScaleFactor, 99);
  });
}
