// 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/scheduler.dart';
import 'package:flutter_gallery/gallery/app.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
  if (binding is LiveTestWidgetsFlutterBinding) {
    binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
  }

  testWidgets('Flutter Gallery drawer item test', (WidgetTester tester) async {
    bool hasFeedback = false;

    await tester.pumpWidget(
      GalleryApp(
        testMode: true,
        onSendFeedback: () {
          hasFeedback = true;
        },
      ),
    );
    await tester.pump(); // see https://github.com/flutter/flutter/issues/1865
    await tester.pump(); // triggers a frame

    // Show the options page
    await tester.tap(find.byTooltip('Toggle options page'));
    await tester.pumpAndSettle();

    // Verify theme settings
    MaterialApp app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.theme!.brightness, equals(Brightness.light));
    expect(app.darkTheme!.brightness, equals(Brightness.dark));

    // Switch to the dark theme: first menu button, choose 'Dark'
    await tester.tap(find.byIcon(Icons.arrow_drop_down).first);
    await tester.pumpAndSettle();
    await tester.tap(find.text('Dark'));
    await tester.pumpAndSettle();
    app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.themeMode, ThemeMode.dark);

    // Switch to the light theme: first menu button, choose 'Light'
    await tester.tap(find.byIcon(Icons.arrow_drop_down).first);
    await tester.pumpAndSettle();
    await tester.tap(find.text('Light'));
    await tester.pumpAndSettle();
    app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.themeMode, ThemeMode.light);

    // Switch back to system theme setting: first menu button, choose 'System Default'
    await tester.tap(find.byIcon(Icons.arrow_drop_down).first);
    await tester.pumpAndSettle();
    await tester.tap(find.descendant(
        of: find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == 'PopupMenuItem<ThemeMode>'),
        matching: find.text('System Default')
    ));
    await tester.pumpAndSettle();
    app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.themeMode, ThemeMode.system);

    // Verify density settings
    expect(app.theme!.visualDensity, equals(VisualDensity.standard));

    // Popup the density menu: third menu button, choose 'Compact'
    await tester.tap(find.byIcon(Icons.arrow_drop_down).at(2));
    await tester.pumpAndSettle();
    await tester.tap(find.text('Compact'));
    await tester.pumpAndSettle();
    app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.theme!.visualDensity, equals(VisualDensity.compact));

    await tester.tap(find.byIcon(Icons.arrow_drop_down).at(2));
    await tester.pumpAndSettle();
    await tester.tap(find.descendant(
        of: find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == 'PopupMenuItem<GalleryVisualDensityValue>'),
        matching: find.text('System Default')
    ));
    await tester.pumpAndSettle();
    app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.theme!.visualDensity, equals(VisualDensity.standard));

    // Verify platform settings
    expect(app.theme!.platform, equals(TargetPlatform.android));

    // Popup the platform menu: fourth menu button, choose 'Cupertino'
    await tester.tap(find.byIcon(Icons.arrow_drop_down).at(3));
    await tester.pumpAndSettle();
    await tester.tap(find.text('Cupertino').at(1));
    await tester.pumpAndSettle();
    app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp;
    expect(app.theme!.platform, equals(TargetPlatform.iOS));

    // Verify the font scale.
    final Size origTextSize = tester.getSize(find.text('Text size'));
    expect(origTextSize, equals(const Size(144.0, 16.0)));

    // Popup the text size menu: second menu button, choose 'Small'
    await tester.tap(find.byIcon(Icons.arrow_drop_down).at(1));
    await tester.pumpAndSettle();
    await tester.tap(find.text('Small'));
    await tester.pumpAndSettle();
    Size textSize = tester.getSize(find.text('Text size'));
    expect(textSize, equals(const Size(116.0, 13.0)));

    // Set font scale back to the default.
    await tester.tap(find.byIcon(Icons.arrow_drop_down).at(1));
    await tester.pumpAndSettle();
    await tester.tap(find.descendant(
        of: find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == 'PopupMenuItem<GalleryTextScaleValue>'),
        matching: find.text('System Default')
    ));
    await tester.pumpAndSettle();
    textSize = tester.getSize(find.text('Text size'));
    expect(textSize, origTextSize);

    // Switch to slow animation: second switch control
    expect(timeDilation, 1.0);
    await tester.tap(find.byType(Switch).at(1));
    await tester.pumpAndSettle();
    expect(timeDilation, greaterThan(1.0));

    // Restore normal animation: second switch control
    await tester.tap(find.byType(Switch).at(1));
    await tester.pumpAndSettle();
    expect(timeDilation, 1.0);

    // Send feedback.
    expect(hasFeedback, false);

    // Scroll to the end
    await tester.drag(find.text('Text size'), const Offset(0.0, -1000.0));
    await tester.pumpAndSettle();
    await tester.tap(find.text('Send feedback'));
    await tester.pumpAndSettle();
    expect(hasFeedback, true);

    // Hide the options page
    await tester.tap(find.byTooltip('Toggle options page'));
    await tester.pumpAndSettle();
  });
}
