// Copyright 2013 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 'dart:async';

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine/browser_detection.dart';

import 'package:ui/src/engine/dom.dart';
import 'package:ui/src/engine/initialization.dart';
import 'package:ui/src/engine/text_editing/composition_aware_mixin.dart';
import 'package:ui/src/engine/text_editing/text_editing.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

class _MockWithCompositionAwareMixin with CompositionAwareMixin {
  // These variables should be equal to their counterparts in CompositionAwareMixin.
  // Separate so the counterparts in CompositionAwareMixin can be private.
  static const String _kCompositionUpdate = 'compositionupdate';
  static const String _kCompositionStart = 'compositionstart';
  static const String _kCompositionEnd = 'compositionend';
}

DomHTMLInputElement get _inputElement {
  return defaultTextEditingRoot.querySelectorAll('input').first as DomHTMLInputElement;
}

GloballyPositionedTextEditingStrategy _enableEditingStrategy({
    required bool deltaModel,
    void Function(EditingState?, TextEditingDeltaState?)? onChange,
  }) {
  final HybridTextEditing owner = HybridTextEditing();

  owner.configuration = InputConfiguration(enableDeltaModel: deltaModel);

  final GloballyPositionedTextEditingStrategy editingStrategy =
      GloballyPositionedTextEditingStrategy(owner);

  owner.debugTextEditingStrategyOverride = editingStrategy;

  editingStrategy.enable(owner.configuration!, onChange: onChange ?? (_, __) {}, onAction: (_) {});
  return editingStrategy;
}

