import * as React from 'react';
import { renderWithAdaptableContext } from '../../../View/renderWithAdaptableContext';
import { InternalAdaptablePercentageEditor, } from './InternalAdaptablePercentageEditor';
import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
import { getStartValue } from '../AdaptableNumberEditor';
import NumberExtensions from '../../../Utilities/Extensions/NumberExtensions';
const defaultValueParser = ({ newValue, oldValue: _ }) => {
    return newValue;
};
const style = {
    position: 'absolute',
    top: '0px',
    left: '0px',
    right: '0px',
    bottom: '0px',
};
export const AdaptableReactPercentageEditor = forwardRef((props, ref) => {
    const [initialValue] = useState(() => NumberExtensions.timesBy100(getStartValue(props)));
    const valueRef = useRef(initialValue);
    const columnId = props.column.getColId();
    const adaptable = props.context.__adaptable;
    const colValueParser = props.column.getColDef().valueParser;
    const valueParser = typeof colValueParser === 'function' ? colValueParser : defaultValueParser;
    function onValueChange(value) {
        const newValue = valueParser
            ? valueParser({
                ...props,
                oldValue: props.value,
                newValue: value,
            })
            : value;
        valueRef.current = newValue;
        props.onValueChange?.(NumberExtensions.divideBy100(newValue));
    }
    const editorRef = useRef(null);
    useImperativeHandle(ref, () => {
        return {
            focusIn() {
                editorRef.current?.focus();
            },
            // the final value to send to the grid, on completion of editing
            getValue() {
                return NumberExtensions.divideBy100(valueRef.current);
            },
        };
    });
    const editorElement = (React.createElement(InternalAdaptablePercentageEditor, { defaultValue: initialValue, showClearButton: props.showClearButton ?? true, emptyValue: props.emptyValue ?? '', onValueChange: onValueChange, ref: (editor) => {
            editorRef.current = editor;
            editor?.focus();
        } }));
    function onKeyDown(keyDownEvent) {
        adaptable._emit('CellEditorKeyDown', {
            keyDownEvent,
            cellValue: valueRef.current,
            columnId,
            updateValueCallback: (updatedValue) => {
                editorRef.current.setValue(updatedValue);
            },
        });
    }
    return (React.createElement("div", { style: style, onKeyDown: onKeyDown }, renderWithAdaptableContext(editorElement, adaptable)));
});
AdaptableReactPercentageEditor.displayName = 'AdaptableReactPercentageEditor';
/**
 * Used to edit percentage columns as percentages (similar to how its done in Excel)
 */
export class AdaptablePercentageEditor {
    value;
    columnId;
    el;
    params;
    editor;
    valueParser = defaultValueParser;
    unmountReactRoot;
    init(params) {
        this.value = getStartValue(params);
        this.params = params;
        this.columnId = params.column.getColId();
        const { valueParser } = params.column.getColDef();
        if (typeof valueParser === 'function') {
            this.valueParser = valueParser;
        }
        this.el = document.createElement('div');
        Object.keys(style).forEach((key) => {
            //@ts-ignore
            this.el.style[key] = style[key];
        });
    }
    /* Component Editor Lifecycle methods */
    // gets called once when grid ready to insert the element
    getGui() {
        return this.el;
    }
    // the final value to send to the grid, on completion of editing
    getValue() {
        return this.value;
    }
    focusIn() {
        this.editor?.focus();
    }
    focusOut() { }
    // after this component has been created and inserted into the grid
    afterGuiAttached() {
        const adaptable = this.params.context.__adaptable;
        const defaultValue = NumberExtensions.timesBy100(this.value);
        const editorElement = (React.createElement(InternalAdaptablePercentageEditor, { defaultValue: defaultValue, showClearButton: this.params.showClearButton ?? true, emptyValue: this.params.emptyValue ?? '', onValueChange: this.onValueChange, ref: (editor) => {
                this.editor = editor;
                editor?.focus();
            } }));
        this.unmountReactRoot = adaptable.renderReactRoot(renderWithAdaptableContext(editorElement, adaptable), this.el);
        this.getGui().addEventListener('keydown', (keyDownEvent) => {
            adaptable._emit('CellEditorKeyDown', {
                keyDownEvent,
                cellValue: this.value,
                columnId: this.columnId,
                updateValueCallback: (updatedValue) => {
                    this.editor.setValue(updatedValue);
                },
            });
        });
    }
    destroy() {
        this.unmountReactRoot?.();
    }
    onValueChange = (value) => {
        const newValue = this.valueParser
            ? this.valueParser({
                ...this.params,
                oldValue: this.params.value,
                newValue: value,
            })
            : value;
        this.value = NumberExtensions.divideBy100(newValue);
    };
}
