import React, { useRef, useEffect, useMemo } from 'react';
import classNames from 'classnames';
import { MergeView } from '@codemirror/merge';
import { EditorState } from '@codemirror/state';
import { lineNumbers, highlightActiveLine, EditorView } from '@codemirror/view';
import { useTranslation } from '../hooks/use-translation';
import { jsx as _jsx } from "react/jsx-runtime";
const readOnlyExtensions = [
// only read-only is supported
EditorView.editable.of(false), EditorState.readOnly.of(true)];
const viewSettingsDefault = {
  showLineNumbers: true,
  highlightActiveLine: false
};

/**
 * Merge view for 2 text versions
 * Limited to read-only view.
 * @midnight-gray-supported
 * @alpine-light-supported
 */
export function TextMergeView({
  className,
  testId = 'text-merge-view-container',
  isDarkTheme = true,
  values,
  viewSettings = viewSettingsDefault
}) {
  const {
    t
  } = useTranslation();
  const mergeViewParentRef = useRef(null);
  const mergeViewRef = useRef(null);
  const ariaLabelForSection = t('Text merge view - read only');
  const allExtensionsMemo = useMemo(() => {
    const extentions = [...readOnlyExtensions, EditorView.contentAttributes.of({
      'aria-label': ariaLabelForSection
    })];
    if (viewSettings.showLineNumbers) {
      extentions.push(lineNumbers());
    }
    if (viewSettings.highlightActiveLine) {
      extentions.push(highlightActiveLine());
    }
    extentions.push(EditorView.theme({}, {
      dark: isDarkTheme
    }));
    return extentions;
  }, [viewSettings, isDarkTheme, ariaLabelForSection]);
  useEffect(() => {
    return () => {
      mergeViewRef.current?.destroy();
      mergeViewRef.current = null;
    };
  }, []);
  useEffect(() => {
    mergeViewRef.current = new MergeView({
      a: {
        doc: values.left,
        extensions: [...allExtensionsMemo]
      },
      b: {
        doc: values.right,
        extensions: [...allExtensionsMemo]
      },
      // @ts-expect-error because parent: Element | DocumentFragment | undefined allows undefined and ref does not allow
      parent: mergeViewParentRef.current
    });
  }, [allExtensionsMemo]);
  useEffect(() => {
    const mv = mergeViewRef.current;
    if (!mv || !values) {
      return;
    }
    const replaceDoc = (view, text) => {
      const current = view.state.doc.toString();
      if (current === text) {
        return;
      }
      view.dispatch({
        changes: {
          from: 0,
          to: view.state.doc.length,
          insert: text
        }
      });
    };
    // Update only if content changed
    replaceDoc(mv.a, values.left);
    replaceDoc(mv.b, values.right);
  }, [values]);
  return /*#__PURE__*/_jsx("div", {
    className: classNames('text-merge-view', className),
    "test-id": testId,
    ref: mergeViewParentRef,
    "aria-label": t('Comparison of two text view'),
    "aria-readonly": true,
    tabIndex: 0,
    role: "textbox"
  });
}