'use strict';

import React, {HTMLAttributes} from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

type Props = {
    noOffset?: boolean;
    addTopOffset?: boolean;
    addLeftOffset?: boolean;
    addRightOffset?: boolean;
    addHorizontalOffset?: boolean;
    cancelTopOffset?: boolean;
    cancelBottomOffset?: boolean;
    cancelHorizontalOffset?: boolean;
    accent?: boolean;
    condensed?: boolean;
    halfCondensed?: boolean;
    inline?: boolean;
    verticalAlign?: string | boolean;
    children?: React.ReactNode;
    className?: string;
    testAutomationId?: string;
    onClick?: Function;
    onKeyDown?: Function;
    onMouseDown?: Function;
    handleKeyDown?: boolean;
    preventDefaultKeyDown?: boolean;
    noOverflow?: boolean;
} & Partial<DefaultProps> &
    HTMLAttributes<any>;

type DefaultProps = {
    noOffset: boolean;
    addTopOffset: boolean;
    addLeftOffset: boolean;
    addRightOffset: boolean;
    addHorizontalOffset: boolean;
    cancelTopOffset: boolean;
    cancelBottomOffset: boolean;
    cancelHorizontalOffset: boolean;
    accent: boolean;
    condensed: boolean;
    halfCondensed: boolean;
    inline: boolean;
    verticalAlign: boolean;
    // testAutomationId: null,
    // onClick: e => e,
    // onKeyDown: null,
    // onMouseDown: null,
    handleKeyDown: boolean;
    preventDefaultKeyDown: boolean;
};

export const KEY_ENTER = 13;
export const KEY_SPACE = 32;

export class Block extends React.Component<Props> {
    static propTypes = {
        noOffset: PropTypes.bool,
        addTopOffset: PropTypes.bool,
        addLeftOffset: PropTypes.bool,
        addRightOffset: PropTypes.bool,
        addHorizontalOffset: PropTypes.bool,
        cancelTopOffset: PropTypes.bool,
        cancelBottomOffset: PropTypes.bool,
        cancelHorizontalOffset: PropTypes.bool,
        accent: PropTypes.bool,
        condensed: PropTypes.bool,
        halfCondensed: PropTypes.bool,
        inline: PropTypes.bool,
        verticalAlign: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
        children: PropTypes.node,
        className: PropTypes.string,
        testAutomationId: PropTypes.string,
        onClick: PropTypes.func,
        onKeyDown: PropTypes.func,
        onMouseDown: PropTypes.func,
        handleKeyDown: PropTypes.bool,
        preventDefaultKeyDown: PropTypes.bool,
        noOverflow: PropTypes.bool
    };

    static defaultProps = {
        noOffset: false,
        addTopOffset: false,
        addLeftOffset: false,
        addRightOffset: false,
        addHorizontalOffset: false,
        cancelTopOffset: false,
        cancelBottomOffset: false,
        cancelHorizontalOffset: false,
        accent: false,
        condensed: false,
        halfCondensed: false,
        inline: false,
        verticalAlign: false,
        children: null,
        className: null,
        testAutomationId: null,
        onClick: e => e,
        onKeyDown: null,
        onMouseDown: null,
        handleKeyDown: false,
        preventDefaultKeyDown: true,
        noOverflow: false
    };

    onKeyDown = e => {
        const {onClick, onKeyDown, preventDefaultKeyDown} = this.props;

        if (onKeyDown) {
            onKeyDown(e);
        }

        if (e.keyCode === KEY_ENTER || e.keyCode === KEY_SPACE) {
            onClick && onClick(e);
            if (preventDefaultKeyDown) {
                e.preventDefault();
            }
        }
    };

    onMouseDown = e => {
        const {onMouseDown} = this.props;
        if (onMouseDown) {
            onMouseDown(e);
        }
    };

    render() {
        let {
            noOffset,
            addTopOffset,
            addLeftOffset,
            addRightOffset,
            addHorizontalOffset,
            cancelTopOffset,
            cancelBottomOffset,
            cancelHorizontalOffset,
            verticalAlign,
            accent,
            condensed,
            halfCondensed,
            inline,
            className,
            testAutomationId,
            children,
            handleKeyDown,
            preventDefaultKeyDown,
            noOverflow,
            ...props
        } = this.props;

        let classNames = classnames(className, {
            'rc-block': !cancelBottomOffset && !noOffset && !inline,
            'rc-block-inline': inline,
            'rc-block-addTopOffset': addTopOffset,
            'rc-block-addLeftOffset': addLeftOffset,
            'rc-block-addRightOffset': addRightOffset,
            'rc-block-addHorizontalOffset': addHorizontalOffset,
            'rc-block-cancelTopOffset': cancelTopOffset,
            'rc-block-cancelBottomOffset': cancelBottomOffset,
            'rc-block-cancelHorizontalOffset': cancelHorizontalOffset,
            'rc-block-accent': accent,
            'rc-block-condensed': condensed,
            'rc-block-half-condensed': halfCondensed,
            'rc-block-vertical-center':
                (verticalAlign as any) === 'center' || verticalAlign === true,
            'rc-block-vertical-bottom': (verticalAlign as any) === 'bottom',
            'rc-block-noOverflow': noOverflow
        });

        if (handleKeyDown) {
            props = {
                ...props,
                onMouseDown: this.onMouseDown,
                onKeyDown: this.onKeyDown
            };
        }

        return (
            <div
                className={classNames}
                data-test-automation-id={testAutomationId}
                {...props as any}>
                {children}
            </div>
        );
    }
}
