// This is the layer that executes on the official react-modal component
// This is accessed by
// - modal-instance.jsx (for React usage)
// - modal-init.js (for vanilla usage)
// https://style.23andme.com/components/#modals-section for more information

import React from 'react';
import PropTypes from 'prop-types';
import ReactModal from 'react-modal';
import { v4 as uuid } from 'uuid';

ReactModal.setAppElement('body');

class Modal extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            hasScrolled: false,
        };
        this.handleScroll = this.handleScroll.bind(this);
        this.closeModal = this.props.closeModal.bind(this);
        this.ctaPosition = props.ctaPosition ? `dismiss-cta-${props.ctaPosition}` : '';
        this.uid = uuid();
    }

    classString() {
        let defaultClasses = 'sd-modal sd-elevation-2';
        if (this.props.alternateModal) {
            defaultClasses += ` sd-modal-${this.props.alternateModal}`;
            if (this.props.useWhiteDismissButton) {
                defaultClasses += ` mod-modal-white-dismiss`;
            }
        }
        return defaultClasses;
    }

    overlayClassString() {
        let overlayDefaultClasses = 'sd-modal-overlay';
        if (this.props.alternateModal === 'interstitial') {
            overlayDefaultClasses += ` mod-overlay-dark`;
        }
        return overlayDefaultClasses;
    }

    handleScroll() {
        const wrapper = document.querySelector('.sd-modal-wrapper');
        if (wrapper.scrollTop > 0 && !this.state.hasScrolled) {
            this.setState({ hasScrolled: true });
        } else if (wrapper.scrollTop === 0 && this.state.hasScrolled) {
            this.setState({ hasScrolled: false });
        }
    }

    render() {
        return (
            <ReactModal
                isOpen={this.props.isVisible}
                onRequestClose={this.props.closeModal}
                className={this.classString()}
                overlayClassName={this.overlayClassString()}
                bodyOpenClassName="sd-modal-body"
                contentLabel={this.props.contentLabel}
                aria={{
                    describedby: `modal-contents-${this.uid}`
                    modal: true,
                }}
            >
                <button
                    className={`sd-unbutton sd-modal-dismiss-top ${this.state.hasScrolled ? 'mod-scrolled' : ''}`}
                    onClick={this.props.closeModal}
                    aria-label="Close"
                />
                <div id={`modal-contents-${this.uid}`} className="sd-modal-wrapper" onScroll={this.handleScroll}>
                    {this.props.contents && (
                        <div
                            // Careful here!
                            dangerouslySetInnerHTML={{
                                __html: this.props.contents,
                            }}
                        />
                    )}
                    {this.props.children && this.props.children}

                    {this.props.includeDismissCta && (
                        <div className={`sd-modal-dismiss-cta-container ${this.ctaPosition}`}>
                            <button
                                className={`sd-button sd-modal-dismiss-cta ${this.props.extraClasses}`}
                                onClick={this.props.closeModal}
                            >
                                {this.props.dismissText}
                            </button>
                        </div>
                    )}
                </div>
            </ReactModal>
        );
    }
}

Modal.defaultProps = {
    contents: '',
    dismissText: 'Close',
    ctaPosition: '',
    extraClasses: '',
    includeDismissCta: true,
    alternateModal: '',
    useWhiteDismissButton: false,
    contentLabel: 'Modal',
};

Modal.propTypes = {
    isVisible: PropTypes.bool.isRequired,
    closeModal: PropTypes.func.isRequired,
    contents: PropTypes.string,
    dismissText: PropTypes.string,
    ctaPosition: PropTypes.string,
    extraClasses: PropTypes.string,
    includeDismissCta: PropTypes.bool,
    alternateModal: PropTypes.string,
    useWhiteDismissButton: PropTypes.bool,
    contentLabel: PropTypes.string,
};

export default Modal;
