import React from 'react';
import PropTypes from 'prop-types';
import { createNamespace } from '../../tools/namingTools';
import { LEFT, RIGHT } from '../../constants/alignment';
import { LINK_THEMES, TARGET_BLANK, REL_NOOPENER } from '../../constants/buttons';
import Icon, { allowedTypes } from '../icon/Icon';
import Image from '../image/Image';
import './styles/Link.scss';

const n = createNamespace('Link');

const Link = ({
    children,
    href,
    alt,
    target,
    theme,
    icon,
    iconSrc,
    iconClass,
    textClass,
    iconPosition,
    iconExtraContent,
    hiddenText,
    className: extraClass,
    onClick,
    onMouseOver,
    onMouseLeave,
    onFocus
}) => {
    const hasIcon = Boolean(icon || iconSrc);

    if (!children && !hasIcon) {
        return null;
    }

    const isExternalLink = target && target === TARGET_BLANK;

    const linkProps = {
        ...n('anchor', theme).withTestId().withE2EId().withClass(extraClass).props,
        target,
        href,
        rel: isExternalLink && REL_NOOPENER,
        onClick,
        onMouseOver,
        onMouseLeave,
        onFocus
    };

    const renderIcon = () => {
        const props = { ...n('icon', iconSrc ? 'external' : icon).withTestId().withClass(iconClass).props };

        return (
            <span {...n('iconWrapper', iconPosition).withTestId().props}>
                {iconSrc ? (
                    <Image {...props} src={iconSrc} alt={alt} />
                ) : (
                    <Icon {...props} type={icon} />
                )}
                {iconExtraContent}
            </span>
        );
    };

    const renderContent = (
        <React.Fragment>
            {hasIcon && renderIcon()}
            {children && (
                <span {...n('text', hiddenText && 'hidden').withClass(textClass).props}>
                    {children}
                </span>
            )}
        </React.Fragment>
    );

    return (
        <a {...linkProps} aria-label={alt}>{renderContent}</a>
    );
};

Link.propTypes = {
    href: PropTypes.string.isRequired,
    alt: PropTypes.string,
    target: PropTypes.oneOf([TARGET_BLANK]),
    theme: PropTypes.oneOf(LINK_THEMES),
    icon: PropTypes.oneOf(allowedTypes),
    iconSrc: PropTypes.string,
    iconClass: PropTypes.string,
    iconExtraContent: PropTypes.element,
    textClass: PropTypes.string,
    iconPosition: PropTypes.oneOf([LEFT.value, RIGHT.value]),
    hiddenText: PropTypes.bool,
    className: PropTypes.string,
    onClick: PropTypes.func,
    onMouseOver: PropTypes.func,
    onMouseLeave: PropTypes.func,
    onFocus: PropTypes.func
};

Link.defaultProps = {
    alt: null,
    target: null,
    theme: null,
    icon: null,
    iconSrc: null,
    iconClass: null,
    iconExtraContent: null,
    textClass: null,
    iconPosition: LEFT.value,
    hiddenText: false,
    className: '',
    onClick: () => {},
    onMouseOver: () => {},
    onMouseLeave: () => {},
    onFocus: () => {}
};

export default Link;
