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

import '../image_data.dart';
import '../widgets/semantics_tester.dart';

Future<void> pumpWidgetWithBoilerplate(WidgetTester tester, Widget widget) async {
  await tester.pumpWidget(
    Localizations(
      locale: const Locale('en', 'US'),
      delegates: const <LocalizationsDelegate<dynamic>>[
        DefaultWidgetsLocalizations.delegate,
        DefaultCupertinoLocalizations.delegate,
      ],
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: widget,
      ),
    ),
  );
}

Future<void> main() async {

  testWidgets('Need at least 2 tabs', (WidgetTester tester) async {
    await expectLater(
      () => pumpWidgetWithBoilerplate(tester, CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
        ],
      )),
      throwsA(isAssertionError.having(
        (AssertionError error) => error.toString(),
        '.toString()',
        contains('items.length'),
      )),
    );
  });

  testWidgets('Active and inactive colors', (WidgetTester tester) async {
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: '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('BottomNavigationBar.label will create a text widget', (WidgetTester tester) async {
    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 2',
          ),
        ],
        currentIndex: 1,
      ),
    ));

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

  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: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: '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: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
              label: 'Tab 1',
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
              label: '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: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
              label: 'Tab 1',
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
              label: '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: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
              label: 'Tab 1',
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
              label: '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 {
    final MemoryImage activeIcon = MemoryImage(Uint8List.fromList(kBlueSquarePng));
    final MemoryImage inactiveIcon = MemoryImage(Uint8List.fromList(kTransparentImage));

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(inactiveIcon),
            activeIcon: ImageIcon(activeIcon),
            label: '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: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
          label: 'Aka',
        ),
        BottomNavigationBarItem(
          icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
          label: '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: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 2',
          ),
        ],
      ),
    ));

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

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 2',
          ),
        ],
        backgroundColor: const Color(0xFFFFFFFF), // Opaque white.
      ),
    ));

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

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

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 2',
          ),
        ],
        currentIndex: 1,
        onTap: (int tab) { callbackTab = tab; },
      ),
    ));

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

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

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

    await pumpWidgetWithBoilerplate(tester, MediaQuery(
      data: const MediaQueryData(),
      child: CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: 'Tab 1',
          ),
          BottomNavigationBarItem(
            icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
            label: '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('Label of items should be nullable', (WidgetTester tester) async {
    final MemoryImage iconProvider = MemoryImage(Uint8List.fromList(kTransparentImage));
    final List<int> itemsTapped = <int>[];

    await pumpWidgetWithBoilerplate(
      tester,
      MediaQuery(
        data: const MediaQueryData(),
        child: CupertinoTabBar(
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(
                MemoryImage(Uint8List.fromList(kTransparentImage)),
              ),
              label: '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: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(
                MemoryImage(Uint8List.fromList(kTransparentImage)),
              ),
              label: 'Tab 1',
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(
                MemoryImage(Uint8List.fromList(kTransparentImage)),
              ),
              label: '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: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: ImageIcon(
                MemoryImage(Uint8List.fromList(kTransparentImage)),
              ),
              label: 'Tab 1',
            ),
            BottomNavigationBarItem(
              icon: ImageIcon(
                MemoryImage(Uint8List.fromList(kTransparentImage)),
              ),
              label: '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);
  });
}
