import * as React from 'react';
import {joinClassNames} from '../../utils/joinClassNames';
import {PLACEMENT, SIZE} from '../../constants/constants';
import {Icon} from '../../component/icon/Icon';
import * as styles from './editableField.m.scss';
import {IconIntent} from '@unidata/icon';
import {safeInvoke} from '../../utils/safeInvoke';
import {Tooltip} from '../../component';

interface IProps {
    isEditMode: boolean;
    readOnly: boolean;
    errorText?: string;
    size?: SIZE;
    isCroppedWidth?: boolean;
    inputExtraControls?: React.ReactNode;
    handlePencilClick?: () => void;
    onToggleEditMode: (isEdit: boolean) => void;
    editIndicatorPosition?: 'inside' | 'outside' | 'outsideOffset';
    iconIntent?: IconIntent;
    tooltipOverlay?: string;
}

interface IState {
    showControls: boolean;
}

export class EditableField extends React.Component<IProps, IState> {
    override state = {
        showControls: false
    };

    onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
        if (e.key === 'Enter') {
            this.props.onToggleEditMode(false);

            e.stopPropagation();
        }
    };

    handleEdit = () => {
        if (this.props.readOnly) {
            return;
        }

        this.setState({showControls: false});

        this.props.onToggleEditMode(true);
    };

    handlePencilClick = () => {
        if (this.props.readOnly) {
            this.setState({showControls: false});
            safeInvoke(this.props.handlePencilClick);
        } else {
            this.handleEdit();
        }
    };

    onBlur = () => {
        this.setState({showControls: false});
    };

    onMouseEnter = () => {
        this.setState({showControls: true});
    };

    onMouseLeave = () => {
        this.setState({showControls: false});
    };

    renderEditMode () {
        const classNames = joinClassNames(
            styles.editableFieldInput,
            [styles.isCropped, Boolean(this.props.isCroppedWidth)]
        );

        return (
            <span
                className={classNames}
                onKeyPress={this.onKeyPress}>
                {this.props.children}
                {this.props.inputExtraControls}
            </span>
        );
    }

    renderViewMode () {
        const withRightOffset = this.props.editIndicatorPosition === 'outside' ||
            (this.props.editIndicatorPosition === 'outsideOffset' && this.state.showControls);

        const iconOutside = this.props.editIndicatorPosition === 'outsideOffset' ||
            this.props.editIndicatorPosition === 'outside';

        const classNames = joinClassNames(
            styles.editableField,
            [styles.showControls, this.state.showControls],
            [styles.withRightOffset, withRightOffset],
            [styles.isCropped, Boolean(this.props.isCroppedWidth)]
        );

        return (
            <span
                className={classNames}
                onMouseEnter={this.onMouseEnter}
                onMouseLeave={this.onMouseLeave}
                onClick={this.handleEdit}
                tabIndex={0}
                onFocus={this.handleEdit}>
                {this.props.children}
                {
                    this.state.showControls && (
                        <div
                            className={joinClassNames(styles.editIcon,
                                [styles.editIconOutside, iconOutside])
                            }>
                            <Icon
                                intent={this.props.iconIntent}
                                onClick={this.handlePencilClick}
                                name={'pencil-line'}/>
                        </div>
                    )}
            </span>
        );
    }

    override render () {
        const isEditMode = this.props.isEditMode;
        const overlay = this.props.tooltipOverlay;

        if (isEditMode) {
            return this.renderEditMode();
        }

        if (overlay) {
            return (
                <Tooltip overlay={overlay} placement={PLACEMENT.TOP_START} mouseEnterDelay={700}>
                    <span>
                        {this.renderViewMode()}
                    </span>
                </Tooltip>
            );
        }

        return this.renderViewMode();
    }


}
