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

import '../widgets/clipboard_utils.dart';

class TestMaterialLocalizations extends DefaultMaterialLocalizations {
  @override
  String formatCompactDate(DateTime date) {
    return '${date.month}/${date.day}/${date.year}';
  }
}

class TestMaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<MaterialLocalizations> load(Locale locale) {
    return SynchronousFuture<MaterialLocalizations>(TestMaterialLocalizations());
  }

  @override
  bool shouldReload(TestMaterialLocalizationsDelegate old) => false;
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  final MockClipboard mockClipboard = MockClipboard();

  Widget inputDatePickerField({
    Key? key,
    DateTime? initialDate,
    DateTime? firstDate,
    DateTime? lastDate,
    ValueChanged<DateTime>? onDateSubmitted,
    ValueChanged<DateTime>? onDateSaved,
    SelectableDayPredicate? selectableDayPredicate,
    String? errorFormatText,
    String? errorInvalidText,
    String? fieldHintText,
    String? fieldLabelText,
    bool autofocus = false,
    Key? formKey,
    ThemeData? theme,
    Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates,
  }) {
    return MaterialApp(
      theme: theme ?? ThemeData.from(colorScheme: const ColorScheme.light()),
      localizationsDelegates: localizationsDelegates,
      home: Material(
        child: Form(
          key: formKey,
          child: InputDatePickerFormField(
            key: key,
            initialDate: initialDate ?? DateTime(2016, DateTime.january, 15),
            firstDate: firstDate ?? DateTime(2001),
            lastDate: lastDate ?? DateTime(2031, DateTime.december, 31),
            onDateSubmitted: onDateSubmitted,
            onDateSaved: onDateSaved,
            selectableDayPredicate: selectableDayPredicate,
            errorFormatText: errorFormatText,
            errorInvalidText: errorInvalidText,
            fieldHintText: fieldHintText,
            fieldLabelText: fieldLabelText,
            autofocus: autofocus,
          ),
        ),
      ),
    );
  }

  TextField textField(WidgetTester tester) {
    return tester.widget<TextField>(find.byType(TextField));
  }

  TextEditingController textFieldController(WidgetTester tester) {
    return textField(tester).controller!;
  }

  double textOpacity(WidgetTester tester, String textValue) {
    final FadeTransition opacityWidget = tester.widget<FadeTransition>(
      find.ancestor(
        of: find.text(textValue),
        matching: find.byType(FadeTransition),
      ).first,
    );
    return opacityWidget.opacity.value;
  }

  group('InputDatePickerFormField', () {

    testWidgets('Initial date is the default', (WidgetTester tester) async {
      final GlobalKey<FormState> formKey = GlobalKey<FormState>();
      final DateTime initialDate = DateTime(2016, DateTime.february, 21);
      DateTime? inputDate;
      await tester.pumpWidget(inputDatePickerField(
        initialDate: initialDate,
        onDateSaved: (DateTime date) => inputDate = date,
        formKey: formKey,
      ));
      expect(textFieldController(tester).value.text, equals('02/21/2016'));
      formKey.currentState!.save();
      expect(inputDate, equals(initialDate));
    });

    testWidgets('Changing initial date is reflected in text value', (WidgetTester tester) async {
      final DateTime initialDate = DateTime(2016, DateTime.february, 21);
      final DateTime updatedInitialDate = DateTime(2016, DateTime.february, 23);
      await tester.pumpWidget(inputDatePickerField(
        initialDate: initialDate,
      ));
      expect(textFieldController(tester).value.text, equals('02/21/2016'));

      await tester.pumpWidget(inputDatePickerField(
        initialDate: updatedInitialDate,
      ));
      await tester.pumpAndSettle();
      expect(textFieldController(tester).value.text, equals('02/23/2016'));
    });

    testWidgets('Valid date entry', (WidgetTester tester) async {
      final GlobalKey<FormState> formKey = GlobalKey<FormState>();
      DateTime? inputDate;
      await tester.pumpWidget(inputDatePickerField(
        onDateSaved: (DateTime date) => inputDate = date,
        formKey: formKey,
      ));

      textFieldController(tester).text = '02/21/2016';
      formKey.currentState!.save();
      expect(inputDate, equals(DateTime(2016, DateTime.february, 21)));
    });

    testWidgets('Invalid text entry shows errorFormat text', (WidgetTester tester) async {
      final GlobalKey<FormState> formKey = GlobalKey<FormState>();
      DateTime? inputDate;
      await tester.pumpWidget(inputDatePickerField(
        onDateSaved: (DateTime date) => inputDate = date,
        formKey: formKey,
      ));
      // Default errorFormat text
      expect(find.text('Invalid format.'), findsNothing);
      await tester.enterText(find.byType(TextField), 'foobar');
      expect(formKey.currentState!.validate(), isFalse);
      await tester.pumpAndSettle();
      expect(inputDate, isNull);
      expect(find.text('Invalid format.'), findsOneWidget);

      // Change to a custom errorFormat text
      await tester.pumpWidget(inputDatePickerField(
        onDateSaved: (DateTime date) => inputDate = date,
        errorFormatText: 'That is not a date.',
        formKey: formKey,
      ));
      expect(formKey.currentState!.validate(), isFalse);
      await tester.pumpAndSettle();
      expect(find.text('Invalid format.'), findsNothing);
      expect(find.text('That is not a date.'), findsOneWidget);
    });

    testWidgets('Valid text entry, but date outside first or last date shows bounds shows errorInvalid text', (WidgetTester tester) async {
      final GlobalKey<FormState> formKey = GlobalKey<FormState>();
      DateTime? inputDate;
      await tester.pumpWidget(inputDatePickerField(
        firstDate: DateTime(1966, DateTime.february, 21),
        lastDate: DateTime(2040, DateTime.february, 23),
        onDateSaved: (DateTime date) => inputDate = date,
        formKey: formKey,
      ));
      // Default errorInvalid text
      expect(find.text('Out of range.'), findsNothing);
      // Before first date
      await tester.enterText(find.byType(TextField), '02/21/1950');
      expect(formKey.currentState!.validate(), isFalse);
      await tester.pumpAndSettle();
      expect(inputDate, isNull);
      expect(find.text('Out of range.'), findsOneWidget);
      // After last date
      await tester.enterText(find.byType(TextField), '02/23/2050');
      expect(formKey.currentState!.validate(), isFalse);
      await tester.pumpAndSettle();
      expect(inputDate, isNull);
      expect(find.text('Out of range.'), findsOneWidget);

      await tester.pumpWidget(inputDatePickerField(
        onDateSaved: (DateTime date) => inputDate = date,
        errorInvalidText: 'Not in given range.',
        formKey: formKey,
      ));
      expect(formKey.currentState!.validate(), isFalse);
      await tester.pumpAndSettle();
      expect(find.text('Out of range.'), findsNothing);
      expect(find.text('Not in given range.'), findsOneWidget);
    });

    testWidgets('selectableDatePredicate will be used to show errorInvalid if date is not selectable', (WidgetTester tester) async {
      final GlobalKey<FormState> formKey = GlobalKey<FormState>();
      DateTime? inputDate;
      await tester.pumpWidget(inputDatePickerField(
        initialDate: DateTime(2016, DateTime.january, 16),
        onDateSaved: (DateTime date) => inputDate = date,
        selectableDayPredicate: (DateTime date) => date.day.isEven,
        formKey: formKey,
      ));
      // Default errorInvalid text
      expect(find.text('Out of range.'), findsNothing);
      // Odd day shouldn't be valid
      await tester.enterText(find.byType(TextField), '02/21/1966');
      expect(formKey.currentState!.validate(), isFalse);
      await tester.pumpAndSettle();
      expect(inputDate, isNull);
      expect(find.text('Out of range.'), findsOneWidget);
      // Even day is valid
      await tester.enterText(find.byType(TextField), '02/24/2030');
      expect(formKey.currentState!.validate(), isTrue);
      formKey.currentState!.save();
      await tester.pumpAndSettle();
      expect(inputDate, equals(DateTime(2030, DateTime.february, 24)));
      expect(find.text('Out of range.'), findsNothing);
    });

    testWidgets('Empty field shows hint text when focused', (WidgetTester tester) async {
      await tester.pumpWidget(inputDatePickerField());
      // Focus on it
      await tester.tap(find.byType(TextField));
      await tester.pumpAndSettle();

      // Hint text should be invisible
      expect(textOpacity(tester, 'mm/dd/yyyy'), equals(0.0));
      textFieldController(tester).clear();
      await tester.pumpAndSettle();
      // Hint text should be visible
      expect(textOpacity(tester, 'mm/dd/yyyy'), equals(1.0));

      // Change to a different hint text
      await tester.pumpWidget(inputDatePickerField(fieldHintText: 'Enter some date'));
      await tester.pumpAndSettle();
      expect(find.text('mm/dd/yyyy'), findsNothing);
      expect(textOpacity(tester, 'Enter some date'), equals(1.0));
      await tester.enterText(find.byType(TextField), 'foobar');
      await tester.pumpAndSettle();
      expect(textOpacity(tester, 'Enter some date'), equals(0.0));
    });

    testWidgets('Label text', (WidgetTester tester) async {
      await tester.pumpWidget(inputDatePickerField());
      // Default label
      expect(find.text('Enter Date'), findsOneWidget);

      await tester.pumpWidget(inputDatePickerField(
        fieldLabelText: 'Give me a date!',
      ));
      expect(find.text('Enter Date'), findsNothing);
      expect(find.text('Give me a date!'), findsOneWidget);
    });

    testWidgets('Semantics', (WidgetTester tester) async {
      final SemanticsHandle semantics = tester.ensureSemantics();
      addTearDown(semantics.dispose);

      // Fill the clipboard so that the Paste option is available in the text
      // selection menu.
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
      await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
      addTearDown(() => tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null));

      await tester.pumpWidget(inputDatePickerField(autofocus: true));
      await tester.pumpAndSettle();

      expect(tester.getSemantics(find.byType(EditableText)), matchesSemantics(
        label: 'Enter Date\nmm/dd/yyyy',
        isTextField: true,
        isFocused: true,
        value: '01/15/2016',
        hasTapAction: true,
        hasSetTextAction: true,
        hasSetSelectionAction: true,
        hasCopyAction: true,
        hasCutAction: true,
        hasPasteAction: true,
        hasMoveCursorBackwardByCharacterAction: true,
        hasMoveCursorBackwardByWordAction: true,
      ));
    });

    testWidgets('InputDecorationTheme is honored', (WidgetTester tester) async {
      const InputBorder border = InputBorder.none;
      await tester.pumpWidget(inputDatePickerField(
        theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
          inputDecorationTheme: const InputDecorationTheme(
            border: border,
          ),
        ),
      ));
      await tester.pumpAndSettle();

      // Get the border and container color from the painter of the _BorderContainer
      // (this was cribbed from input_decorator_test.dart).
      final CustomPaint customPaint = tester.widget(find.descendant(
        of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_BorderContainer'),
        matching: find.byWidgetPredicate((Widget w) => w is CustomPaint),
      ));
      final dynamic/*_InputBorderPainter*/ inputBorderPainter = customPaint.foregroundPainter;
      // ignore: avoid_dynamic_calls
      final dynamic/*_InputBorderTween*/ inputBorderTween = inputBorderPainter.border;
      // ignore: avoid_dynamic_calls
      final Animation<double> animation = inputBorderPainter.borderAnimation as Animation<double>;
      // ignore: avoid_dynamic_calls
      final InputBorder actualBorder = inputBorderTween.evaluate(animation) as InputBorder;
      // ignore: avoid_dynamic_calls
      final Color containerColor = inputBorderPainter.blendedColor as Color;

      // Border should match
      expect(actualBorder, equals(border));

      // It shouldn't be filled, so the color should be transparent
      expect(containerColor, equals(Colors.transparent));
    });

    testWidgets('Date text localization', (WidgetTester tester) async {
      final Iterable<LocalizationsDelegate<dynamic>> delegates = <LocalizationsDelegate<dynamic>>[
        TestMaterialLocalizationsDelegate(),
        DefaultWidgetsLocalizations.delegate,
      ];
      await tester.pumpWidget(
        inputDatePickerField(
          localizationsDelegates: delegates,
        )
      );
      await tester.enterText(find.byType(TextField), '01/01/2022');
      await tester.pumpAndSettle();

      // Verify that the widget can be updated to a new value after the
      // entered text was transformed by the localization formatter.
      await tester.pumpWidget(
        inputDatePickerField(
          initialDate: DateTime(2017),
          localizationsDelegates: delegates,
        )
      );
    });
  });
}
