import { __rest } from "tslib";
import React, { useContext, useEffect, useMemo, useRef, useCallback } from 'react';
import * as path from 'path';
import { URI, useInjectable } from '@opensumi/ide-core-browser';
import { ConfigProvider, AppConfig } from '@opensumi/ide-core-browser/lib/react-providers/config-provider';
import { EditorCollectionService } from '@opensumi/ide-editor/lib/common';
import { IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser/doc-model/types';
import { AppContext } from './context';
const noop = () => { };
export function useMemorizeFn(fn) {
    const fnRef = useRef(fn);
    fnRef.current = useMemo(() => fn, [fn]);
    return useCallback((...args) => fnRef.current(...args), []);
}
export const CodeEditorComponent = (_a) => {
    var { uri, editorOptions, onEditorCreate } = _a, props = __rest(_a, ["uri", "editorOptions", "onEditorCreate"]);
    const editorCollectionService = useInjectable(EditorCollectionService);
    const documentService = useInjectable(IEditorDocumentModelService);
    const appConfig = useInjectable(AppConfig);
    const containerRef = React.useRef(null);
    const uriStr = useMemo(() => {
        if (typeof uri === 'string') {
            return URI.file(path.join(appConfig.workspaceDir, uri)).toString();
        }
        return uri.toString();
    }, [uri]);
    const fetchingUriRef = useRef('');
    const documentModelRef = useRef();
    const editorRef = useRef();
    const unmountRef = useRef(false);
    const onEditorCreateMemorizeFn = useMemorizeFn(onEditorCreate || noop);
    const openDocumentModel = () => {
        if (editorRef.current && documentModelRef.current) {
            editorRef.current.open(documentModelRef.current);
        }
    };
    React.useEffect(() => {
        var _a;
        if (containerRef.current) {
            (_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
            editorRef.current = editorCollectionService.createCodeEditor(containerRef.current, Object.assign({ automaticLayout: true }, editorOptions));
            onEditorCreateMemorizeFn(editorRef.current);
            openDocumentModel();
        }
        return () => {
            var _a, _b;
            unmountRef.current = true;
            (_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
            (_b = documentModelRef.current) === null || _b === void 0 ? void 0 : _b.dispose();
        };
    }, []);
    useEffect(() => {
        if (fetchingUriRef.current !== uriStr) {
            fetchingUriRef.current = uriStr;
            documentService.createModelReference(new URI(uriStr), 'editor-react-component').then((ref) => {
                if (documentModelRef.current) {
                    documentModelRef.current.dispose();
                }
                if (!unmountRef.current && ref.instance.uri.toString() === uriStr) {
                    documentModelRef.current = ref;
                    openDocumentModel();
                }
                else {
                    ref.dispose();
                }
            });
        }
    }, [uriStr]);
    return React.createElement("div", Object.assign({ ref: containerRef }, props));
};
export const CodeEditor = (props) => {
    const appContext = useContext(AppContext);
    if (!appContext.app)
        return null;
    return (React.createElement(ConfigProvider, { value: appContext.app.config },
        React.createElement(CodeEditorComponent, Object.assign({}, props))));
};
//# sourceMappingURL=CodeEditor.js.map