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

import '../painting/mocks_for_image_cache.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)), const Offset(0.0, 0.0));
  });

  testWidgets('Opaque bar pushes contents down', (WidgetTester tester) async {
    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),
    );

    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);

    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 overriden', (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(
            padding: EdgeInsets.zero,
            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: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(TestImageProvider(24, 24)),
                title: Text('Tab 1'),
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(TestImageProvider(24, 24)),
                title: Text('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 {
    final Container content = Container(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: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: ImageIcon(TestImageProvider(24, 24)),
                  title: Text('Tab 1'),
                ),
                BottomNavigationBarItem(
                  icon: ImageIcon(TestImageProvider(24, 24)),
                  title: Text('Tab 2'),
                ),
              ],
            ),
            tabBuilder: (BuildContext context, int index) {
              return index == 0
                  ? CupertinoPageScaffold(
                    navigationBar: const CupertinoNavigationBar(
                      middle: Text('Title'),
                    ),
                    child: ListView(
                      children: <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));
    // 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: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(TestImageProvider(24, 24)),
                title: Text('Tab 1'),
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(TestImageProvider(24, 24)),
                title: Text('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(
          child: Center(),
          backgroundColor: Color(0xFF010203),
        ),
      ),
    );

    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(
            padding: EdgeInsets.zero,
            viewPadding: const EdgeInsets.only(bottom: 20),
            viewInsets: EdgeInsets.only(bottom: showKeyboard ? 300 : 20),
          ),
          child: CupertinoPageScaffold(
            resizeToAvoidBottomInset: true,
            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);
  });
}
