// 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);
  });
}
