import React from 'react';
import PropTypes from 'prop-types';
import { createNamespace } from '../../tools/namingTools';
import { TYPE_BUTTON, TYPE_SUBMIT, TYPE_RESET, ATTR_REFER_URL } from '../../constants/buttons';
import { ALLOWED_CTA_TYPES, CTA_REFERABLE } from '../../constants/actions';
// IMPORTANT: (s)css should be imported after other atoms/components
import './styles/Button.scss';
import { getUrlWithPreviewMode } from '../../tools/urlTools';

const n = createNamespace('Button');

const Button = ({
    action,
    active,
    buttonType,
    children,
    condensed,
    ctaType,
    disabled,
    className: extraClass,
    onClick,
    referUrl,
    selected,
    size,
    type,
    url,
    wide,
    renderAsDiv,
    'data-testid': dataTestId,
    ...otherProps
}) => {
    const modifiers = [type, size, buttonType];
    // if a button is disabled, it won't be set as active
    if (disabled) {
        modifiers.push('disabled');
    } else if (active) {
        modifiers.push('active');
    }
    if (selected) {
        modifiers.push('selected');
    }
    if (condensed) {
        modifiers.push('condensed');
    }
    if (wide) {
        modifiers.push('wide');
    }

    const renderChild = child => (typeof child === 'string' ? <div key={child} {...n('text').withE2EId().props}>{child}</div> : child);

    const onClickHandler = e => {
        if (disabled) { return; }
        if (url) { window.location.assign(getUrlWithPreviewMode(url)); }
        if (onClick) {
            onClick(e);
        }
    };

    const buttonTestId = dataTestId ? { [createNamespace.TESTID_ATTR]: dataTestId } : n().withTestId('item').withE2EId('item').props;
    const buttonProps = Object.assign(
        n('item', modifiers).withClass(extraClass).props,
        buttonTestId,
        {
            onClick: onClickHandler
        },
        ctaType && { 'data-cta-type': ctaType },
        referUrl && ctaType === CTA_REFERABLE && { [ATTR_REFER_URL]: referUrl },
        url && { 'data-href': url },
        disabled && { disabled: true },
        otherProps
    );

    const renderButton = () => (renderAsDiv
        ? (
            /* eslint-disable react/button-has-type */
            <div {...buttonProps} type={action}>
                {React.Children.map(children, renderChild)}
            </div>
        )
        : (
            <button {...buttonProps} type={action}>
                {React.Children.map(children, renderChild)}
            </button>
        ));

    return renderButton();
};

export const allowedThemes = [
    'primary', 'primary-outline', 'secondary', 'emphasis', 'emphasis-outline', 'emphasisAlt', 'emphasisAlt-outline', 'white', 'card'
];
export const allowedActions = [TYPE_BUTTON, TYPE_SUBMIT, TYPE_RESET];
export const allowedSizes = ['default', 'small', 'large', 'input'];
export const allowedTypes = ['button', 'link', 'icon'];

Button.propTypes = {
    action: PropTypes.oneOf(allowedActions),
    active: PropTypes.bool,
    buttonType: PropTypes.oneOf(allowedTypes),
    condensed: PropTypes.bool,
    ctaType: PropTypes.oneOf(ALLOWED_CTA_TYPES),
    disabled: PropTypes.bool,
    className: PropTypes.string,
    onClick: PropTypes.func,
    referUrl: PropTypes.string,
    selected: PropTypes.bool,
    size: PropTypes.oneOf(allowedSizes),
    type: PropTypes.oneOf(allowedThemes),
    url: PropTypes.string,
    wide: PropTypes.bool,
    renderAsDiv: PropTypes.bool,
    'data-testid': PropTypes.string
};

Button.defaultProps = {
    action: TYPE_BUTTON,
    active: false,
    buttonType: 'button',
    condensed: false,
    ctaType: null,
    disabled: false,
    className: null,
    onClick: null,
    referUrl: null,
    selected: false,
    size: 'default',
    type: 'secondary',
    url: undefined,
    wide: false,
    renderAsDiv: false,
    'data-testid': ''
};

export default Button;
