import { useEffect } from 'react'
import { useEditor, react } from 'tldraw'
import { toolBrushStylesAtom } from '../utils/brushUtils'

export function BrushManager() {
    const editor = useEditor()

    // Tools that should have completely independent styles
    const DRAWING_TOOLS = ['draw', 'highlight']

    // 1. Capture tools' brushes ONLY when user actively changes them (not on tool switch)
    useEffect(() => {
        let previousStyles: Record<string, any> = {}
        let previousTool = editor.getCurrentToolId()
        
        const unreact = react('capture-user-brush', () => {
            const selection = editor.getSelectedShapeIds()
            const toolId = editor.getCurrentToolId()
            const activeStyles = editor.getInstanceState().stylesForNextShape
            
            // Skip select tool
            if (toolId === 'select') return

            // Detect if tool changed
            const toolChanged = toolId !== previousTool
            previousTool = toolId
            
            // For drawing tools: ONLY capture if user changes style while already on the tool
            // Do NOT capture when switching TO the tool (prevents contamination)
            if (DRAWING_TOOLS.includes(toolId)) {
                if (toolChanged) {
                    // Just switched to this tool - don't capture, just record current state
                    previousStyles[toolId] = JSON.parse(JSON.stringify(activeStyles))
                    return
                }
                
                // Already on this tool - check if user changed something
                const prevForThisTool = previousStyles[toolId]
                if (prevForThisTool && JSON.stringify(prevForThisTool) !== JSON.stringify(activeStyles)) {
                    // User actively changed the style! Save it.
                    const currentStored = toolBrushStylesAtom.get()
                    toolBrushStylesAtom.set({
                        ...currentStored,
                        [toolId]: JSON.parse(JSON.stringify(activeStyles))
                    })
                    previousStyles[toolId] = JSON.parse(JSON.stringify(activeStyles))
                }
                return
            }
            
            // For non-drawing tools: capture when no selection
            if (selection.length === 0) {
                const currentStored = toolBrushStylesAtom.get()
                if (JSON.stringify(currentStored[toolId]) !== JSON.stringify(activeStyles)) {
                    toolBrushStylesAtom.set({
                        ...currentStored,
                        [toolId]: JSON.parse(JSON.stringify(activeStyles))
                    })
                }
            }
        })
        
        return () => {
            unreact()
        }
    }, [editor])

    // 2. Restore the saved brush for ALL tools (including drawing tools)
    useEffect(() => {
        const restoreBrush = () => {
            const toolId = editor.getCurrentToolId()
            
            // Skip select tool only
            if (toolId === 'select') return

            const storedStyles = toolBrushStylesAtom.get()[toolId]
            if (storedStyles && Object.keys(storedStyles).length > 0) {
                editor.run(() => {
                    for (const [id, value] of Object.entries(storedStyles)) {
                        // Use the internal style ID to set the next style
                        editor.setStyleForNextShapes({ id } as any, value, { history: 'ignore' })
                    }
                }, { history: 'ignore' })
            }
        }

        // Restore when:
        // - Tool changes
        // - Selection is cleared
        // - A pointer operation finishes (to overwrite tldraw's auto-sync-to-selection)
        
        const handleEvent = (e: any) => {
            if (e.name === 'tool_change') {
                restoreBrush()
            }
            if (e.name === 'pointer_up') {
                // Wait for tldraw to finish its own sync-to-selection
                setTimeout(restoreBrush, 20)
            }
        }

        editor.on('event', handleEvent)
        
        // Also watch for selection becoming empty via react
        const unreact = react('restore-on-deselect', () => {
            const selection = editor.getSelectedShapeIds()
            if (selection.length === 0) {
                restoreBrush()
            }
        })

        return () => {
            editor.off('event', handleEvent)
            unreact()
        }
    }, [editor])

    // 3. EXPLICIT PROTECTION: Prevent drawing tools from syncing styles from selections
    useEffect(() => {
        let lastToolId = editor.getCurrentToolId()
        
        return react('block-drawing-tool-sync', () => {
            const toolId = editor.getCurrentToolId()
            const selection = editor.getSelectedShapeIds()
            
            // Detect tool change
            if (toolId !== lastToolId) {
                lastToolId = toolId
                
                // If we switched TO a drawing tool AND there's a selection
                // Force restore the drawing tool's saved styles immediately
                if (DRAWING_TOOLS.includes(toolId) && selection.length > 0) {
                    const storedStyles = toolBrushStylesAtom.get()[toolId]
                    if (storedStyles && Object.keys(storedStyles).length > 0) {
                        // Multiple aggressive restores to override tldraw's sync
                        for (let i = 0; i < 3; i++) {
                            setTimeout(() => {
                                editor.run(() => {
                                    for (const [id, value] of Object.entries(storedStyles)) {
                                        editor.setStyleForNextShapes({ id } as any, value, { history: 'ignore' })
                                    }
                                }, { history: 'ignore' })
                            }, i * 10)
                        }
                    }
                }
            }
        })
    }, [editor])

    return null
}