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,
    target,
    theme,
    icon,
    iconSrc,
    alt,
    iconClass,
    iconPosition,
    hiddenText,
    ...otherProps
}) => {
    const hasIcon = Boolean(icon || iconSrc);

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

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

    const {
        className: extraClass,
        'data-testid': parentTestId,
        ...otherLinkProps
    } = otherProps;

    const linkProps = {
        ...n('anchor', theme).withTestId(parentTestId).withClass(extraClass).props,
        ...otherLinkProps,
        target,
        href,
        rel: isExternalLink && REL_NOOPENER
    };

    const renderIcon = () => {
        const modifiers = [
            iconPosition,
            iconSrc ? 'external' : icon
        ];

        const props = { ...n('icon', modifiers).withTestId().withClass(iconClass).props };

        return iconSrc ? (
            <Image {...props} src={iconSrc} alt={alt} />
        ) : (
            <Icon {...props} type={icon} />
        );
    };

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

    return (
        <a {...linkProps}>{renderContent}</a>
    );
};

Link.propTypes = {
    href: PropTypes.string.isRequired,
    target: PropTypes.oneOf([TARGET_BLANK]),
    theme: PropTypes.oneOf(LINK_THEMES),
    icon: PropTypes.oneOf(allowedTypes),
    iconSrc: PropTypes.string,
    alt: PropTypes.string,
    iconClass: PropTypes.string,
    iconPosition: PropTypes.oneOf([LEFT.value, RIGHT.value]),
    hiddenText: PropTypes.bool
};

Link.defaultProps = {
    target: null,
    theme: null,
    icon: null,
    iconSrc: null,
    alt: null,
    iconClass: '',
    iconPosition: LEFT.value,
    hiddenText: false
};

export default Link;
