import React, {useEffect, useRef} from 'react';
import {Button, Dialog, DialogContent, DialogTitle} from '@tryghost/shade/components';
import {DirtyConfirmDialog, useDirtyConfirmation} from '@tryghost/shade/patterns';
import {type OkProps} from '@tryghost/admin-x-framework/hooks';
import {cn} from '@tryghost/shade/utils';

interface EmailDesignModalProps {
    open: boolean;
    title: string;
    preview: React.ReactNode;
    sidebar: React.ReactNode;
    dirty?: boolean;
    isLoading?: boolean;
    okProps?: Pick<OkProps, 'disabled' | 'label' | 'variant'>;
    onSave: () => void;
    onClose: () => void;
    afterClose?: () => void;
    testId?: string;
}

const EmailDesignModal: React.FC<EmailDesignModalProps> = ({
    open,
    title,
    preview,
    sidebar,
    dirty = false,
    isLoading = false,
    okProps,
    onSave,
    onClose,
    afterClose,
    testId
}) => {
    const onSaveRef = useRef(onSave);
    const prevOpenRef = useRef(open);
    const {confirm, dialogProps} = useDirtyConfirmation();

    useEffect(() => {
        onSaveRef.current = onSave;
    }, [onSave]);

    useEffect(() => {
        if (prevOpenRef.current && !open) {
            afterClose?.();
        }

        prevOpenRef.current = open;
    }, [afterClose, open]);

    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            if ((e.metaKey || e.ctrlKey) && e.key === 's') {
                e.preventDefault();
                onSaveRef.current();
            }
        };
        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, []);

    const handleClose = () => {
        confirm(dirty, onClose);
    };

    return (
        <Dialog
            open={open}
            onOpenChange={(isOpen) => {
                if (!isOpen) {
                    handleClose();
                }
            }}
        >
            <DialogContent
                aria-describedby={undefined}
                className={cn(
                    'top-[50%] left-[50%] h-[calc(100vh-8vmin)] w-[calc(100vw-8vmin)] max-w-none translate-[-50%] gap-0 overflow-hidden p-0'
                )}
                data-testid={testId}
                onEscapeKeyDown={(event) => {
                    event.preventDefault();
                    event.stopPropagation();
                    handleClose();
                }}
            >
                <div className="flex h-full min-h-0">
                    <div className="hidden min-h-0 flex-1 flex-col bg-gray-50 dark:bg-black [@media(min-width:801px)]:flex">
                        <div className="flex min-h-0 flex-1 items-center justify-center p-8">
                            {preview}
                        </div>
                    </div>

                    <div className="flex min-h-0 w-full flex-col border-l border-gray-200 dark:border-gray-900 [@media(min-width:801px)]:w-[400px] [@media(min-width:801px)]:shrink-0">
                        <div className="flex items-center justify-between px-6 py-5">
                            <DialogTitle>{title}</DialogTitle>
                            <div className="flex items-center gap-2">
                                <Button className='font-semibold' type='button' variant='ghost' onClick={() => handleClose()}>Close</Button>
                                <Button
                                    disabled={isLoading || okProps?.disabled}
                                    type='button'
                                    variant={okProps?.variant}
                                    onClick={onSave}
                                >
                                    {okProps?.label || 'Save'}
                                </Button>
                            </div>
                        </div>
                        {sidebar}
                    </div>
                </div>
            </DialogContent>
            <DirtyConfirmDialog testId='welcome-email-dirty-confirm-modal' {...dialogProps} />
        </Dialog>
    );
};

export default EmailDesignModal;
