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

import '../painting/mocks_for_image_cache.dart';
import '../widgets/semantics_tester.dart';

Future<void> pumpWidgetWithBoilerplate(WidgetTester tester, Widget widget) async {
  await tester.pumpWidget(
    Directionality(
      textDirection: TextDirection.ltr,
      child: widget,
    ),
  );
}

void main() {
  testWidgets('Need at least 2 tabs', (WidgetTester tester) async {
    try {
      await pumpWidgetWithBoilerplate(tester, CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
        ],
      ));
      fail('Should not be possible to create a tab bar with just one item');
    } on AssertionError catch (e) {
      expect(e.toString(), contains('items.length'));
      // Exception expected.
    }
  });

  testWidgets('Active and inactive colors', (WidgetTester tester) async {
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 2'),
          ),
        ],
        currentIndex: 1,
        activeColor: const Color(0xFF123456),
        inactiveColor: const Color(0xFF654321),
      ),
    ));

    final RichText actualInactive = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    expect(actualInactive.text.style.color, const Color(0xFF654321));

    final RichText actualActive = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));
    expect(actualActive.text.style.color, const Color(0xFF123456));
  });

  testWidgets('Active and inactive colors dark mode', (WidgetTester tester) async {
    const CupertinoDynamicColor dynamicActiveColor = CupertinoDynamicColor.withBrightness(
      color: Color(0xFF000000),
      darkColor: Color(0xFF000001),
    );

    const CupertinoDynamicColor dynamicInactiveColor = CupertinoDynamicColor.withBrightness(
      color: Color(0xFF000002),
      darkColor: Color(0xFF000003),
    );

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 2'),
          ),
        ],
        currentIndex: 1,
        activeColor: dynamicActiveColor,
        inactiveColor: dynamicInactiveColor,
      ),
    ));

    RichText actualInactive = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    expect(actualInactive.text.style.color.value, 0xFF000002);

    RichText actualActive = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));
    expect(actualActive.text.style.color.value, 0xFF000000);

    final RenderDecoratedBox renderDecoratedBox = tester.renderObject(find.descendant(
      of: find.byType(BackdropFilter),
      matching: find.byType(DecoratedBox),
    ));

    // Border color is resolved correctly.
    final BoxDecoration decoration1 = renderDecoratedBox.decoration as BoxDecoration;
    expect(decoration1.border.top.color.value, 0x4C000000);

    // Switch to dark mode.
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
        data: const MediaQueryData(platformBrightness: Brightness.dark),
        child: CupertinoTabBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(TestImageProvider(24, 24)),
              title: Text('Tab 1'),
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(TestImageProvider(24, 24)),
              title: Text('Tab 2'),
            ),
          ],
          currentIndex: 1,
          activeColor: dynamicActiveColor,
          inactiveColor: dynamicInactiveColor,
        ),
    ));

    actualInactive = tester.widget(find.descendant(
        of: find.text('Tab 1'),
        matching: find.byType(RichText),
    ));
    expect(actualInactive.text.style.color.value, 0xFF000003);

    actualActive = tester.widget(find.descendant(
        of: find.text('Tab 2'),
        matching: find.byType(RichText),
    ));
    expect(actualActive.text.style.color.value, 0xFF000001);

    // Border color is resolved correctly.
    final BoxDecoration decoration2 = renderDecoratedBox.decoration as BoxDecoration;
    expect(decoration2.border.top.color.value, 0x29000000);
  });

  testWidgets('Tabs respects themes', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(TestImageProvider(24, 24)),
              title: Text('Tab 1'),
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(TestImageProvider(24, 24)),
              title: Text('Tab 2'),
            ),
          ],
          currentIndex: 1,
        ),
      ),
    );

    RichText actualInactive = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    expect(actualInactive.text.style.color.value, 0xFF999999);

    RichText actualActive = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));
    expect(actualActive.text.style.color, CupertinoColors.activeBlue);

    await tester.pumpWidget(
      CupertinoApp(
        theme: const CupertinoThemeData(brightness: Brightness.dark),
        home: CupertinoTabBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(TestImageProvider(24, 24)),
              title: Text('Tab 1'),
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(TestImageProvider(24, 24)),
              title: Text('Tab 2'),
            ),
          ],
          currentIndex: 1,
        ),
      ),
    );

    actualInactive = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    expect(actualInactive.text.style.color.value, 0xFF757575);

    actualActive = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));

    expect(actualActive.text.style.color, isSameColorAs(CupertinoColors.activeBlue.darkColor));
  });

  testWidgets('Use active icon', (WidgetTester tester) async {
    const TestImageProvider activeIcon = TestImageProvider(16, 16);
    const TestImageProvider inactiveIcon = TestImageProvider(24, 24);

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(inactiveIcon),
            activeIcon: ImageIcon(activeIcon),
            title: Text('Tab 2'),
          ),
        ],
        currentIndex: 1,
        activeColor: const Color(0xFF123456),
        inactiveColor: const Color(0xFF654321),
      ),
    ));

    final Image image = tester.widget(find.descendant(
      of: find.widgetWithText(GestureDetector, 'Tab 2'),
      matching: find.byType(Image),
    ));

    expect(image.color, const Color(0xFF123456));
    expect(image.image, activeIcon);
  });

  testWidgets('Adjusts height to account for bottom padding', (WidgetTester tester) async {
    final CupertinoTabBar tabBar = CupertinoTabBar(
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: ImageIcon(TestImageProvider(24, 24)),
          title: Text('Aka'),
        ),
        BottomNavigationBarItem(
          icon: ImageIcon(TestImageProvider(24, 24)),
          title: Text('Shiro'),
        ),
      ],
    );

    // Verify height with no bottom padding.
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabScaffold(
        tabBar: tabBar,
        tabBuilder: (BuildContext context, int index) {
          return const Placeholder();
        },
      ),
    ));
    expect(tester.getSize(find.byType(CupertinoTabBar)).height, 50.0);

    // Verify height with bottom padding.
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(padding: EdgeInsets.only(bottom: 40.0)),
      child: CupertinoTabScaffold(
        tabBar: tabBar,
        tabBuilder: (BuildContext context, int index) {
          return const Placeholder();
        },
      ),
    ));
    expect(tester.getSize(find.byType(CupertinoTabBar)).height, 90.0);
  });

  testWidgets('Opaque background does not add blur effects', (WidgetTester tester) async {
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 2'),
          ),
        ],
      ),
    ));

    expect(find.byType(BackdropFilter), findsOneWidget);

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 2'),
          ),
        ],
        backgroundColor: const Color(0xFFFFFFFF), // Opaque white.
      ),
    ));

    expect(find.byType(BackdropFilter), findsNothing);
  });

  testWidgets('Tap callback', (WidgetTester tester) async {
    int callbackTab;

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 2'),
          ),
        ],
        currentIndex: 1,
        onTap: (int tab) { callbackTab = tab; },
      ),
    ));

    await tester.tap(find.text('Tab 1'));
    expect(callbackTab, 0);
  });

  testWidgets('tabs announce semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 1'),
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(TestImageProvider(24, 24)),
            title: Text('Tab 2'),
          ),
        ],
      ),
    ));

    expect(semantics, includesNodeWith(
      label: 'Tab 1',
      hint: 'tab, 1 of 2',
      flags: <SemanticsFlag>[SemanticsFlag.isSelected],
      textDirection: TextDirection.ltr,
    ));

    expect(semantics, includesNodeWith(
      label: 'Tab 2',
      hint: 'tab, 2 of 2',
      textDirection: TextDirection.ltr,
    ));

    semantics.dispose();
  });

  testWidgets('Title of items should be nullable', (WidgetTester tester) async {
    const TestImageProvider iconProvider = TestImageProvider(16, 16);
    final List<int> itemsTapped = <int>[];

    await pumpWidgetWithBoilerplate(
        tester,
        MediaQuery(
          data: const MediaQueryData(),
          child: CupertinoTabBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(
                  TestImageProvider(24, 24),
                ),
                title: Text('Tab 1'),
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(
                  iconProvider,
                ),
              ),
            ],
            onTap: (int index) => itemsTapped.add(index),
          ),
        ));

    expect(find.text('Tab 1'), findsOneWidget);

    final Finder finder = find.byWidgetPredicate(
        (Widget widget) => widget is Image && widget.image == iconProvider);

    await tester.tap(finder);
    expect(itemsTapped, <int>[1]);
  });

  testWidgets('Hide border hides the top border of the tabBar', (WidgetTester tester) async {
    await pumpWidgetWithBoilerplate(
        tester,
        MediaQuery(
          data: const MediaQueryData(),
          child: CupertinoTabBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(
                  TestImageProvider(24, 24),
                ),
                title: Text('Tab 1'),
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(
                  TestImageProvider(24, 24),
                ),
                title: Text('Tab 2'),
              ),
            ],
          ),
        ));

    final DecoratedBox decoratedBox = tester.widget(find.byType(DecoratedBox));
    final BoxDecoration boxDecoration = decoratedBox.decoration as BoxDecoration;
    expect(boxDecoration.border, isNotNull);

    await pumpWidgetWithBoilerplate(
        tester,
        MediaQuery(
          data: const MediaQueryData(),
          child: CupertinoTabBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: ImageIcon(
                  TestImageProvider(24, 24),
                ),
                title: Text('Tab 1'),
              ),
              BottomNavigationBarItem(
                icon: ImageIcon(
                  TestImageProvider(24, 24),
                ),
                title: Text('Tab 2'),
              ),
            ],
            backgroundColor: const Color(0xFFFFFFFF), // Opaque white.
            border: null,
          ),
        ));

    final DecoratedBox decoratedBoxHiddenBorder =
        tester.widget(find.byType(DecoratedBox));
    final BoxDecoration boxDecorationHiddenBorder =
        decoratedBoxHiddenBorder.decoration as BoxDecoration;
    expect(boxDecorationHiddenBorder.border, isNull);
  });
}
