function NoteCanvas({ note, token, settings, onBack }) {
    const [contentBlocks, setContentBlocks] = useState(() => {
        // Initial layout for blocks without position
        const blocks = note.content_blocks || [];
        const allZero = blocks.every(b => !b.x_pos && !b.y_pos);
        if (allZero && blocks.length > 0) {
            return blocks.map((b, i) => ({
                ...b,
                x_pos: 50,
                y_pos: 50 + (i * 250), // Standard height + gap
                width: b.width || 400
            }));
        }
        return blocks;
    });
    const [draggedBlock, setDraggedBlock] = useState(null);
    const [expandedBlockId, setExpandedBlockId] = useState(null);
    const [expandedBlockPosition, setExpandedBlockPosition] = useState(null);
    const [extractionStatus, setExtractionStatus] = useState(note.note.extraction_completed ? 'completed' : 'pending');
    const [loading, setLoading] = useState(false);
    const [showExtractModal, setShowExtractModal] = useState(false);
    const [showTextInput, setShowTextInput] = useState(false);
    const [newTextContent, setNewTextContent] = useState('');
    const [showAudioModal, setShowAudioModal] = useState(false);
    const [audioMode, setAudioMode] = useState(null); // 'upload' or 'record'
    const [viewMode, setViewMode] = useState('canvas'); // 'canvas' or 'document'
    const [highlightedBlockId, setHighlightedBlockId] = useState(null);
    // Zoom and Pan state
    const [zoom, setZoom] = useState(1);
    const [panOffset, setPanOffset] = useState({ x: 0, y: 0 });
    const [isPanning, setIsPanning] = useState(false);
    const [panStart, setPanStart] = useState(null);

    // Canvas Drag Logic
    const handleMouseDown = (e, block) => {
        if (viewMode !== 'canvas') return;
        // prevent drag if clicking buttons inputs or links
        if (['BUTTON', 'INPUT', 'TEXTAREA', 'A'].includes(e.target.tagName)) return;

        e.preventDefault();
        setDraggedBlock({
            id: block.id,
            startX: e.clientX,
            startY: e.clientY,
            initialX: block.x_pos || 0,
            initialY: block.y_pos || 0
        });
    };

    const handleMouseMove = (e) => {
        if (!draggedBlock) return;
        const dx = e.clientX - draggedBlock.startX;
        const dy = e.clientY - draggedBlock.startY;

        setContentBlocks(blocks => blocks.map(b => {
            if (b.id === draggedBlock.id) {
                return { ...b, x_pos: draggedBlock.initialX + dx, y_pos: draggedBlock.initialY + dy };
            }
            return b;
        }));
    };

    const handleMouseUp = async () => {
        if (!draggedBlock) return;
        const block = contentBlocks.find(b => b.id === draggedBlock.id);
        if (block) {
            try {
                await fetch(`${API_URL}/notes/${note.note.id}/content/${block.id}/position`, {
                    method: 'PATCH',
                    headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                    body: JSON.stringify({ x: block.x_pos, y: block.y_pos })
                });
            } catch (err) {
                console.error('Failed to save position', err);
            }
        }
        setDraggedBlock(null);
    };

    // Zoom and Pan handlers
    const handleZoomIn = () => setZoom(z => Math.min(2, z + 0.1));
    const handleZoomOut = () => setZoom(z => Math.max(0.5, z - 0.1));
    const handleZoomReset = () => {
        setZoom(1);
        setPanOffset({ x: 0, y: 0 });
    };

    const handleWheel = (e) => {
        if (e.ctrlKey || e.metaKey) {
            e.preventDefault();
            const delta = e.deltaY * -0.001;
            setZoom(z => Math.min(2, Math.max(0.5, z + delta)));
        }
    };

    const handlePanStart = (e) => {
        if (e.button === 1 || e.shiftKey || isPanning) { // Middle mouse or Shift+drag
            setIsPanning(true);
            setPanStart({ x: e.clientX - panOffset.x, y: e.clientY - panOffset.y });
            e.preventDefault();
        }
    };

    const handlePanMove = (e) => {
        if (isPanning && panStart) {
            setPanOffset({
                x: e.clientX - panStart.x,
                y: e.clientY - panStart.y
            });
        }
    };

    const handlePanEnd = () => {
        setIsPanning(false);
        setPanStart(null);
    };

    // Keyboard shortcuts
    React.useEffect(() => {
        const handleKeyDown = (e) => {
            if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
            if (e.key === '+' || e.key === '=') handleZoomIn();
            if (e.key === '-' || e.key === '_') handleZoomOut();
            if (e.key === '0') handleZoomReset();
        };
        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, []);

    const addTextBlock = () => {
        setShowTextInput(true);
    };

    const saveTextBlock = async () => {
        if (!newTextContent.trim()) {
            setShowTextInput(false);
            setNewTextContent('');
            return;
        }
        try {
            // Smart positioning: find empty spot
            const BLOCK_WIDTH = 350, BLOCK_HEIGHT = 200, SPACING = 30, START_X = 50, START_Y = 50, GRID_COLS = 3;
            let newX = START_X, newY = START_Y;

            // Try grid positions
            outerLoop: for (let row = 0; row < 10; row++) {
                for (let col = 0; col < GRID_COLS; col++) {
                    const testX = START_X + (col * (BLOCK_WIDTH + SPACING));
                    const testY = START_Y + (row * (BLOCK_HEIGHT + SPACING));
                    const hasOverlap = contentBlocks.some(b => Math.abs(testX - (b.x_pos || 0)) < (BLOCK_WIDTH - 50) && Math.abs(testY - (b.y_pos || 0)) < (BLOCK_HEIGHT - 50));
                    if (!hasOverlap) { newX = testX; newY = testY; break outerLoop; }
                }
            }

            const response = await fetch(`${API_URL}/notes/${note.note.id}/content/text`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    content_type: 'text',
                    content_data: { text: newTextContent },
                    position: contentBlocks.length,
                    x: newX,
                    y: newY
                })
            });
            if (response.ok) {
                const data = await response.json();
                setContentBlocks([...contentBlocks, {
                    id: data.block_id,
                    content_type: 'text',
                    content_data: { text: newTextContent },
                    x_pos: newX,
                    y_pos: newY
                }]);
                setNewTextContent('');
                setShowTextInput(false);
            }
        } catch (err) {
            alert('Failed to add text block');
        }
    };

    const addFileBlock = async (file) => {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('position', contentBlocks.length);

        // Smart positioning
        const BLOCK_WIDTH = 350, BLOCK_HEIGHT = 200, SPACING = 30, START_X = 50, START_Y = 50, GRID_COLS = 3;
        let newX = START_X, newY = START_Y;
        outerLoop: for (let row = 0; row < 10; row++) {
            for (let col = 0; col < GRID_COLS; col++) {
                const testX = START_X + (col * (BLOCK_WIDTH + SPACING));
                const testY = START_Y + (row * (BLOCK_HEIGHT + SPACING));
                const hasOverlap = contentBlocks.some(b => Math.abs(testX - (b.x_pos || 0)) < (BLOCK_WIDTH - 50) && Math.abs(testY - (b.y_pos || 0)) < (BLOCK_HEIGHT - 50));
                if (!hasOverlap) { newX = testX; newY = testY; break outerLoop; }
            }
        }

        try {
            setLoading(true);
            const response = await fetch(`${API_URL}/notes/${note.note.id}/content/file`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}` },
                body: formData
            });
            if (response.ok) {
                const data = await response.json();
                setContentBlocks([...contentBlocks, {
                    id: data.block_id,
                    content_type: file.type.startsWith('image/') ? 'image' : file.type === 'application/pdf' ? 'pdf' : 'audio',
                    filename: data.filename,
                    file_id: data.file_id,
                    file_path: data.file_path,
                    x_pos: newX,
                    y_pos: newY
                }]);

                // Immediately save position
                await fetch(`${API_URL}/notes/${note.note.id}/content/${data.block_id}/position`, {
                    method: 'PATCH',
                    headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                    body: JSON.stringify({ x: newX, y: newY })
                });
            }
        } catch (err) {
            alert('Failed to upload file');
        } finally {
            setLoading(false);
        }
    };

    const addLinkBlock = async () => {
        const url = prompt('Enter URL:');
        if (!url) return;
        try {
            // Smart positioning
            const BLOCK_WIDTH = 350, BLOCK_HEIGHT = 200, SPACING = 30, START_X = 50, START_Y = 50, GRID_COLS = 3;
            let newX = START_X, newY = START_Y;
            outerLoop: for (let row = 0; row < 10; row++) {
                for (let col = 0; col < GRID_COLS; col++) {
                    const testX = START_X + (col * (BLOCK_WIDTH + SPACING));
                    const testY = START_Y + (row * (BLOCK_HEIGHT + SPACING));
                    const hasOverlap = contentBlocks.some(b => Math.abs(testX - (b.x_pos || 0)) < (BLOCK_WIDTH - 50) && Math.abs(testY - (b.y_pos || 0)) < (BLOCK_HEIGHT - 50));
                    if (!hasOverlap) { newX = testX; newY = testY; break outerLoop; }
                }
            }

            const formData = new FormData();
            formData.append('url', url);
            formData.append('position', contentBlocks.length);
            const response = await fetch(`${API_URL}/notes/${note.note.id}/content/link`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}` },
                body: formData
            });
            if (response.ok) {
                const data = await response.json();
                setContentBlocks([...contentBlocks, {
                    id: data.block_id,
                    content_type: 'link',
                    content_data: { url },
                    x_pos: newX,
                    y_pos: newY
                }]);

                await fetch(`${API_URL}/notes/${note.note.id}/content/${data.block_id}/position`, {
                    method: 'PATCH',
                    headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                    body: JSON.stringify({ x: newX, y: newY })
                });
            }
        } catch (err) {
            alert('Failed to add link');
        }
    };

    const deleteBlock = async (blockId) => {
        if (!confirm('Delete this block?')) return;
        try {
            const response = await fetch(`${API_URL}/notes/${note.note.id}/content/${blockId}`, {
                method: 'DELETE',
                headers: { 'Authorization': `Bearer ${token}` }
            });
            if (response.ok) {
                setContentBlocks(contentBlocks.filter(b => b.id !== blockId));
            }
        } catch (err) {
            alert('Failed to delete block');
        }
    };

    const extractContent = async (extractNow) => {
        try {
            setLoading(true);
            setShowExtractModal(false);
            const response = await fetch(`${API_URL}/notes/${note.note.id}/extract`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                body: JSON.stringify({ extract_now: extractNow, force: false })
            });
            const data = await response.json();
            if (extractNow) {
                setExtractionStatus('processing');
                const interval = setInterval(async () => {
                    const statusRes = await fetch(`${API_URL}/notes/${note.note.id}/extraction-status`, {
                        headers: { 'Authorization': `Bearer ${token}` }
                    });
                    const statusData = await statusRes.json();
                    if (statusData.status === 'completed') {
                        setExtractionStatus('completed');
                        clearInterval(interval);
                        alert('Extraction completed!');
                    } else if (statusData.status === 'failed') {
                        setExtractionStatus('failed');
                        clearInterval(interval);
                        alert('Extraction failed');
                    }
                }, 2000);
            } else {
                alert('Content will be extracted later');
            }
        } catch (err) {
            alert('Failed to start extraction');
        } finally {
            setLoading(false);
        }
    };

    const handleViewInCanvas = (blockId) => {
        setViewMode('canvas');
        setHighlightedBlockId(blockId);
        setTimeout(() => {
            const element = document.getElementById(`block-${blockId}`);
            if (element) {
                // Smooth scroll manually because position absolute
                element.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
            setTimeout(() => setHighlightedBlockId(null), 2000);
        }, 100);
    };

    return (
        <div style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '1rem 2rem', borderBottom: '1px solid var(--border-color)', background: 'var(--bg-primary)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
                    <button onClick={onBack} className="btn btn-secondary" style={{ padding: '0.5rem 1rem' }}>← Back</button>
                    <h2 style={{ fontSize: '1.25rem', fontWeight: '600' }}>{note.note.title}</h2>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
                    {/* View Mode Toggle */}
                    <div style={{
                        display: 'inline-flex',
                        background: 'var(--bg-secondary)',
                        borderRadius: '8px',
                        padding: '0.25rem',
                        border: '1px solid var(--border-color)'
                    }}>
                        <button
                            onClick={() => setViewMode('canvas')}
                            style={{
                                padding: '0.5rem 1rem',
                                border: 'none',
                                borderRadius: '6px',
                                background: viewMode === 'canvas' ? 'var(--primary)' : 'transparent',
                                color: viewMode === 'canvas' ? 'white' : 'var(--text-primary)',
                                fontWeight: '500',
                                cursor: 'pointer',
                                transition: 'all 0.2s',
                                fontSize: '0.875rem'
                            }}
                        >
                            RAW
                        </button>
                        <button
                            onClick={() => setViewMode('document')}
                            style={{
                                padding: '0.5rem 1rem',
                                border: 'none',
                                borderRadius: '6px',
                                background: viewMode === 'document' ? 'var(--primary)' : 'transparent',
                                color: viewMode === 'document' ? 'white' : 'var(--text-primary)',
                                fontWeight: '500',
                                cursor: 'pointer',
                                transition: 'all 0.2s',
                                fontSize: '0.875rem'
                            }}
                        >
                            Document
                        </button>
                    </div>
                    <button onClick={() => setShowExtractModal(true)} className="btn btn-primary" disabled={loading || contentBlocks.length === 0} style={{ padding: '0.5rem 1.5rem' }}>
                        {extractionStatus === 'completed' ? '✓ Extracted' : extractionStatus === 'processing' ? '⏳ Extracting...' : 'Extract Content'}
                    </button>
                </div>
            </div>
            {viewMode === 'canvas' ? (
                <>
                    <div style={{ display: 'flex', gap: '0.5rem', padding: '1rem 2rem', borderBottom: '1px solid var(--border-color)', background: 'var(--bg-secondary)', position: 'relative' }}>
                        <button onClick={addTextBlock} className="btn" style={{ padding: '0.5rem 1rem' }}>📝 Text</button>
                        <label className="btn" style={{ padding: '0.5rem 1rem', cursor: 'pointer' }}>🖼️ File<input type="file" style={{ display: 'none' }} accept="image/*,application/pdf,audio/*" onChange={(e) => { if (e.target.files[0]) addFileBlock(e.target.files[0]); }} disabled={loading} /></label>
                        <button onClick={addLinkBlock} className="btn" style={{ padding: '0.5rem 1rem' }}>🔗 Link</button>
                        <button onClick={() => setShowAudioModal(true)} className="btn" style={{ padding: '0.5rem 1rem' }}>🎤 Audio</button>
                        {note.note.canvas_enabled && <button className="btn" style={{ padding: '0.5rem 1rem' }}>✏️ Draw</button>}

                        {/* Zoom Controls - Fixed outside canvas */}
                        <div style={{
                            position: 'absolute',
                            left: '50%',
                            bottom: '-3.5rem',
                            transform: 'translateX(-50%)',
                            zIndex: 100,
                            display: 'flex',
                            gap: '0.5rem',
                            background: 'var(--card-bg)',
                            padding: '0.5rem',
                            borderRadius: '8px',
                            boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
                            border: '1px solid var(--border-color)'
                        }}>
                            <button onClick={handleZoomOut} className="btn" style={{ padding: '0.25rem 0.5rem', fontSize: '1.25rem', minWidth: '32px' }} title="Zoom Out (-)">
                                −
                            </button>
                            <div style={{ display: 'flex', alignItems: 'center', padding: '0 0.5rem', fontSize: '0.875rem', fontWeight: '600', minWidth: '50px', justifyContent: 'center' }}>
                                {Math.round(zoom * 100)}%
                            </div>
                            <button onClick={handleZoomIn} className="btn" style={{ padding: '0.25rem 0.5rem', fontSize: '1.25rem', minWidth: '32px' }} title="Zoom In (+)">
                                +
                            </button>
                            <button onClick={handleZoomReset} className="btn" style={{ padding: '0.25rem 0.75rem', fontSize: '0.75rem' }} title="Reset (0)">
                                ⟲ Reset
                            </button>
                        </div>
                    </div>
                    <div
                        style={{
                            flex: 1,
                            overflow: 'auto',
                            padding: '2rem',
                            background: 'var(--bg-primary)',
                            position: 'relative'
                        }}
                        onMouseMove={(e) => { handleMouseMove(e); handlePanMove(e); }}
                        onMouseUp={() => { handleMouseUp(); handlePanEnd(); }}
                        onMouseLeave={() => { handleMouseUp(); handlePanEnd(); }}
                        onMouseDown={handlePanStart}
                        onWheel={handleWheel}
                    >

                        {showTextInput && (
                            <div style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: '80%', maxWidth: '600px', background: 'var(--card-bg)', border: '2px solid var(--primary)', borderRadius: '8px', padding: '1rem', zIndex: 100, boxShadow: '0 4px 20px rgba(0,0,0,0.2)' }}>
                                <textarea
                                    value={newTextContent}
                                    onChange={(e) => setNewTextContent(e.target.value)}
                                    placeholder="Type your text here..."
                                    style={{ width: '100%', minHeight: '150px', border: 'none', outline: 'none', fontSize: '1rem', resize: 'vertical', background: 'transparent', color: 'var(--text-primary)' }}
                                    autoFocus
                                />
                                <div style={{ display: 'flex', gap: '0.5rem', marginTop: '1rem' }}>
                                    <button onClick={saveTextBlock} className="btn btn-primary">Save</button>
                                    <button onClick={() => { setShowTextInput(false); setNewTextContent(''); }} className="btn btn-secondary">Cancel</button>
                                </div>
                            </div>
                        )}

                        {/* Audio Modal */}
                        {showAudioModal && (
                            <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.5)', zIndex: 150, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                                {audioMode === null ? (
                                    // Mode selection
                                    <div style={{ background: 'var(--card-bg)', borderRadius: '12px', padding: '2rem', maxWidth: '400px', width: '90%' }}>
                                        <h3 style={{ marginBottom: '1.5rem', fontSize: '1.25rem' }}>🎤 Add Audio</h3>
                                        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
                                            <button
                                                onClick={() => setAudioMode('upload')}
                                                className="btn btn-primary"
                                                style={{ padding: '1rem', fontSize: '1rem', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '0.5rem' }}
                                            >
                                                📁 Upload Audio File
                                            </button>
                                            <button
                                                onClick={() => setAudioMode('record')}
                                                className="btn btn-primary"
                                                style={{ padding: '1rem', fontSize: '1rem', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '0.5rem' }}
                                            >
                                                🎙️ Record Live
                                            </button>
                                            <button
                                                onClick={() => setShowAudioModal(false)}
                                                className="btn btn-secondary"
                                                style={{ padding: '0.75rem' }}
                                            >
                                                ✖️ Cancel
                                            </button>
                                        </div>
                                    </div>
                                ) : audioMode === 'upload' ? (
                                    // Upload mode
                                    <div style={{ background: 'var(--card-bg)', borderRadius: '12px', padding: '2rem', maxWidth: '500px', width: '90%' }}>
                                        <h3 style={{ marginBottom: '1rem', fontSize: '1.25rem' }}>📁 Upload Audio File</h3>
                                        <input
                                            type="file"
                                            accept=".mp3,.wav,.m4a,.ogg,.flac,.aac,.wma"
                                            onChange={async (e) => {
                                                const file = e.target.files[0];
                                                if (!file) return;

                                                try {
                                                    setLoading(true);
                                                    const formData = new FormData();
                                                    formData.append('file', file);
                                                    formData.append('position', contentBlocks.length);

                                                    const response = await fetch(`${API_URL}/notes/${note.note.id}/content/audio`, {
                                                        method: 'POST',
                                                        headers: { 'Authorization': `Bearer ${token}` },
                                                        body: formData
                                                    });

                                                    if (response.ok) {
                                                        const data = await response.json();
                                                        const lastBlock = contentBlocks[contentBlocks.length - 1];
                                                        const newY = lastBlock ? (lastBlock.y_pos || 0) + 250 : 50;

                                                        const newBlock = {
                                                            id: data.block_id,
                                                            content_type: 'audio',
                                                            file_id: data.file_id,
                                                            filename: data.filename,
                                                            file_path: data.file_path,
                                                            x_pos: 50,
                                                            y_pos: newY
                                                        };

                                                        setContentBlocks([...contentBlocks, newBlock]);

                                                        // Update position
                                                        await fetch(`${API_URL}/notes/${note.note.id}/content/${data.block_id}/position`, {
                                                            method: 'PATCH',
                                                            headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                                                            body: JSON.stringify({ x: 50, y: newY })
                                                        });

                                                        setShowAudioModal(false);
                                                        setAudioMode(null);
                                                    } else {
                                                        const error = await response.json();
                                                        alert(error.detail || 'Upload failed');
                                                    }
                                                } catch (err) {
                                                    console.error('Audio upload error:', err);
                                                    alert('Failed to upload audio: ' + err.message);
                                                } finally {
                                                    setLoading(false);
                                                }
                                            }}
                                            style={{ width: '100%', marginBottom: '1rem', padding: '0.5rem' }}
                                        />
                                        <p style={{ fontSize: '0.85rem', color: 'var(--text-secondary)', marginBottom: '1rem' }}>
                                            Supported: MP3, WAV, M4A, OGG, FLAC, AAC, WMA (Max: 15MB)
                                        </p>
                                        <button
                                            onClick={() => setAudioMode(null)}
                                            className="btn btn-secondary"
                                            style={{ width: '100%' }}
                                        >
                                            ← Back
                                        </button>
                                    </div>
                                ) : (
                                    // Record mode
                                    <div style={{ background: 'var(--card-bg)', borderRadius: '12px', padding: '0', maxWidth: '550px', width: '90%', overflow: 'hidden' }}>
                                        {typeof AudioRecorder !== 'undefined' ? (
                                            <AudioRecorder
                                                noteId={note.note.id}
                                                onRecordingComplete={(data) => {
                                                    const lastBlock = contentBlocks[contentBlocks.length - 1];
                                                    const newY = lastBlock ? (lastBlock.y_pos || 0) + 250 : 50;

                                                    const newBlock = {
                                                        id: data.block_id,
                                                        content_type: 'audio',
                                                        file_id: data.file_id,
                                                        filename: data.filename,
                                                        file_path: data.file_path,
                                                        x_pos: 50,
                                                        y_pos: newY
                                                    };

                                                    setContentBlocks([...contentBlocks, newBlock]);

                                                    fetch(`${API_URL}/notes/${note.note.id}/content/${data.block_id}/position`, {
                                                        method: 'PATCH',
                                                        headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
                                                        body: JSON.stringify({ x: 50, y: newY })
                                                    });

                                                    setShowAudioModal(false);
                                                    setAudioMode(null);
                                                }}
                                                onCancel={() => setAudioMode(null)}
                                            />
                                        ) : (
                                            <div style={{ padding: '2rem', textAlign: 'center' }}>
                                                <p>AudioRecorder component not loaded. Please refresh the page.</p>
                                                <button onClick={() => setAudioMode(null)} className="btn" style={{ marginTop: '1rem' }}>Back</button>
                                            </div>
                                        )}
                                    </div>
                                )}
                            </div>
                        )}

                        {contentBlocks.length === 0 && !showTextInput ? (
                            <div style={{ textAlign: 'center', padding: '4rem 2rem', color: 'var(--text-secondary)' }}>
                                <p style={{ fontSize: '1.25rem', marginBottom: '1rem' }}>Empty canvas</p>
                                <p>Add text, upload files, or add links to start building your note</p>
                            </div>
                        ) : (
                            <div style={{
                                position: 'relative',
                                minHeight: '2000px',
                                minWidth: '2000px',
                                backgroundImage: 'radial-gradient(var(--border-color) 1px, transparent 1px)',
                                backgroundSize: `${20 * zoom}px ${20 * zoom}px`,
                                transform: `scale(${zoom}) translate(${panOffset.x / zoom}px, ${panOffset.y / zoom}px)`,
                                transformOrigin: 'top left',
                                transition: isPanning ? 'none' : 'transform 0.1s ease-out',
                                cursor: isPanning ? 'grabbing' : 'default'
                            }}>
                                {contentBlocks.map((block) => (
                                    <>
                                        {/* Backdrop for expanded block */}
                                        {expandedBlockId === block.id && (
                                            <div
                                                onClick={() => setExpandedBlockId(null)}
                                                style={{
                                                    position: 'fixed',
                                                    top: 0,
                                                    left: 0,
                                                    right: 0,
                                                    bottom: 0,
                                                    background: 'rgba(0, 0, 0, 0.6)',
                                                    zIndex: 9998,
                                                    cursor: 'pointer'
                                                }}
                                            />
                                        )}
                                        <div
                                            key={block.id}
                                            id={`block-${block.id}`}
                                            onMouseDown={(e) => expandedBlockId === block.id ? null : handleMouseDown(e, block)}
                                            style={{
                                                position: expandedBlockId === block.id ? 'fixed' : 'absolute',
                                                left: block.x_pos || 0,
                                                top: block.y_pos || 0,
                                                transform: highlightedBlockId === block.id ? 'scale(1.02)' : 'scale(1)',
                                                width: expandedBlockId === block.id ? 'auto' : (block.content_type === 'text' ? '300px' : '250px'),
                                                minWidth: expandedBlockId === block.id ? '400px' : 'auto',
                                                height: expandedBlockId === block.id ? 'auto' : '200px',
                                                maxWidth: expandedBlockId === block.id ? '700px' : '300px',
                                                maxHeight: expandedBlockId === block.id ? 'calc(100vh - 4rem)' : '200px',
                                                overflow: expandedBlockId === block.id ? 'auto' : 'hidden',
                                                cursor: expandedBlockId === block.id ? 'default' : 'grab',
                                                transition: draggedBlock && draggedBlock.id === block.id ? 'none' : 'all 0.3s ease',
                                                boxShadow: expandedBlockId === block.id ? '0 20px 60px rgba(0,0,0,0.5)' : (highlightedBlockId === block.id ? '0 0 0 3px var(--primary)' : '0 2px 8px rgba(0,0,0,0.1)'),
                                                borderRadius: '12px',
                                                zIndex: expandedBlockId === block.id ? 9999 : (draggedBlock && draggedBlock.id === block.id ? 100 : (block.z_index || 1)),
                                                background: expandedBlockId === block.id ? 'rgba(255, 255, 255, 0.95)' : 'var(--card-bg)',
                                                opacity: expandedBlockId === block.id ? 1 : (draggedBlock && draggedBlock.id === block.id ? 0.8 : 1),
                                                display: 'flex',
                                                flexDirection: 'column'
                                            }}
                                        >
                                            <div style={{ flex: 1, overflow: 'auto' }}>
                                                <ContentBlock block={block} onDelete={() => deleteBlock(block.id)} />
                                            </div>
                                            <button
                                                onClick={(e) => {
                                                    e.stopPropagation();
                                                    if (expandedBlockId === block.id) {
                                                        setExpandedBlockId(null);
                                                        setExpandedBlockPosition(null);
                                                    } else {
                                                        setExpandedBlockId(block.id);
                                                        setExpandedBlockPosition({ x: block.x_pos, y: block.y_pos });
                                                    }
                                                }}
                                                style={{
                                                    width: '100%',
                                                    background: 'var(--bg-secondary)',
                                                    border: 'none',
                                                    borderTop: '1px solid var(--border-color)',
                                                    padding: '0.25rem',
                                                    fontSize: '0.75rem',
                                                    cursor: 'pointer',
                                                    color: 'var(--primary)',
                                                    fontWeight: '600'
                                                }}
                                            >
                                                {expandedBlockId === block.id ? '🔽 Collapse' : '🔼 Expand'}
                                            </button>
                                        </div>
                                    </>
                                ))}
                            </div>
                        )}
                    </div>
                </>
            ) : (
                <div style={{ flex: 1, overflow: 'auto', background: 'var(--bg-primary)' }}>
                    <DocumentView
                        note={note}
                        contentBlocks={contentBlocks}
                        onViewInCanvas={handleViewInCanvas}
                    />
                </div>
            )}
            {showExtractModal && (
                <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000 }} onClick={() => setShowExtractModal(false)}>
                    <div style={{ background: 'var(--bg-primary)', padding: '2rem', borderRadius: '12px', maxWidth: '400px', width: '90%' }} onClick={(e) => e.stopPropagation()}>
                        <h3 style={{ marginBottom: '1rem' }}>Extract Content</h3>
                        <p style={{ color: 'var(--text-secondary)', marginBottom: '1.5rem' }}>AI will extract text from images, transcribe audio, and summarize all content.</p>
                        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
                            <button onClick={() => extractContent(true)} className="btn btn-primary" style={{ width: '100%', padding: '0.75rem' }}>Extract Now</button>
                            {settings.store_original_files && <button onClick={() => extractContent(false)} className="btn btn-secondary" style={{ width: '100%', padding: '0.75rem' }}>Extract Later</button>}
                            <button onClick={() => setShowExtractModal(false)} className="btn" style={{ width: '100%', padding: '0.75rem' }}>Cancel</button>
                        </div>
                        {!settings.store_original_files && <p style={{ fontSize: '0.875rem', color: 'var(--text-secondary)', marginTop: '1rem', fontStyle: 'italic' }}>Note: Original files will be deleted after extraction (storage is disabled)</p>}
                    </div>
                </div>
            )}
        </div>
    );
}

// Export to global scope
window.NoteCanvas = NoteCanvas;