Future<void> testMain() async {
  await initializeEngine();

  const String fakeComposingText = 'ImComposingText';

  group('$CompositionAwareMixin', () {
    late TextEditingStrategy editingStrategy;

    setUp(() {
      editingStrategy = _enableEditingStrategy(deltaModel: false);
    });

    tearDown(() {
      editingStrategy.disable();
    });

    group('composition end', () {
      test('should reset composing text on handle composition end', () {
        final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
            _MockWithCompositionAwareMixin();
        mockWithCompositionAwareMixin.composingText = fakeComposingText;
        mockWithCompositionAwareMixin.addCompositionEventHandlers(_inputElement);

        _inputElement.dispatchEvent(createDomEvent('Event', _MockWithCompositionAwareMixin._kCompositionEnd));

        expect(mockWithCompositionAwareMixin.composingText, null);
      });
    });

    group('composition start', () {
      test('should reset composing text on handle composition start', () {
        final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
            _MockWithCompositionAwareMixin();
        mockWithCompositionAwareMixin.composingText = fakeComposingText;
        mockWithCompositionAwareMixin.addCompositionEventHandlers(_inputElement);

        _inputElement.dispatchEvent(createDomEvent('Event', _MockWithCompositionAwareMixin._kCompositionStart));

        expect(mockWithCompositionAwareMixin.composingText, null);
      });
    });

    group('composition update', () {
      test('should set composing text to event composing text', () {
        const String fakeEventText = 'IAmComposingThis';
        final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
            _MockWithCompositionAwareMixin();
        mockWithCompositionAwareMixin.composingText = fakeComposingText;
        mockWithCompositionAwareMixin.addCompositionEventHandlers(_inputElement);

        _inputElement.dispatchEvent(createDomCompositionEvent(
            _MockWithCompositionAwareMixin._kCompositionUpdate,
            <Object?, Object?>{ 'data': fakeEventText }
        ));

        expect(mockWithCompositionAwareMixin.composingText, fakeEventText);
      });
    });

    group('determine composition state', () {
      test('should return new composition state if valid new composition', () {
        const int baseOffset = 100;
        const String composingText = 'composeMe';

        final EditingState editingState = EditingState(
          extentOffset: baseOffset,
          text: 'testing',
          baseOffset: baseOffset,
        );

        final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
            _MockWithCompositionAwareMixin();
        mockWithCompositionAwareMixin.composingText = composingText;

        const int expectedComposingBase = baseOffset - composingText.length;

        expect(
            mockWithCompositionAwareMixin.determineCompositionState(editingState),
            editingState.copyWith(
                composingBaseOffset: expectedComposingBase,
                composingExtentOffset: expectedComposingBase + composingText.length));
      });
    });
  });

  group('composing range', () {
    late GloballyPositionedTextEditingStrategy editingStrategy;

    setUp(() {
      editingStrategy = _enableEditingStrategy(deltaModel: false);
    });

    tearDown(() {
      editingStrategy.disable();
    });

    test('should be [0, compostionStrLength] on new composition', () {
      const String composingText = 'hi';

      _inputElement.dispatchEvent(createDomCompositionEvent(
              _MockWithCompositionAwareMixin._kCompositionUpdate,
              <Object?, Object?>{'data': composingText}));

      // Set the selection text.
      _inputElement.value = composingText;
      _inputElement.dispatchEvent(createDomEvent('Event', 'input'));

      expect(
          editingStrategy.lastEditingState,
          isA<EditingState>()
              .having((EditingState editingState) => editingState.composingBaseOffset,
                  'composingBaseOffset', 0)
              .having((EditingState editingState) => editingState.composingExtentOffset,
                  'composingExtentOffset', composingText.length));
    });

    test(
        'should be [beforeComposingText - composingText, compostionStrLength] on composition in the middle of text',
        () {
      const String composingText = 'hi';
      const String beforeComposingText = 'beforeComposingText';
      const String afterComposingText = 'afterComposingText';

      // Type in the text box, then move cursor to the middle.
      _inputElement.value = '$beforeComposingText$afterComposingText';
      _inputElement.setSelectionRange(beforeComposingText.length, beforeComposingText.length);

      _inputElement.dispatchEvent(createDomCompositionEvent(
          _MockWithCompositionAwareMixin._kCompositionUpdate,
          <Object?, Object?>{ 'data': composingText }
      ));

      // Flush editing state (since we did not compositionend).
      _inputElement.dispatchEvent(createDomEvent('Event', 'input'));

      expect(
          editingStrategy.lastEditingState,
          isA<EditingState>()
              .having((EditingState editingState) => editingState.composingBaseOffset!,
                  'composingBaseOffset', beforeComposingText.length - composingText.length)
              .having((EditingState editingState) => editingState.composingExtentOffset,
                  'composingExtentOffset', beforeComposingText.length));
    });
  });

  group('Text Editing Delta Model', () {
    late GloballyPositionedTextEditingStrategy editingStrategy;

    final StreamController<TextEditingDeltaState?> deltaStream =
        StreamController<TextEditingDeltaState?>.broadcast();

    setUp(() {
        editingStrategy = _enableEditingStrategy(
          deltaModel: true,
          onChange: (_, TextEditingDeltaState? deltaState) => deltaStream.add(deltaState)
        );
    });

    tearDown(() {
      editingStrategy.disable();
    });

    test('should have newly entered composing characters', () async {
      const String newComposingText = 'n';

      editingStrategy.setEditingState(EditingState(text: newComposingText, baseOffset: 1, extentOffset: 1));

      final Future<dynamic> containExpect = expectLater(
          deltaStream.stream.first,
          completion(isA<TextEditingDeltaState>()
            .having((TextEditingDeltaState deltaState) => deltaState.composingOffset, 'composingOffset', 0)
            .having((TextEditingDeltaState deltaState) => deltaState.composingExtent, 'composingExtent', newComposingText.length)
          ));


      _inputElement.dispatchEvent(createDomCompositionEvent(
          _MockWithCompositionAwareMixin._kCompositionUpdate,
          <Object?, Object?>{ 'data': newComposingText }));

      await containExpect;
    });

    test('should emit changed composition', () async {
      const String newComposingCharsInOrder = 'hiCompose';

      for (int currCharIndex = 0; currCharIndex < newComposingCharsInOrder.length; currCharIndex++) {
        final String currComposingSubstr = newComposingCharsInOrder.substring(0, currCharIndex + 1);

        editingStrategy.setEditingState(
          EditingState(text: currComposingSubstr, baseOffset: currCharIndex + 1, extentOffset: currCharIndex + 1)
        );

        final Future<dynamic> containExpect = expectLater(
          deltaStream.stream.first,
          completion(isA<TextEditingDeltaState>()
            .having((TextEditingDeltaState deltaState) => deltaState.composingOffset, 'composingOffset', 0)
            .having((TextEditingDeltaState deltaState) => deltaState.composingExtent, 'composingExtent', currCharIndex + 1)
        ));

        _inputElement.dispatchEvent(createDomCompositionEvent(
          _MockWithCompositionAwareMixin._kCompositionUpdate,
          <Object?, Object?>{ 'data': currComposingSubstr }));

        await containExpect;
      }
    },
    // TODO(antholeole): This test fails on Firefox because of how it orders events;
    // it's likely that this will be fixed by https://github.com/flutter/flutter/issues/105243.
    // Until the refactor gets merged, this test should run on all other browsers to prevent
    // regressions in the meantime.
    skip: browserEngine == BrowserEngine.firefox);
  });
}
