// 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.

// @dart = 2.8

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('copyWith, ==, hashCode basics', () {
    expect(const NavigationRailThemeData(), const NavigationRailThemeData().copyWith());
    expect(const NavigationRailThemeData().hashCode, const NavigationRailThemeData().copyWith().hashCode);
  });

  testWidgets('Default values are used when no NavigationRail or NavigationRailThemeData properties are specified', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: NavigationRail(
            selectedIndex: 0,
            destinations: _destinations(),
          ),
        ),
      ),
    );

    expect(_railMaterial(tester).color, ThemeData().colorScheme.surface);
    expect(_railMaterial(tester).elevation, 0);
    expect(_selectedIconTheme(tester).size, 24.0);
    expect(_selectedIconTheme(tester).color, ThemeData().colorScheme.primary);
    expect(_selectedIconTheme(tester).opacity, 1.0);
    expect(_unselectedIconTheme(tester).size, 24.0);
    expect(_unselectedIconTheme(tester).color, ThemeData().colorScheme.onSurface);
    expect(_unselectedIconTheme(tester).opacity, 0.64);
    expect(_selectedLabelStyle(tester).fontSize, 14.0);
    expect(_unselectedLabelStyle(tester).fontSize, 14.0);
    expect(_destinationsAlign(tester).alignment, Alignment.topCenter);
    expect(_labelType(tester), NavigationRailLabelType.none);
  });

  testWidgets('NavigationRailThemeData values are used when no NavigationRail properties are specified', (WidgetTester tester) async {
    const Color backgroundColor = Color(0x00000001);
    const double elevation = 7.0;
    const double selectedIconSize = 25.0;
    const double unselectedIconSize = 23.0;
    const Color selectedIconColor = Color(0x00000002);
    const Color unselectedIconColor = Color(0x00000003);
    const double selectedIconOpacity = 0.99;
    const double unselectedIconOpacity = 0.98;
    const double selectedLabelFontSize = 13.0;
    const double unselectedLabelFontSize = 11.0;
    const double groupAlignment = 0.0;
    const NavigationRailLabelType labelType = NavigationRailLabelType.all;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: NavigationRailTheme(
            data: const NavigationRailThemeData(
              backgroundColor: backgroundColor,
              elevation: elevation,
              selectedIconTheme: IconThemeData(
                size: selectedIconSize,
                color: selectedIconColor,
                opacity: selectedIconOpacity,
              ),
              unselectedIconTheme: IconThemeData(
                size: unselectedIconSize,
                color: unselectedIconColor,
                opacity: unselectedIconOpacity,
              ),
              selectedLabelTextStyle: TextStyle(fontSize: selectedLabelFontSize),
              unselectedLabelTextStyle: TextStyle(fontSize: unselectedLabelFontSize),
              groupAlignment: groupAlignment,
              labelType: labelType,
            ),
            child: NavigationRail(
              selectedIndex: 0,
              destinations: _destinations(),
            ),
          ),
        ),
      ),
    );

    expect(_railMaterial(tester).color, backgroundColor);
    expect(_railMaterial(tester).elevation, elevation);
    expect(_selectedIconTheme(tester).size, selectedIconSize);
    expect(_selectedIconTheme(tester).color, selectedIconColor);
    expect(_selectedIconTheme(tester).opacity, selectedIconOpacity);
    expect(_unselectedIconTheme(tester).size, unselectedIconSize);
    expect(_unselectedIconTheme(tester).color, unselectedIconColor);
    expect(_unselectedIconTheme(tester).opacity, unselectedIconOpacity);
    expect(_selectedLabelStyle(tester).fontSize, selectedLabelFontSize);
    expect(_unselectedLabelStyle(tester).fontSize, unselectedLabelFontSize);
    expect(_destinationsAlign(tester).alignment, Alignment.center);
    expect(_labelType(tester), labelType);
  });

  testWidgets('NavigationRail values take priority over NavigationRailThemeData values when both properties are specified', (WidgetTester tester) async {
    const Color backgroundColor = Color(0x00000001);
    const double elevation = 7.0;
    const double selectedIconSize = 25.0;
    const double unselectedIconSize = 23.0;
    const Color selectedIconColor = Color(0x00000002);
    const Color unselectedIconColor = Color(0x00000003);
    const double selectedIconOpacity = 0.99;
    const double unselectedIconOpacity = 0.98;
    const double selectedLabelFontSize = 13.0;
    const double unselectedLabelFontSize = 11.0;
    const double groupAlignment = 0.0;
    const NavigationRailLabelType labelType = NavigationRailLabelType.all;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: NavigationRailTheme(
            data: const NavigationRailThemeData(
              backgroundColor: Color(0x00000099),
              elevation: 5,
              selectedIconTheme: IconThemeData(
                size: 31.0,
                color: Color(0x00000098),
                opacity: 0.81,
              ),
              unselectedIconTheme: IconThemeData(
                size: 37.0,
                color: Color(0x00000097),
                opacity: 0.82,
              ),
              selectedLabelTextStyle: TextStyle(fontSize: 9.0),
              unselectedLabelTextStyle: TextStyle(fontSize: 7.0),
              groupAlignment: 1.0,
              labelType: NavigationRailLabelType.selected,
            ),
            child: NavigationRail(
              selectedIndex: 0,
              destinations: _destinations(),
              backgroundColor: backgroundColor,
              elevation: elevation,
              selectedIconTheme: const IconThemeData(
                size: selectedIconSize,
                color: selectedIconColor,
                opacity: selectedIconOpacity,
              ),
              unselectedIconTheme: const IconThemeData(
                size: unselectedIconSize,
                color: unselectedIconColor,
                opacity: unselectedIconOpacity,
              ),
              selectedLabelTextStyle: const TextStyle(fontSize: selectedLabelFontSize),
              unselectedLabelTextStyle: const TextStyle(fontSize: unselectedLabelFontSize),
              groupAlignment: groupAlignment,
              labelType: labelType,
            ),
          ),
        ),
      ),
    );

    expect(_railMaterial(tester).color, backgroundColor);
    expect(_railMaterial(tester).elevation, elevation);
    expect(_selectedIconTheme(tester).size, selectedIconSize);
    expect(_selectedIconTheme(tester).color, selectedIconColor);
    expect(_selectedIconTheme(tester).opacity, selectedIconOpacity);
    expect(_unselectedIconTheme(tester).size, unselectedIconSize);
    expect(_unselectedIconTheme(tester).color, unselectedIconColor);
    expect(_unselectedIconTheme(tester).opacity, unselectedIconOpacity);
    expect(_selectedLabelStyle(tester).fontSize, selectedLabelFontSize);
    expect(_unselectedLabelStyle(tester).fontSize, unselectedLabelFontSize);
    expect(_destinationsAlign(tester).alignment, Alignment.center);
    expect(_labelType(tester), labelType);
  });

  testWidgets('Default debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const NavigationRailThemeData().debugFillProperties(builder);

    final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

    expect(description, <String>[]);
  });

  testWidgets('Custom debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const NavigationRailThemeData(
      backgroundColor: Color(0x00000099),
      elevation: 5,
      selectedIconTheme: IconThemeData(color: Color(0x00000098)),
      unselectedIconTheme: IconThemeData(color: Color(0x00000097)),
      selectedLabelTextStyle: TextStyle(fontSize: 9.0),
      unselectedLabelTextStyle: TextStyle(fontSize: 7.0),
      groupAlignment: 1.0,
      labelType: NavigationRailLabelType.selected,
    ).debugFillProperties(builder);

    final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

    expect(description[0], 'backgroundColor: Color(0x00000099)');
    expect(description[1], 'elevation: 5.0');
    expect(description[2], 'unselectedLabelTextStyle: TextStyle(inherit: true, size: 7.0)');
    expect(description[3], 'selectedLabelTextStyle: TextStyle(inherit: true, size: 9.0)');

    // Ignore instance address for IconThemeData.
    expect(description[4].contains('unselectedIconTheme: IconThemeData'), isTrue);
    expect(description[4].contains('(color: Color(0x00000097))'), isTrue);
    expect(description[5].contains('selectedIconTheme: IconThemeData'), isTrue);
    expect(description[5].contains('(color: Color(0x00000098))'), isTrue);

    expect(description[6], 'groupAlignment: 1.0');
    expect(description[7], 'labelType: NavigationRailLabelType.selected');

  });
}

