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

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

void main() {
  testWidgets('Passes textAlign to underlying CupertinoTextField', (WidgetTester tester) async {
    const TextAlign alignment = TextAlign.center;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            textAlign: alignment,
          ),
        ),
      ),
    );

    final Finder textFieldFinder = find.byType(CupertinoTextField);
    expect(textFieldFinder, findsOneWidget);

    final CupertinoTextField textFieldWidget = tester.widget(textFieldFinder);
    expect(textFieldWidget.textAlign, alignment);
  });

  testWidgets('Passes scrollPhysics to underlying TextField', (WidgetTester tester) async {
    const ScrollPhysics scrollPhysics = ScrollPhysics();

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            scrollPhysics: scrollPhysics,
          ),
        ),
      ),
    );

    final Finder textFieldFinder = find.byType(CupertinoTextField);
    expect(textFieldFinder, findsOneWidget);

    final CupertinoTextField textFieldWidget = tester.widget(textFieldFinder);
    expect(textFieldWidget.scrollPhysics, scrollPhysics);
  });

  testWidgets('Passes textAlignVertical to underlying CupertinoTextField', (WidgetTester tester) async {
    const TextAlignVertical textAlignVertical = TextAlignVertical.bottom;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            textAlignVertical: textAlignVertical,
          ),
        ),
      ),
    );

    final Finder textFieldFinder = find.byType(CupertinoTextField);
    expect(textFieldFinder, findsOneWidget);

    final CupertinoTextField textFieldWidget = tester.widget(textFieldFinder);
    expect(textFieldWidget.textAlignVertical, textAlignVertical);
  });

  testWidgets('Passes textInputAction to underlying CupertinoTextField', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            textInputAction: TextInputAction.next,
          ),
        ),
      ),
    );

    final Finder textFieldFinder = find.byType(CupertinoTextField);
    expect(textFieldFinder, findsOneWidget);

    final CupertinoTextField textFieldWidget = tester.widget(textFieldFinder);
    expect(textFieldWidget.textInputAction, TextInputAction.next);
  });

  testWidgets('Passes onEditingComplete to underlying CupertinoTextField', (WidgetTester tester) async {
    void onEditingComplete() {}

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            onEditingComplete: onEditingComplete,
          ),
        ),
      ),
    );

    final Finder textFieldFinder = find.byType(CupertinoTextField);
    expect(textFieldFinder, findsOneWidget);

    final CupertinoTextField textFieldWidget = tester.widget(textFieldFinder);
    expect(textFieldWidget.onEditingComplete, onEditingComplete);
  });

  testWidgets('Passes cursor attributes to underlying CupertinoTextField', (WidgetTester tester) async {
    const double cursorWidth = 3.14;
    const double cursorHeight = 6.28;
    const Radius cursorRadius = Radius.circular(2);
    const Color cursorColor = CupertinoColors.systemPurple;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            cursorWidth: cursorWidth,
            cursorHeight: cursorHeight,
            cursorColor: cursorColor,
          ),
        ),
      ),
    );

    final Finder textFieldFinder = find.byType(CupertinoTextField);
    expect(textFieldFinder, findsOneWidget);

    final CupertinoTextField textFieldWidget = tester.widget(textFieldFinder);
    expect(textFieldWidget.cursorWidth, cursorWidth);
    expect(textFieldWidget.cursorHeight, cursorHeight);
    expect(textFieldWidget.cursorRadius, cursorRadius);
    expect(textFieldWidget.cursorColor, cursorColor);
  });

  testWidgets('onFieldSubmit callbacks are called', (WidgetTester tester) async {
    bool called = false;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            onFieldSubmitted: (String value) {
              called = true;
            },
          ),
        ),
      ),
    );

    await tester.showKeyboard(find.byType(CupertinoTextField));
    await tester.testTextInput.receiveAction(TextInputAction.done);
    await tester.pump();
    expect(called, true);
  });

  testWidgets('onChanged callbacks are called', (WidgetTester tester) async {
    late String value;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            onChanged: (String v) {
              value = v;
            },
          ),
        ),
      ),
    );

    await tester.enterText(find.byType(CupertinoTextField), 'Soup');
    await tester.pump();
    expect(value, 'Soup');
  });

  testWidgets('autovalidateMode is passed to super', (WidgetTester tester) async {
    int validateCalled = 0;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            autovalidateMode: AutovalidateMode.always,
            validator: (String? value) {
              validateCalled++;
              return null;
            },
          ),
        ),
      ),
    );

    expect(validateCalled, 1);
    await tester.enterText(find.byType(CupertinoTextField), 'a');
    await tester.pump();
    expect(validateCalled, 2);
  });

  testWidgets('validate is called if widget is enabled', (WidgetTester tester) async {
    int validateCalled = 0;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            enabled: true,
            autovalidateMode: AutovalidateMode.always,
            validator: (String? value) {
              validateCalled += 1;
              return null;
            },
          ),
        ),
      ),
    );

    expect(validateCalled, 1);
    await tester.enterText(find.byType(CupertinoTextField), 'a');
    await tester.pump();
    expect(validateCalled, 2);
  });

  testWidgets('readonly text form field will hide cursor by default', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            initialValue: 'readonly',
            readOnly: true,
          ),
        ),
      ),
    );

    await tester.showKeyboard(find.byType(CupertinoTextFormFieldRow));
    expect(tester.testTextInput.hasAnyClients, false);

    await tester.tap(find.byType(CupertinoTextField));
    await tester.pump();
    expect(tester.testTextInput.hasAnyClients, false);

    await tester.longPress(find.text('readonly'));
    await tester.pump();

    // Context menu should not have paste.
    expect(find.byType(CupertinoTextSelectionToolbar), findsOneWidget);
    expect(find.text('Paste'), findsNothing);

    final EditableTextState editableTextState =
        tester.firstState(find.byType(EditableText));
    final RenderEditable renderEditable = editableTextState.renderEditable;

    // Make sure it does not paint caret for a period of time.
    await tester.pump(const Duration(milliseconds: 200));
    expect(renderEditable, paintsExactlyCountTimes(#drawRect, 0));

    await tester.pump(const Duration(milliseconds: 200));
    expect(renderEditable, paintsExactlyCountTimes(#drawRect, 0));

    await tester.pump(const Duration(milliseconds: 200));
    expect(renderEditable, paintsExactlyCountTimes(#drawRect, 0));
  }, skip: isBrowser); // [intended] We do not use Flutter-rendered context menu on the Web.

  testWidgets('onTap is called upon tap', (WidgetTester tester) async {
    int tapCount = 0;
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            onTap: () {
              tapCount += 1;
            },
          ),
        ),
      ),
    );

    expect(tapCount, 0);
    await tester.tap(find.byType(CupertinoTextField));
    // Wait a bit so they're all single taps and not double taps.
    await tester.pump(const Duration(milliseconds: 300));
    await tester.tap(find.byType(CupertinoTextField));
    await tester.pump(const Duration(milliseconds: 300));
    await tester.tap(find.byType(CupertinoTextField));
    await tester.pump(const Duration(milliseconds: 300));
    expect(tapCount, 3);
  });

  // Regression test for https://github.com/flutter/flutter/issues/54472.
  testWidgets('reset resets the text fields value to the initialValue', (WidgetTester tester) async {
    await tester.pumpWidget(CupertinoApp(
      home: Center(
        child: CupertinoTextFormFieldRow(
          initialValue: 'initialValue',
        ),
      ),
    ));

    await tester.enterText(find.byType(CupertinoTextFormFieldRow), 'changedValue');

    final FormFieldState<String> state = tester.state<FormFieldState<String>>(find.byType(CupertinoTextFormFieldRow));
    state.reset();

    expect(find.text('changedValue'), findsNothing);
    expect(find.text('initialValue'), findsOneWidget);
  });

  // Regression test for https://github.com/flutter/flutter/issues/54472.
  testWidgets('didChange changes text fields value', (WidgetTester tester) async {
    await tester.pumpWidget(CupertinoApp(
      home: Center(
        child: CupertinoTextFormFieldRow(
          initialValue: 'initialValue',
        ),
      ),
    ));

    expect(find.text('initialValue'), findsOneWidget);

    final FormFieldState<String> state = tester
        .state<FormFieldState<String>>(find.byType(CupertinoTextFormFieldRow));
    state.didChange('changedValue');

    expect(find.text('initialValue'), findsNothing);
    expect(find.text('changedValue'), findsOneWidget);
  });

  testWidgets('onChanged callbacks value and FormFieldState.value are sync', (WidgetTester tester) async {
    bool called = false;

    late FormFieldState<String> state;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            onChanged: (String value) {
              called = true;
              expect(value, state.value);
            },
          ),
        ),
      ),
    );

    state = tester
        .state<FormFieldState<String>>(find.byType(CupertinoTextFormFieldRow));

    await tester.enterText(find.byType(CupertinoTextField), 'Soup');

    expect(called, true);
  });

  testWidgets('autofillHints is passed to super', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            autofillHints: const <String>[AutofillHints.countryName],
          ),
        ),
      ),
    );

    final CupertinoTextField widget =
        tester.widget(find.byType(CupertinoTextField));
    expect(widget.autofillHints, equals(const <String>[AutofillHints.countryName]));
  });

  testWidgets('autovalidateMode is passed to super', (WidgetTester tester) async {
    int validateCalled = 0;

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoPageScaffold(
          child: CupertinoTextFormFieldRow(
            autovalidateMode: AutovalidateMode.onUserInteraction,
            validator: (String? value) {
              validateCalled++;
              return null;
            },
          ),
        ),
      ),
    );

    expect(validateCalled, 0);
    await tester.enterText(find.byType(CupertinoTextField), 'a');
    await tester.pump();
    expect(validateCalled, 1);
  });

  testWidgets('AutovalidateMode.always mode shows error from the start', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            initialValue: 'Value',
            autovalidateMode: AutovalidateMode.always,
            validator: (String? value) => 'Error',
          ),
        ),
      ),
    );

    final Finder errorTextFinder = find.byType(Text);
    expect(errorTextFinder, findsOneWidget);

    final Text errorText = tester.widget(errorTextFinder);
    expect(errorText.data, 'Error');
  });

  testWidgets('Shows error text upon invalid input', (WidgetTester tester) async {
    final TextEditingController controller = TextEditingController(text: '');

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            controller: controller,
            autovalidateMode: AutovalidateMode.onUserInteraction,
            validator: (String? value) => 'Error',
          ),
        ),
      ),
    );

    expect(find.byType(Text), findsNothing);

    controller.text = 'Value';

    await tester.pumpAndSettle();

    final Finder errorTextFinder = find.byType(Text);
    expect(errorTextFinder, findsOneWidget);

    final Text errorText = tester.widget(errorTextFinder);
    expect(errorText.data, 'Error');
  });

  testWidgets('Shows prefix', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            prefix: const Text('Enter Value'),
          ),
        ),
      ),
    );

    final Finder errorTextFinder = find.byType(Text);
    expect(errorTextFinder, findsOneWidget);

    final Text errorText = tester.widget(errorTextFinder);
    expect(errorText.data, 'Enter Value');
  });

  testWidgets('Passes textDirection to underlying CupertinoTextField', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            textDirection: TextDirection.ltr,
          ),
        ),
      ),
    );

    final Finder ltrTextFieldFinder = find.byType(CupertinoTextField);
    expect(ltrTextFieldFinder, findsOneWidget);

    final CupertinoTextField ltrTextFieldWidget = tester.widget(ltrTextFieldFinder);
    expect(ltrTextFieldWidget.textDirection, TextDirection.ltr);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoTextFormFieldRow(
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
    );

    final Finder rtlTextFieldFinder = find.byType(CupertinoTextField);
    expect(rtlTextFieldFinder, findsOneWidget);

    final CupertinoTextField rtlTextFieldWidget = tester.widget(rtlTextFieldFinder);
    expect(rtlTextFieldWidget.textDirection, TextDirection.rtl);
  });
}
