"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CollaborativeCanvas = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * Collaborative Canvas - Multi-user real-time collaborative editing component
 * Features: Shared cursors, live editing, conflict resolution, presence awareness
 */
const react_1 = require("react");
const useRealtimeCollaboration_1 = require("../../hooks/useRealtimeCollaboration");
const CollaborativeCanvas = ({ canvasId, initialElements = [], width = 1200, height = 800, backgroundColor = '#ffffff', gridSize = 20, enableGrid = true, enableSnapping = true, enableVoiceChat = false, enableVideoChat = false, enableScreenShare = false, enableFileSharing = false, maxUsers = 10, onElementsChanged, onUserJoined, onUserLeft, className = '', style = {} }) => {
    // Canvas state
    const [canvasState, setCanvasState] = (0, react_1.useState)({
        elements: initialElements,
        selectedElements: [],
        clipboard: [],
        history: {
            past: [],
            present: initialElements,
            future: []
        },
        viewport: { x: 0, y: 0, zoom: 1 },
        gridEnabled: enableGrid,
        snapToGrid: enableSnapping,
        gridSize
    });
    const [tool, setTool] = (0, react_1.useState)('select');
    const [isDrawing, setIsDrawing] = (0, react_1.useState)(false);
    const [dragStart, setDragStart] = (0, react_1.useState)(null);
    const [currentElement, setCurrentElement] = (0, react_1.useState)(null);
    // Refs
    const canvasRef = (0, react_1.useRef)(null);
    const svgRef = (0, react_1.useRef)(null);
    const lastMousePosRef = (0, react_1.useRef)({ x: 0, y: 0 });
    // Advanced collaboration with all features
    const collaboration = (0, useRealtimeCollaboration_1.useAdvancedCollaboration)({
        enabled: true,
        conversationId: canvasId,
        enableVoiceChat,
        enableVideoChat,
        enableScreenShare,
        enableFileSharing,
        onUserJoined: (user) => {
            console.log(`👤 User joined: ${user.name}`);
            onUserJoined?.(user);
        },
        onUserLeft: (userId) => {
            console.log(`👤 User left: ${userId}`);
            onUserLeft?.(userId);
        },
        onEventReceived: (event) => {
            handleCollaborationEvent(event);
        }
    });
    // Handle collaboration events
    const handleCollaborationEvent = (0, react_1.useCallback)((event) => {
        switch (event.type) {
            case 'canvas-element-added':
                addElement(event.data.element, false);
                break;
            case 'canvas-element-updated':
                updateElement(event.data.element, false);
                break;
            case 'canvas-element-deleted':
                deleteElement(event.data.elementId, false);
                break;
            case 'canvas-viewport-changed':
                updateViewport(event.data.viewport, false);
                break;
            case 'canvas-selection-changed':
                // Show other users' selections
                break;
        }
    }, []);
    // Add element to canvas
    const addElement = (0, react_1.useCallback)((element, broadcast = true) => {
        setCanvasState(prev => {
            const newElements = [...prev.elements, element];
            const newState = {
                ...prev,
                elements: newElements,
                history: {
                    past: [...prev.history.past, prev.history.present],
                    present: newElements,
                    future: []
                }
            };
            onElementsChanged?.(newElements);
            return newState;
        });
        if (broadcast) {
            collaboration.broadcastEvent({
                type: 'canvas-element-added',
                data: { element }
            });
        }
    }, [onElementsChanged, collaboration]);
    // Update element
    const updateElement = (0, react_1.useCallback)((updatedElement, broadcast = true) => {
        setCanvasState(prev => {
            const newElements = prev.elements.map(el => el.id === updatedElement.id ? updatedElement : el);
            const newState = {
                ...prev,
                elements: newElements,
                history: {
                    past: [...prev.history.past, prev.history.present],
                    present: newElements,
                    future: []
                }
            };
            onElementsChanged?.(newElements);
            return newState;
        });
        if (broadcast) {
            collaboration.broadcastEvent({
                type: 'canvas-element-updated',
                data: { element: updatedElement }
            });
        }
    }, [onElementsChanged, collaboration]);
    // Delete element
    const deleteElement = (0, react_1.useCallback)((elementId, broadcast = true) => {
        setCanvasState(prev => {
            const newElements = prev.elements.filter(el => el.id !== elementId);
            const newState = {
                ...prev,
                elements: newElements,
                selectedElements: prev.selectedElements.filter(id => id !== elementId),
                history: {
                    past: [...prev.history.past, prev.history.present],
                    present: newElements,
                    future: []
                }
            };
            onElementsChanged?.(newElements);
            return newState;
        });
        if (broadcast) {
            collaboration.broadcastEvent({
                type: 'canvas-element-deleted',
                data: { elementId }
            });
        }
    }, [onElementsChanged, collaboration]);
    // Update viewport
    const updateViewport = (0, react_1.useCallback)((viewport, broadcast = true) => {
        setCanvasState(prev => ({
            ...prev,
            viewport
        }));
        if (broadcast) {
            collaboration.broadcastEvent({
                type: 'canvas-viewport-changed',
                data: { viewport }
            });
        }
    }, [collaboration]);
    // Create new element
    const createElement = (0, react_1.useCallback)((type, position, size) => {
        return {
            id: `element-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
            type,
            position,
            size,
            content: type === 'text' ? 'Text' : type === 'sticky-note' ? 'Note' : '',
            style: {
                color: '#000000',
                backgroundColor: type === 'sticky-note' ? '#ffeb3b' : type === 'text' ? 'transparent' : '#ffffff',
                fontSize: 14,
                fontFamily: 'Arial, sans-serif',
                borderColor: '#000000',
                borderWidth: type === 'text' ? 0 : 1,
                opacity: 1,
                rotation: 0
            },
            metadata: {
                createdBy: collaboration.currentUser?.id || 'anonymous',
                createdAt: new Date(),
                lastModifiedBy: collaboration.currentUser?.id || 'anonymous',
                lastModifiedAt: new Date(),
                version: 1,
                locked: false,
                visible: true
            },
            permissions: {
                canEdit: ['*'], // Everyone can edit by default
                canDelete: ['*'],
                canMove: ['*']
            }
        };
    }, [collaboration.currentUser]);
    // Convert screen coordinates to canvas coordinates
    const screenToCanvas = (0, react_1.useCallback)((screenX, screenY) => {
        const rect = canvasRef.current?.getBoundingClientRect();
        if (!rect)
            return { x: 0, y: 0 };
        const canvasX = (screenX - rect.left - canvasState.viewport.x) / canvasState.viewport.zoom;
        const canvasY = (screenY - rect.top - canvasState.viewport.y) / canvasState.viewport.zoom;
        if (canvasState.snapToGrid) {
            return {
                x: Math.round(canvasX / canvasState.gridSize) * canvasState.gridSize,
                y: Math.round(canvasY / canvasState.gridSize) * canvasState.gridSize
            };
        }
        return { x: canvasX, y: canvasY };
    }, [canvasState.viewport, canvasState.snapToGrid, canvasState.gridSize]);
    // Mouse event handlers
    const handleMouseDown = (0, react_1.useCallback)((e) => {
        const canvasPos = screenToCanvas(e.clientX, e.clientY);
        setDragStart(canvasPos);
        setIsDrawing(true);
        // Update cursor position for collaboration
        collaboration.updateCursor(e.clientX, e.clientY);
        if (tool !== 'select') {
            // Start creating new element
            const newElement = createElement(tool, canvasPos, { width: 0, height: 0 });
            setCurrentElement(newElement);
        }
    }, [screenToCanvas, tool, createElement, collaboration]);
    const handleMouseMove = (0, react_1.useCallback)((e) => {
        const canvasPos = screenToCanvas(e.clientX, e.clientY);
        lastMousePosRef.current = canvasPos;
        // Update cursor position for collaboration
        collaboration.updateCursor(e.clientX, e.clientY);
        if (isDrawing && dragStart && currentElement) {
            // Update current element size/position
            const width = Math.abs(canvasPos.x - dragStart.x);
            const height = Math.abs(canvasPos.y - dragStart.y);
            const x = Math.min(canvasPos.x, dragStart.x);
            const y = Math.min(canvasPos.y, dragStart.y);
            setCurrentElement(prev => prev ? {
                ...prev,
                position: { x, y },
                size: { width, height }
            } : null);
        }
    }, [screenToCanvas, isDrawing, dragStart, currentElement, collaboration]);
    const handleMouseUp = (0, react_1.useCallback)(() => {
        if (isDrawing && currentElement && dragStart) {
            // Finalize element creation
            if (currentElement.size.width > 5 || currentElement.size.height > 5) {
                addElement(currentElement);
            }
        }
        setIsDrawing(false);
        setDragStart(null);
        setCurrentElement(null);
    }, [isDrawing, currentElement, dragStart, addElement]);
    // Keyboard shortcuts
    (0, react_1.useEffect)(() => {
        const handleKeyDown = (e) => {
            if (e.ctrlKey || e.metaKey) {
                switch (e.key) {
                    case 'z':
                        e.preventDefault();
                        // Undo
                        if (canvasState.history.past.length > 0) {
                            setCanvasState(prev => ({
                                ...prev,
                                elements: prev.history.past[prev.history.past.length - 1],
                                history: {
                                    past: prev.history.past.slice(0, -1),
                                    present: prev.history.past[prev.history.past.length - 1],
                                    future: [prev.history.present, ...prev.history.future]
                                }
                            }));
                        }
                        break;
                    case 'y':
                        e.preventDefault();
                        // Redo
                        if (canvasState.history.future.length > 0) {
                            setCanvasState(prev => ({
                                ...prev,
                                elements: prev.history.future[0],
                                history: {
                                    past: [...prev.history.past, prev.history.present],
                                    present: prev.history.future[0],
                                    future: prev.history.future.slice(1)
                                }
                            }));
                        }
                        break;
                    case 'a':
                        e.preventDefault();
                        // Select all
                        setCanvasState(prev => ({
                            ...prev,
                            selectedElements: prev.elements.map(el => el.id)
                        }));
                        break;
                }
            }
            // Delete selected elements
            if (e.key === 'Delete' || e.key === 'Backspace') {
                canvasState.selectedElements.forEach(elementId => {
                    deleteElement(elementId);
                });
            }
        };
        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, [canvasState, deleteElement]);
    // Rendered elements including current drawing element
    const allElements = (0, react_1.useMemo)(() => {
        const elements = [...canvasState.elements];
        if (currentElement) {
            elements.push(currentElement);
        }
        return elements;
    }, [canvasState.elements, currentElement]);
    return ((0, jsx_runtime_1.jsxs)("div", { className: `collaborative-canvas ${className}`, style: style, children: [(0, jsx_runtime_1.jsxs)("div", { className: "canvas-toolbar", children: [(0, jsx_runtime_1.jsxs)("div", { className: "toolbar-section", children: [(0, jsx_runtime_1.jsx)("button", { className: `tool-button ${tool === 'select' ? 'tool-button--active' : ''}`, onClick: () => setTool('select'), title: "Select", children: "\u2196\uFE0F" }), (0, jsx_runtime_1.jsx)("button", { className: `tool-button ${tool === 'text' ? 'tool-button--active' : ''}`, onClick: () => setTool('text'), title: "Text", children: "T" }), (0, jsx_runtime_1.jsx)("button", { className: `tool-button ${tool === 'rectangle' ? 'tool-button--active' : ''}`, onClick: () => setTool('rectangle'), title: "Rectangle", children: "\u25AD" }), (0, jsx_runtime_1.jsx)("button", { className: `tool-button ${tool === 'circle' ? 'tool-button--active' : ''}`, onClick: () => setTool('circle'), title: "Circle", children: "\u25EF" }), (0, jsx_runtime_1.jsx)("button", { className: `tool-button ${tool === 'sticky-note' ? 'tool-button--active' : ''}`, onClick: () => setTool('sticky-note'), title: "Sticky Note", children: "\uD83D\uDCDD" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "toolbar-section", children: [(0, jsx_runtime_1.jsx)("button", { className: "tool-button", onClick: () => setCanvasState(prev => ({ ...prev, gridEnabled: !prev.gridEnabled })), title: "Toggle Grid", children: "\uD83C\uDFB2" }), (0, jsx_runtime_1.jsx)("button", { className: "tool-button", onClick: () => setCanvasState(prev => ({ ...prev, snapToGrid: !prev.snapToGrid })), title: "Toggle Snap to Grid", children: "\uD83E\uDDE1" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "toolbar-section", children: [enableVoiceChat && ((0, jsx_runtime_1.jsx)("button", { className: `tool-button ${collaboration.voiceChatActive ? 'tool-button--active' : ''}`, onClick: collaboration.voiceChatActive ? collaboration.stopVoiceChat : collaboration.startVoiceChat, title: "Voice Chat", children: "\uD83C\uDFA4" })), enableVideoChat && ((0, jsx_runtime_1.jsx)("button", { className: `tool-button ${collaboration.videoChatActive ? 'tool-button--active' : ''}`, onClick: collaboration.videoChatActive ? collaboration.stopVideoChat : collaboration.startVideoChat, title: "Video Chat", children: "\uD83D\uDCF9" })), enableScreenShare && ((0, jsx_runtime_1.jsx)("button", { className: `tool-button ${collaboration.screenShareActive ? 'tool-button--active' : ''}`, onClick: collaboration.screenShareActive ? collaboration.stopScreenShare : collaboration.startScreenShare, title: "Screen Share", children: "\uD83D\uDCBB" }))] }), (0, jsx_runtime_1.jsx)("div", { className: "toolbar-section", children: (0, jsx_runtime_1.jsxs)("div", { className: "active-users", children: [collaboration.collaborators.slice(0, 5).map(user => ((0, jsx_runtime_1.jsx)("div", { className: "user-indicator", style: { borderColor: user.color }, title: user.name, children: user.avatar ? ((0, jsx_runtime_1.jsx)("img", { src: user.avatar, alt: user.name })) : (user.name[0]) }, user.id))), collaboration.collaborators.length > 5 && ((0, jsx_runtime_1.jsxs)("div", { className: "user-indicator user-indicator--overflow", children: ["+", collaboration.collaborators.length - 5] }))] }) })] }), (0, jsx_runtime_1.jsxs)("div", { ref: canvasRef, className: "canvas-area", onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, style: {
                    width,
                    height,
                    backgroundColor,
                    cursor: tool === 'select' ? 'default' : 'crosshair'
                }, children: [(0, jsx_runtime_1.jsxs)("svg", { ref: svgRef, width: width, height: height, className: "canvas-svg", style: {
                            transform: `translate(${canvasState.viewport.x}px, ${canvasState.viewport.y}px) scale(${canvasState.viewport.zoom})`
                        }, children: [canvasState.gridEnabled && ((0, jsx_runtime_1.jsxs)("defs", { children: [(0, jsx_runtime_1.jsx)("pattern", { id: "grid", width: canvasState.gridSize, height: canvasState.gridSize, patternUnits: "userSpaceOnUse", children: (0, jsx_runtime_1.jsx)("path", { d: `M ${canvasState.gridSize} 0 L 0 0 0 ${canvasState.gridSize}`, fill: "none", stroke: "#e0e0e0", strokeWidth: "0.5" }) }), (0, jsx_runtime_1.jsx)("rect", { width: "100%", height: "100%", fill: "url(#grid)" })] })), allElements.map(element => ((0, jsx_runtime_1.jsxs)("g", { children: [element.type === 'rectangle' && ((0, jsx_runtime_1.jsx)("rect", { x: element.position.x, y: element.position.y, width: element.size.width, height: element.size.height, fill: element.style.backgroundColor, stroke: element.style.borderColor, strokeWidth: element.style.borderWidth, opacity: element.style.opacity, transform: `rotate(${element.style.rotation} ${element.position.x + element.size.width / 2} ${element.position.y + element.size.height / 2})` })), element.type === 'circle' && ((0, jsx_runtime_1.jsx)("ellipse", { cx: element.position.x + element.size.width / 2, cy: element.position.y + element.size.height / 2, rx: element.size.width / 2, ry: element.size.height / 2, fill: element.style.backgroundColor, stroke: element.style.borderColor, strokeWidth: element.style.borderWidth, opacity: element.style.opacity })), element.type === 'text' && ((0, jsx_runtime_1.jsx)("text", { x: element.position.x, y: element.position.y + element.style.fontSize, fill: element.style.color, fontSize: element.style.fontSize, fontFamily: element.style.fontFamily, opacity: element.style.opacity, children: element.content })), element.type === 'sticky-note' && ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("rect", { x: element.position.x, y: element.position.y, width: element.size.width, height: element.size.height, fill: element.style.backgroundColor, stroke: element.style.borderColor, strokeWidth: element.style.borderWidth, opacity: element.style.opacity, rx: "4" }), (0, jsx_runtime_1.jsx)("text", { x: element.position.x + 8, y: element.position.y + element.style.fontSize + 8, fill: element.style.color, fontSize: element.style.fontSize, fontFamily: element.style.fontFamily, children: element.content })] })), canvasState.selectedElements.includes(element.id) && ((0, jsx_runtime_1.jsx)("rect", { x: element.position.x - 2, y: element.position.y - 2, width: element.size.width + 4, height: element.size.height + 4, fill: "none", stroke: "#007bff", strokeWidth: "2", strokeDasharray: "4 4", opacity: "0.8" }))] }, element.id)))] }), collaboration.userCursors.map(cursor => ((0, jsx_runtime_1.jsxs)("div", { className: "user-cursor", style: {
                            position: 'absolute',
                            left: cursor.x,
                            top: cursor.y,
                            pointerEvents: 'none',
                            zIndex: 1000
                        }, children: [(0, jsx_runtime_1.jsx)("div", { className: "cursor-pointer", style: {
                                    width: 12,
                                    height: 12,
                                    backgroundColor: cursor.color,
                                    borderRadius: '50%',
                                    border: '2px solid white',
                                    boxShadow: '0 2px 4px rgba(0,0,0,0.2)'
                                } }), (0, jsx_runtime_1.jsx)("div", { className: "cursor-label", style: {
                                    position: 'absolute',
                                    top: 16,
                                    left: 0,
                                    padding: '2px 6px',
                                    backgroundColor: cursor.color,
                                    color: 'white',
                                    fontSize: '12px',
                                    borderRadius: '4px',
                                    whiteSpace: 'nowrap'
                                }, children: cursor.userName })] }, cursor.userId)))] }), (0, jsx_runtime_1.jsxs)("div", { className: "canvas-status", children: [(0, jsx_runtime_1.jsxs)("div", { className: "status-info", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["Elements: ", canvasState.elements.length] }), (0, jsx_runtime_1.jsxs)("span", { children: ["Zoom: ", Math.round(canvasState.viewport.zoom * 100), "%"] }), (0, jsx_runtime_1.jsxs)("span", { children: ["Users: ", collaboration.collaborators.length] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "status-connection", children: [(0, jsx_runtime_1.jsx)("span", { className: `connection-indicator connection-indicator--${collaboration.connectionStatus}`, children: collaboration.isConnected ? '🟢' : '🔴' }), (0, jsx_runtime_1.jsx)("span", { children: collaboration.connectionStatus })] })] })] }));
};
exports.CollaborativeCanvas = CollaborativeCanvas;
exports.default = exports.CollaborativeCanvas;
//# sourceMappingURL=CollaborativeCanvas.js.map