import React, { useState, useCallback, useMemo, useRef } from 'react';
import PreviewZoomOverlay from './components/PreviewZoomOverlay';
import type { Document } from '../types/documents';
import type { Identifier } from '../types/identifiers';
import { createSafeContext } from '../utils/createSafeContext';

interface PreviewContextType {
    openPreview: (doc: Document) => void;
    closePreview: () => void;
}

const [PreviewContext, usePreviewContext] = createSafeContext<PreviewContextType>('Preview');

interface PreviewProviderProps {
    children: React.ReactNode;
    onNavigate?: (documentId: Identifier) => void;
}

export const PreviewProvider: React.FC<PreviewProviderProps> = ({ children, onNavigate }) => {
    const [previewDoc, setPreviewDoc] = useState<Document | null>(null);
    const lastFocusedElement = useRef<HTMLElement | null>(null);

    const openPreview = useCallback((doc: Document) => {
        if (!lastFocusedElement.current) {
            lastFocusedElement.current = document.activeElement as HTMLElement;
        }
        setPreviewDoc(doc);
    }, []);

    const closePreview = useCallback(() => {
        setPreviewDoc(null);
        if (lastFocusedElement.current) {
            lastFocusedElement.current.focus();
            lastFocusedElement.current = null;
        }
    }, []);

    const handleMaximize = useCallback(() => {
        if (previewDoc && onNavigate) {
            onNavigate(previewDoc.id);
            closePreview();
        }
    }, [previewDoc, onNavigate, closePreview]);

    const value = useMemo(() => ({
        openPreview,
        closePreview,
    }), [openPreview, closePreview]);

    return (
        <PreviewContext.Provider value={value}>
            {children}
            <PreviewZoomOverlay
                open={Boolean(previewDoc)}
                onClose={closePreview}
                onMaximize={onNavigate ? handleMaximize : undefined}
                document={previewDoc}
            />
        </PreviewContext.Provider>
    );
};

export { usePreviewContext };
