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

import '../rendering/mock_canvas.dart';

void main() {
  // Constants taken from _ContextMenuActionState.
  const CupertinoDynamicColor kBackgroundColor = CupertinoDynamicColor.withBrightness(
    color: Color(0xFFEEEEEE),
    darkColor: Color(0xFF212122),
  );
  const CupertinoDynamicColor kBackgroundColorPressed = CupertinoDynamicColor.withBrightness(
    color: Color(0xFFDDDDDD),
    darkColor: Color(0xFF3F3F40),
  );
  const Color kDestructiveActionColor = CupertinoColors.destructiveRed;
  const FontWeight kDefaultActionWeight = FontWeight.w600;

  Widget getApp({
    VoidCallback? onPressed,
    bool isDestructiveAction = false,
    bool isDefaultAction = false,
    Brightness? brightness,
  }) {
    final UniqueKey actionKey = UniqueKey();
    final CupertinoContextMenuAction action = CupertinoContextMenuAction(
      key: actionKey,
      onPressed: onPressed,
      trailingIcon: CupertinoIcons.home,
      isDestructiveAction: isDestructiveAction,
      isDefaultAction: isDefaultAction,
      child: const Text('I am a CupertinoContextMenuAction'),
    );

    return CupertinoApp(
      theme: CupertinoThemeData(
        brightness: brightness ?? Brightness.light,
      ),
      home: CupertinoPageScaffold(
        child: Center(
          child: action,
        ),
      ),
    );
  }

  TextStyle getTextStyle(WidgetTester tester) {
    final Finder finder = find.descendant(
      of: find.byType(CupertinoContextMenuAction),
      matching: find.byType(DefaultTextStyle),
    );
    expect(finder, findsOneWidget);
    final DefaultTextStyle defaultStyle = tester.widget(finder);
    return defaultStyle.style;
  }

  Icon getIcon(WidgetTester tester) {
    final Finder finder = find.descendant(
      of: find.byType(CupertinoContextMenuAction),
      matching: find.byType(Icon),
    );
    expect(finder, findsOneWidget);
    final Icon icon = tester.widget(finder);
    return icon;
  }

  testWidgets('responds to taps', (WidgetTester tester) async {
    bool wasPressed = false;
    await tester.pumpWidget(getApp(onPressed: () {
      wasPressed = true;
    }));

    expect(wasPressed, false);
    await tester.tap(find.byType(CupertinoContextMenuAction));
    expect(wasPressed, true);
  });

  testWidgets('turns grey when pressed and held', (WidgetTester tester) async {
    await tester.pumpWidget(getApp());
    expect(find.byType(CupertinoContextMenuAction), paints..rect(color: kBackgroundColor.color));

    final Offset actionCenterLight = tester.getCenter(find.byType(CupertinoContextMenuAction));
    final TestGesture gestureLight = await tester.startGesture(actionCenterLight);
    await tester.pump();
    expect(find.byType(CupertinoContextMenuAction), paints..rect(color: kBackgroundColorPressed.color));

    await gestureLight.up();
    await tester.pump();
    expect(find.byType(CupertinoContextMenuAction), paints..rect(color: kBackgroundColor.color));

    await tester.pumpWidget(getApp(brightness: Brightness.dark));
    expect(find.byType(CupertinoContextMenuAction), paints..rect(color: kBackgroundColor.darkColor));

    final Offset actionCenterDark = tester.getCenter(find.byType(CupertinoContextMenuAction));
    final TestGesture gestureDark = await tester.startGesture(actionCenterDark);
    await tester.pump();
    expect(find.byType(CupertinoContextMenuAction), paints..rect(color: kBackgroundColorPressed.darkColor));

    await gestureDark.up();
    await tester.pump();
    expect(find.byType(CupertinoContextMenuAction), paints..rect(color: kBackgroundColor.darkColor));
  });

  testWidgets('icon and textStyle colors are correct out of the box', (WidgetTester tester) async {
    await tester.pumpWidget(getApp());
    expect(getTextStyle(tester).color, CupertinoColors.label);
    expect(getIcon(tester).color,  CupertinoColors.label);
  });

  testWidgets('icon and textStyle colors are correct for destructive actions', (WidgetTester tester) async {
    await tester.pumpWidget(getApp(isDestructiveAction: true));
    expect(getTextStyle(tester).color, kDestructiveActionColor);
    expect(getIcon(tester).color, kDestructiveActionColor);
  });

  testWidgets('textStyle is correct for defaultAction', (WidgetTester tester) async {
    await tester.pumpWidget(getApp(isDefaultAction: true));
    expect(getTextStyle(tester).fontWeight, kDefaultActionWeight);
  });

  testWidgets(
    'Hovering over Cupertino context menu action updates cursor to clickable on Web',
    (WidgetTester tester) async {
      /// Cupertino context menu action without "onPressed" callback.
      await tester.pumpWidget(getApp());
      final Offset contextMenuAction = tester.getCenter(find.text('I am a CupertinoContextMenuAction'));
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
      await gesture.addPointer(location: contextMenuAction);
      await tester.pumpAndSettle();
      expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);

      // / Cupertino context menu action with "onPressed" callback.
      await tester.pumpWidget(getApp(onPressed: (){}));
      await gesture.moveTo(const Offset(10, 10));
      await tester.pumpAndSettle();
      expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);

      await gesture.moveTo(contextMenuAction);
      await tester.pumpAndSettle();
      expect(
        RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
        kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
      );
  });
}
