'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import {Alert as BSAlert, Overlay} from 'react-bootstrap';
import EventBus from '../utils/EventBus';
import {getConfig, constants} from '../../utils';

const DISABLE_DISMISSIBLE_ALERT = 0;
const DEFAULT_DURATION = 3;

export class DismissibleAlert extends React.Component<any, any> {
    static propTypes = {
        testAutomationId: PropTypes.string,
        overlayProps: PropTypes.object,
        delayInterval: PropTypes.number,
        message: PropTypes.shape({
            text: PropTypes.string.isRequired
        }).isRequired,
        onShow: PropTypes.func,
        onHide: PropTypes.func
    };

    static defaultProps = {
        testAutomationId: 'dismissibleAlert',
        overlayProps: {},
        delayInterval: null,
        onShow: null,
        onHide: null,
        message: {
            text: ''
        }
    };

    delayTimeout: any;

    constructor(props, context) {
        super(props, context);
        this.state = {
            show: props.message.text !== '',
            message: {}
        };
        this.onHide = this.onHide.bind(this);
    }

    componentDidMount() {
        this.setDelayTimeout();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.message !== this.props.message) {
            this.setState(
                {
                    show: nextProps.message.text !== ''
                },
                () => {
                    if (this.state.show) {
                        this.setShown();
                    } else {
                        this.setHidden();
                    }
                    this.setDelayTimeout();
                }
            );
        }
    }

    componentWillUnmount() {
        if (this.delayTimeout) {
            clearTimeout(this.delayTimeout);
        }
        if (this.state.show) {
            this.setHidden();
        }
    }

    onHide() {
        if (this.delayTimeout) {
            clearTimeout(this.delayTimeout);
        }
        this.setState(
            {
                show: false,
                message: {}
            },
            this.setHidden
        );
    }

    setShown = () => {
        EventBus.emit(constants.onTestAutomationAwait);
        if (this.props.onShow) {
            this.props.onShow();
        }
    };

    setHidden = () => {
        EventBus.emit(constants.onTestAutomationReady);
        if (this.props.onHide) {
            this.props.onHide();
        }
    };

    setDelayTimeout() {
        if (!this.state.show) {
            return;
        }
        setTimeout(() => {
            this.setState({
                message: this.props.message
            });
        }, 10);

        if (this.delayTimeout) {
            clearTimeout(this.delayTimeout);
        }
        this.delayTimeout = setTimeout(this.onHide, this.getDelayInterval());
    }

    getDelayInterval() {
        let {dismissibleAlertDuration = DEFAULT_DURATION} = getConfig();
        return this.props.delayInterval === null
            ? dismissibleAlertDuration * 1000
            : this.props.delayInterval;
    }

    render() {
        if (this.getDelayInterval() === DISABLE_DISMISSIBLE_ALERT) {
            return null;
        }
        let {overlayProps, testAutomationId} = this.props;
        return (
            <Overlay
                show={this.state.show}
                onHide={this.onHide}
                rootClose={false}
                placement="bottom"
                container={document.body}
                {...overlayProps}>
                <div className="bootstrap-rc">
                    <div className="rc-popup-dismissible-alert">
                        <BSAlert
                            className="rc-popup-dismissible-alert-content alert-dismissible"
                            data-test-automation-id={testAutomationId}>
                            <button
                                aria-hidden="true"
                                ref="dismissCloseButton"
                                className="close"
                                data-dismiss="alert"
                                onClick={this.onHide}
                                data-test-automation-id="closeButton">
                                <span aria-hidden="true">{'\xD7'}</span>
                            </button>
                            <span data-test-automation-id="dismissibleAlertText">
                                {this.state.message.text || ''}
                            </span>
                        </BSAlert>
                    </div>
                </div>
            </Overlay>
        );
    }
}