List<NavigationRailDestination> _destinations() {
  return const <NavigationRailDestination>[
    NavigationRailDestination(
      icon: Icon(Icons.favorite_border),
      selectedIcon: Icon(Icons.favorite),
      label: Text('Abc'),
    ),
    NavigationRailDestination(
      icon: Icon(Icons.star_border),
      selectedIcon: Icon(Icons.star),
      label: Text('Def'),
    ),
  ];
}

Material _railMaterial(WidgetTester tester) {
  // The first material is for the rail, and the rest are for the destinations.
  return tester.firstWidget<Material>(
    find.descendant(
      of: find.byType(NavigationRail),
      matching: find.byType(Material),
    ),
  );
}

IconThemeData _selectedIconTheme(WidgetTester tester) {
  return _iconTheme(tester, Icons.favorite);
}

IconThemeData _unselectedIconTheme(WidgetTester tester) {
  return _iconTheme(tester, Icons.star_border);
}

IconThemeData _iconTheme(WidgetTester tester, IconData icon) {
  // The first IconTheme is the one added by the navigation rail.
  return tester.firstWidget<IconTheme>(
    find.ancestor(
      of: find.byIcon(icon),
      matching: find.byType(IconTheme),
    ),
  ).data;
}

TextStyle _selectedLabelStyle(WidgetTester tester) {
  return tester.widget<RichText>(
    find.descendant(
      of: find.text('Abc'),
      matching: find.byType(RichText),
    ),
  ).text.style;
}

TextStyle _unselectedLabelStyle(WidgetTester tester) {
  return tester.widget<RichText>(
    find.descendant(
      of: find.text('Def'),
      matching: find.byType(RichText),
    ),
  ).text.style;
}

Align _destinationsAlign(WidgetTester tester) {
  // The first Expanded widget is the one within the main Column for the rail
  // content.
  return tester.firstWidget<Align>(
    find.descendant(
      of: find.byType(Expanded),
      matching: find.byType(Align),
    ),
  );
}

NavigationRailLabelType _labelType(WidgetTester tester) {
  if (_opacityAboveLabel('Abc').evaluate().isNotEmpty && _opacityAboveLabel('Def').evaluate().isNotEmpty) {
    return _labelOpacity(tester, 'Abc') == 1 ? NavigationRailLabelType.selected : NavigationRailLabelType.none;
  } else {
    return NavigationRailLabelType.all;
  }
}

Finder _opacityAboveLabel(String text) {
  return find.ancestor(
    of: find.text(text),
    matching: find.byType(Opacity),
  );
}

// Only valid when labelType != all.
double _labelOpacity(WidgetTester tester, String text) {
  final Opacity opacityWidget = tester.widget<Opacity>(
    find.ancestor(
      of: find.text(text),
      matching: find.byType(Opacity),
    ),
  );
  return opacityWidget.opacity;
}
