import React, {useLayoutEffect, useRef, PropsWithChildren, KeyboardEvent} from 'react';
import cls from 'classnames';
import {Breadcrumb} from '@core0/breadcrumb';
import {renderForeground} from '@core0/utils';
import {RoundButton} from '@core0/round-button';
import {Transition, TransitionType} from '@core0/transition';
import {Backdrop} from '@core0/backdrop';
import cn from './modal.module.styl';

export interface ModalProps<Output> extends Partial<ModalStyles> {
    onClose?(output?: Output): void;
    canBackdropCloseModal?: boolean;
    canEscapeCloseModal?: boolean;
    hasCloseButton?: boolean;
    locations?: string[];
}

export interface ModalStyles {
    backdropBackground: string;
    backdropOpacity: string;
    contentContainerMaxWidth: string;
    contentContainerWidth: string;
    contentContainerHeight: string;
    contentContainerMaxHeight: string;
    transitionType: TransitionType;
    zIndex: number;
}

export function Modal<Output>(props: PropsWithChildren<ModalProps<Output>>): JSX.Element {
    const {
        onClose = () => {},
        canBackdropCloseModal = false,
        canEscapeCloseModal = false,
        hasCloseButton = false,
        backdropBackground = 'white',
        backdropOpacity = '0.98',
        contentContainerWidth = 'auto',
        contentContainerMaxWidth = '100%',
        contentContainerHeight = 'auto',
        contentContainerMaxHeight = '100%',
        transitionType = 'zoom-in-inward',
        zIndex,
        locations = [],
        children
    } = props;

    const hostElmRef = useRef<HTMLDivElement>(null);
    const backdropElmRef = useRef<HTMLDivElement>(null);

    /*
     ****************************************
     * Effect Hooks
     ****************************************
     */
    useLayoutEffect(() => {
        const requestId = requestAnimationFrame(() => {
            if (backdropElmRef.current) {
                backdropElmRef.current.style.opacity = backdropOpacity;
            }
        });
        return () => cancelAnimationFrame(requestId);
    }, []);

    useLayoutEffect(() => {
        hostElmRef?.current?.focus();
    }, []);

    /*
     ****************************************
     * Event Handlers
     ****************************************
     */
    function backdropClickHandler() {
        if (canBackdropCloseModal) onClose();
    }

    function closeButtonClickHandler() {
        onClose();
    }

    function hostElmKeyDownHandler(evt: KeyboardEvent) {
        if (canEscapeCloseModal && evt.key.toLowerCase() === 'escape') onClose();
    }

    return renderForeground(
        <div
            ref={hostElmRef}
            tabIndex={0}
            role="modal"
            className={cls('ffwd-modal', cn.modal)}
            style={{zIndex}}
            onKeyDown={hostElmKeyDownHandler}
        >
            <Backdrop
                ref={backdropElmRef}
                type='cover'
                className={cls(cn.backdrop, {[cn.closable]: canBackdropCloseModal})}
                background={backdropBackground}
                onClick={backdropClickHandler}
            />
            <Transition type={transitionType}>
                <Breadcrumb layers={locations} />
            </Transition>
            <Transition type={transitionType}>
                <div
                    className={cn.contentContainer}
                    style={{
                        width: contentContainerWidth,
                        maxWidth: contentContainerMaxWidth,
                        height: contentContainerHeight,
                        maxHeight: contentContainerMaxHeight
                    }}
                >
                    {children}
                </div>
            </Transition>
            <Transition in={hasCloseButton} type="zoom-in-inward">
                <RoundButton
                    inverse
                    icon="close"
                    size="large"
                    className={cn.close}
                    onClick={closeButtonClickHandler}
                />
            </Transition>
        </div>
    );
}
