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

class TestLeftIntent extends Intent {
  const TestLeftIntent();
}
class TestRightIntent extends Intent {
  const TestRightIntent();
}

void main() {
  testWidgets('DoNothingAndStopPropagationTextIntent', (WidgetTester tester) async {
    bool leftCalled = false;
    bool rightCalled = false;
    final TextEditingController controller = TextEditingController(
      text: 'blah1 blah2',
    );
    final FocusNode focusNodeTarget = FocusNode();
    final FocusNode focusNodeNonTarget = FocusNode();

    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(),
      home: Scaffold(
        body: Builder(
          builder: (BuildContext context) {
            return Shortcuts(
              shortcuts: const <ShortcutActivator, Intent>{
                SingleActivator(LogicalKeyboardKey.arrowLeft): TestLeftIntent(),
                SingleActivator(LogicalKeyboardKey.arrowRight): TestRightIntent(),
              },
              child: Shortcuts(
                shortcuts: const <ShortcutActivator, Intent>{
                  SingleActivator(LogicalKeyboardKey.arrowRight): DoNothingAndStopPropagationTextIntent(),
                },
                child: Actions(
                  // These Actions intercept default Intents, set a flag that they
                  // were called, and then call through to the default Action.
                  actions: <Type, Action<Intent>>{
                    TestLeftIntent: CallbackAction<TestLeftIntent>(onInvoke: (Intent intent) {
                      leftCalled = true;
                    }),
                    TestRightIntent: CallbackAction<TestRightIntent>(onInvoke: (Intent intent) {
                      rightCalled = true;
                    }),
                  },
                  child: Center(
                    child: Column(
                      children: <Widget>[
                        EditableText(
                          controller: controller,
                          focusNode: focusNodeTarget,
                          style: Typography.material2018(platform: TargetPlatform.android).black.subtitle1!,
                          cursorColor: Colors.blue,
                          backgroundCursorColor: Colors.grey,
                        ),
                        Focus(
                          focusNode: focusNodeNonTarget,
                          child: const Text('focusable'),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      ),
    ));

    // Focus on the EditableText, which is a TextEditingActionTarget.
    focusNodeTarget.requestFocus();
    await tester.pump();
    expect(focusNodeTarget.hasFocus, isTrue);
    expect(focusNodeNonTarget.hasFocus, isFalse);
    expect(controller.selection.isCollapsed, isTrue);
    expect(controller.selection.baseOffset, 11);

    // The left arrow key's Action is called.
    await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
    await tester.pump();
    expect(leftCalled, isTrue);
    expect(rightCalled, isFalse);
    leftCalled = false;

    // The right arrow key is blocked by DoNothingAndStopPropagationTextIntent.
    await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
    await tester.pump();
    expect(rightCalled, isFalse);
    expect(leftCalled, isFalse);

    // Focus on the other node, which is not a TextEditingActionTarget.
    focusNodeNonTarget.requestFocus();
    await tester.pump();
    expect(focusNodeTarget.hasFocus, isFalse);
    expect(focusNodeNonTarget.hasFocus, isTrue);

    // The left arrow key's Action is called as normal.
    await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
    await tester.pump();
    expect(leftCalled, isTrue);
    expect(rightCalled, isFalse);
    leftCalled = false;

    // The right arrow key's Action is also called. That's because
    // DoNothingAndStopPropagationTextIntent only applies if a
    // TextEditingActionTarget is currently focused.
    await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
    await tester.pump();
    expect(leftCalled, isFalse);
    expect(rightCalled, isTrue);
  });
}
