import * as React from 'react';
import classnames from 'classnames';

import {scrollElementIntoView} from '../utils/functions';
import {Block} from './Block';
import {Icon} from './Icon';
import lang from '../../lang/common/index-en_US';

type InfoCardProps = {
    title?: React.ReactNode;
    tipOffset?: number | string;
    shouldScrollIntoView?: boolean;
    testAutomationId?: string;
    onClose?: React.DOMAttributes<HTMLButtonElement>['onClick'];
    closeLabel?: string;
};

export class InfoCard extends React.PureComponent<InfoCardProps> {
    static calculateTipPositionWithColumns(index: number, columns: number) {
        return (100 / columns) * ((index % columns) + 0.5);
    }

    static calculateTipPositionByOffset(percent: number) {
        const correction = 0.5;

        return Math.max(correction, Math.min(percent + 0.5, 100 - correction));
    }

    static defaultProps = {
        testAutomationId: 'infoCard',
        shouldScrollIntoView: false,
        get closeLabel() {
            return lang.CLOSE;
        }
    };

    private ref = null;

    getNodeRef = element => {
        if (this.ref !== element && element) {
            const {shouldScrollIntoView} = this.props;

            if (shouldScrollIntoView) {
                scrollElementIntoView(element);
            }
        }

        this.ref = element;
    };

    hasCloseButton() {
        const {onClose} = this.props;

        return typeof onClose === 'function';
    }

    hasTip() {
        const {tipOffset} = this.props;

        return typeof tipOffset === 'number' || typeof tipOffset === 'string';
    }

    renderTip() {
        const {tipOffset} = this.props;

        if (!this.hasTip()) {
            return null;
        }

        if (typeof tipOffset === 'number') {
            return <div style={{left: `${tipOffset}%`}} className="rc-info-card__tip" />;
        }

        if (typeof tipOffset === 'string') {
            return <div style={{left: tipOffset}} className="rc-info-card__tip" />;
        }

        return null;
    }

    renderTitle() {
        const {title} = this.props;

        if (!title) {
            return null;
        }

        const className = classnames('rc-info-card__title', {
            'rc-info-card__title--with-close': this.hasCloseButton()
        });

        return (
            <div className={className} data-test-automation-id="title">
                <Block addTopOffset addHorizontalOffset>
                    {title}
                </Block>
            </div>
        );
    }

    renderCloseButton() {
        if (!this.hasCloseButton()) {
            return null;
        }

        const {onClose, closeLabel} = this.props;

        return (
            <button
                data-test-automation-id="closeButton"
                className="rc-info-card__close"
                onClick={onClose}>
                <Icon name="close" />
                <span className="sr-only">{closeLabel}</span>
            </button>
        );
    }

    renderContent() {
        const {children, title} = this.props;

        const className = classnames('rc-info-card__content', {
            'rc-info-card__content--with-close': !title && this.hasCloseButton()
        });

        return (
            <div className={className} data-test-automation-id="infoCardChildren">
                {children}
            </div>
        );
    }

    render() {
        const {testAutomationId} = this.props;

        const className = classnames('rc-info-card', {
            'rc-info-card--with-tip': this.hasTip()
        });

        return (
            <div
                ref={this.getNodeRef}
                className={className}
                data-test-automation-id={testAutomationId}>
                {this.renderTip()}
                {this.renderTitle()}
                {this.renderCloseButton()}
                {this.renderContent()}
            </div>
        );
    }
}
