// 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_test/flutter_test.dart';

void main() {
  testWidgets('Navigation drawer updates destinations when tapped',
      (WidgetTester tester) async {
    int mutatedIndex = -1;
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
    widgetSetup(tester, 3000, windowHeight: 3000);
    final Widget widget = _buildWidget(
      scaffoldKey,
      NavigationDrawer(
        children: <Widget>[
          Text('Headline', style: theme.textTheme.bodyLarge),
          NavigationDrawerDestination(
            icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
            label: Text('AC', style: theme.textTheme.bodySmall),
          ),
          NavigationDrawerDestination(
            icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
            label: Text('Alarm', style: theme.textTheme.bodySmall),
          ),
        ],
        onDestinationSelected: (int i) {
          mutatedIndex = i;
        },
      ),
    );

    await tester.pumpWidget(widget);
    scaffoldKey.currentState!.openDrawer();
    await tester.pump();

    expect(find.text('Headline'), findsOneWidget);
    expect(find.text('AC'), findsOneWidget);
    expect(find.text('Alarm'), findsOneWidget);

    await tester.pump(const Duration(seconds: 1)); // animation done

    await tester.tap(find.text('Alarm'));
    expect(mutatedIndex, 1);

    await tester.tap(find.text('AC'));
    expect(mutatedIndex, 0);
  });

  testWidgets('NavigationDrawer can update background color',
      (WidgetTester tester) async {
    const Color color = Colors.yellow;
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());

    await tester.pumpWidget(
      _buildWidget(
        scaffoldKey,
        NavigationDrawer(
          backgroundColor: color,
          children: <Widget>[
            Text('Headline', style: theme.textTheme.bodyLarge),
            NavigationDrawerDestination(
              icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
              label: Text('AC', style: theme.textTheme.bodySmall),
            ),
            NavigationDrawerDestination(
              icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
              label: Text('Alarm', style: theme.textTheme.bodySmall),
            ),
          ],
          onDestinationSelected: (int i) {},
        ),
      ),
    );

    scaffoldKey.currentState!.openDrawer();
    await tester.pump(const Duration(seconds: 1)); // animation done

    expect(_getMaterial(tester).color, equals(color));
  });

  testWidgets('NavigationDrawer can update elevation',
      (WidgetTester tester) async {
    const double elevation = 42.0;
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
    final NavigationDrawer drawer = NavigationDrawer(
      elevation: elevation,
      children: <Widget>[
        Text('Headline', style: theme.textTheme.bodyLarge),
        NavigationDrawerDestination(
          icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
          label: Text('AC', style: theme.textTheme.bodySmall),
        ),
        NavigationDrawerDestination(
          icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
          label: Text('Alarm', style: theme.textTheme.bodySmall),
        ),
      ],
    );

    await tester.pumpWidget(
      _buildWidget(
        scaffoldKey,
        drawer,
      ),
    );
    scaffoldKey.currentState!.openDrawer();
    await tester.pump(const Duration(seconds: 1));

    expect(_getMaterial(tester).elevation, equals(elevation));
  });

  testWidgets(
      'NavigationDrawer uses proper defaults when no parameters are given',
      (WidgetTester tester) async {
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
    // M3 settings from the token database.
    await tester.pumpWidget(
      _buildWidget(
        scaffoldKey,
        Theme(
          data: ThemeData.light().copyWith(useMaterial3: true),
          child: NavigationDrawer(
            children: <Widget>[
              Text('Headline', style: theme.textTheme.bodyLarge),
              NavigationDrawerDestination(
                icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
                label: Text('AC', style: theme.textTheme.bodySmall),
              ),
              NavigationDrawerDestination(
                icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
                label: Text('Alarm', style: theme.textTheme.bodySmall),
              ),
            ],
            onDestinationSelected: (int i) {},
          ),
        ),
      ),
    );
    scaffoldKey.currentState!.openDrawer();
    await tester.pump(const Duration(seconds: 1));

    expect(_getMaterial(tester).color, ThemeData().colorScheme.surface);
    expect(_getMaterial(tester).surfaceTintColor, ThemeData().colorScheme.surfaceTint);
    expect(_getMaterial(tester).elevation, 1);
    expect(_getIndicatorDecoration(tester)?.color, const Color(0xff2196f3));
    expect(_getIndicatorDecoration(tester)?.shape, const StadiumBorder());
  });

  testWidgets('Navigation drawer is scrollable', (WidgetTester tester) async {
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    widgetSetup(tester, 500, windowHeight: 300);
    await tester.pumpWidget(
      _buildWidget(
        scaffoldKey,
        NavigationDrawer(
          children: <Widget>[
            for(int i = 0; i < 100; i++)
              NavigationDrawerDestination(
                icon: const Icon(Icons.ac_unit),
                label: Text('Label$i'),
              ),
          ],
          onDestinationSelected: (int i) {},
        ),
      ),
    );
    scaffoldKey.currentState!.openDrawer();
    await tester.pump(const Duration(seconds: 1));

    expect(find.text('Label0'), findsOneWidget);
    expect(find.text('Label1'), findsOneWidget);
    expect(find.text('Label2'), findsOneWidget);
    expect(find.text('Label3'), findsOneWidget);
    expect(find.text('Label4'), findsOneWidget);
    expect(find.text('Label5'), findsOneWidget);
    expect(find.text('Label6'), findsNothing);
    expect(find.text('Label7'), findsNothing);
    expect(find.text('Label8'), findsNothing);

    await tester.dragFrom(const Offset(0, 200), const Offset(0.0, -200));
    await tester.pump();

    expect(find.text('Label0'), findsNothing);
    expect(find.text('Label1'), findsNothing);
    expect(find.text('Label2'), findsNothing);
    expect(find.text('Label3'), findsOneWidget);
    expect(find.text('Label4'), findsOneWidget);
    expect(find.text('Label5'), findsOneWidget);
    expect(find.text('Label6'), findsOneWidget);
    expect(find.text('Label7'), findsOneWidget);
    expect(find.text('Label8'), findsOneWidget);
    expect(find.text('Label9'), findsNothing);
    expect(find.text('Label10'), findsNothing);
   });

  testWidgets('Safe Area test', (WidgetTester tester) async {
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    const double windowHeight = 300;
    widgetSetup(tester, 500, windowHeight: windowHeight);
    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(padding: EdgeInsets.all(20.0)),
        child: MaterialApp(
          useInheritedMediaQuery: true,
          theme: ThemeData.light(),
          home: Scaffold(
            key: scaffoldKey,
            drawer: NavigationDrawer(
                  children: <Widget>[
                    for(int i = 0; i < 10; i++)
                      NavigationDrawerDestination(
                        icon: const Icon(Icons.ac_unit),
                        label: Text('Label$i'),
                      ),
                  ],
                  onDestinationSelected: (int i) {},
                ),
            body: Container(),
          ),
        ),
      ),
    );
    scaffoldKey.currentState!.openDrawer();
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

    // Safe area padding on the top and sides.
    expect(
      tester.getTopLeft(find.widgetWithText(NavigationDrawerDestination,'Label0')),
      const Offset(20.0, 20.0),
    );

    // No Safe area padding at the bottom.
    expect(tester.getBottomRight(find.widgetWithText(NavigationDrawerDestination,'Label4')).dy, windowHeight);
   });

  testWidgets('Navigation drawer semantics', (WidgetTester tester) async {
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
    Widget widget({int selectedIndex = 0}) {
      return _buildWidget(
        scaffoldKey,
        NavigationDrawer(
          selectedIndex: selectedIndex,
          children: <Widget>[
            Text('Headline', style: theme.textTheme.bodyLarge),
            NavigationDrawerDestination(
              icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
              label: Text('AC', style: theme.textTheme.bodySmall),
            ),
            NavigationDrawerDestination(
              icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
              label: Text('Alarm', style: theme.textTheme.bodySmall),
            ),
          ],
        ),
      );
    }

    await tester.pumpWidget(widget());
    scaffoldKey.currentState!.openDrawer();
    await tester.pump(const Duration(seconds: 1));

    expect(
      tester.getSemantics(find.text('AC')),
      matchesSemantics(
        label: 'AC\nTab 1 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        isSelected: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Alarm')),
      matchesSemantics(
        label: 'Alarm\nTab 2 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );

    await tester.pumpWidget(widget(selectedIndex: 1));

    expect(
      tester.getSemantics(find.text('AC')),
      matchesSemantics(
        label: 'AC\nTab 1 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Alarm')),
      matchesSemantics(
        label: 'Alarm\nTab 2 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        isSelected: true,
        hasTapAction: true,
      ),
    );
  });

  testWidgets('Navigation destination updates indicator color and shape', (WidgetTester tester) async {
    final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    final ThemeData theme = ThemeData(useMaterial3: true);
    const Color color = Color(0xff0000ff);
    const ShapeBorder shape = RoundedRectangleBorder();

    Widget buildNavigationDrawer({Color? indicatorColor, ShapeBorder? indicatorShape}) {
      return MaterialApp(
        theme: theme,
        home: Scaffold(
          key: scaffoldKey,
          drawer: NavigationDrawer(
            indicatorColor: indicatorColor,
            indicatorShape: indicatorShape,
            children: <Widget>[
              Text('Headline', style: theme.textTheme.bodyLarge),
              const NavigationDrawerDestination(
                icon: Icon(Icons.ac_unit),
                label: Text('AC'),
              ),
              const NavigationDrawerDestination(
                icon: Icon(Icons.access_alarm),
                label: Text('Alarm'),
              ),
            ],
            onDestinationSelected: (int i) { },
          ),
          body: Container(),
        ),
      );
    }

    await tester.pumpWidget(buildNavigationDrawer());
    scaffoldKey.currentState!.openDrawer();
    await tester.pumpAndSettle();

    // Test default indicator color and shape.
    expect(_getIndicatorDecoration(tester)?.color, theme.colorScheme.secondaryContainer);
    expect(_getIndicatorDecoration(tester)?.shape, const StadiumBorder());

    await tester.pumpWidget(buildNavigationDrawer(indicatorColor: color, indicatorShape: shape));

    // Test custom indicator color and shape.
    expect(_getIndicatorDecoration(tester)?.color, color);
    expect(_getIndicatorDecoration(tester)?.shape, shape);
  });
}

Widget _buildWidget(GlobalKey<ScaffoldState> scaffoldKey, Widget child) {
  return MaterialApp(
    theme: ThemeData.light(),
    home: Scaffold(
      key: scaffoldKey,
      drawer: child,
      body: Container(),
    ),
  );
}

Material _getMaterial(WidgetTester tester) {
  return tester.firstWidget<Material>(
    find.descendant(
        of: find.byType(NavigationDrawer), matching: find.byType(Material)),
  );
}

ShapeDecoration? _getIndicatorDecoration(WidgetTester tester) {
  return tester
      .firstWidget<Container>(
        find.descendant(
          of: find.byType(FadeTransition),
          matching: find.byType(Container),
        ),
      )
      .decoration as ShapeDecoration?;
}

void widgetSetup(WidgetTester tester, double windowWidth,
    {double? windowHeight}) {
  final double height = windowHeight ?? 1000;
  tester.binding.window.devicePixelRatioTestValue = 2;
  final double dpi = tester.binding.window.devicePixelRatio;
  tester.binding.window.physicalSizeTestValue =
      Size(windowWidth * dpi, height * dpi);
}
