import React, { createContext, useContext, useState, useCallback, useMemo, useEffect } from 'react';
import PreviewZoomOverlay from '../detail/PreviewZoomOverlay';
import type { Document } from '../types/documents';
import type { Identifier } from '../types/identifiers';

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

const PreviewContext = createContext<PreviewContextType | null>(null);

export const usePreviewContext = () => {
    const context = useContext(PreviewContext);
    if (!context) {
        throw new Error('usePreviewContext must be used within a PreviewProvider');
    }
    return context;
};

interface PreviewProviderProps {
    children: React.ReactNode;
    ensureDownloadUrl?: (docId: Identifier) => Promise<any>;
}

export const PreviewProvider: React.FC<PreviewProviderProps> = ({ children, ensureDownloadUrl }) => {
    const [previewDoc, setPreviewDoc] = useState<Document | null>(null);
    const [previewUrl, setPreviewUrl] = useState<string | null>(null);

    const openPreview = useCallback((doc: Document) => {
        setPreviewDoc(doc);
    }, []);

    const closePreview = useCallback(() => {
        setPreviewDoc(null);
        setPreviewUrl(null);
    }, []);

    useEffect(() => {
        if (!previewDoc) {
            setPreviewUrl(null);
            return;
        }

        let cancelled = false;
        if (ensureDownloadUrl) {
            ensureDownloadUrl(previewDoc.id)
                .then((entry) => {
                    if (!cancelled && entry?.url) {
                        setPreviewUrl(entry.url);
                    }
                })
                .catch(() => {
                    if (!cancelled) {
                        setPreviewUrl(null);
                    }
                });
        }

        return () => {
            cancelled = true;
        };
    }, [previewDoc, ensureDownloadUrl]);

    const overlayDocument = useMemo(() => {
        if (!previewDoc || !previewUrl) {
            return previewDoc;
        }
        return {
            ...previewDoc,
            documentLink: {
                url: previewUrl,
                alt: previewDoc.title,
                mimeType: previewDoc.mime_type,
            },
        };
    }, [previewDoc, previewUrl]);

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

    return (
        <PreviewContext.Provider value={value}>
            {children}
            <PreviewZoomOverlay
                open={Boolean(previewUrl)}
                onClose={closePreview}
                document={overlayDocument}
            />
        </PreviewContext.Provider>
    );
};
