import React, { useState, useRef, useMemo, useEffect, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import type { VariableInputProps } from './types';
import { detectTrigger, insertVariable, filterVariables } from './utils';
import { collectNodeVariables, groupVariablesByNode } from '@/utils/workflow/collectNodeVariables';
import HighlightLayer from './HighlightLayer';
import { handleBackspaceDelete, handleDeleteKey } from './deleteHelper';

/**
 * 变量输入组件
 * 支持在输入 ${ 时自动提示可用变量
 */
const VariableInput: React.FC<VariableInputProps> = ({
    value = '',
    onChange,
    allNodes,
    allEdges,
    currentNodeId,
    variant = 'input',
    placeholder,
    disabled = false,
    rows = 3,
}) => {
    const [showSuggestions, setShowSuggestions] = useState(false);
    const [triggerInfo, setTriggerInfo] = useState({ shouldShow: false, startPos: -1, searchText: '' });
    const [selectedIndex, setSelectedIndex] = useState(0); // 当前选中的变量索引
    const [dropdownPosition, setDropdownPosition] = useState<'bottom' | 'top'>('bottom'); // 下拉框位置
    const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
    const containerRef = useRef<HTMLDivElement>(null);
    const dropdownRef = useRef<HTMLDivElement>(null);
    const highlightRef = useRef<HTMLDivElement>(null);
    
    // 收集可用变量
    const allVariables = useMemo(() => {
        return collectNodeVariables(currentNodeId, allNodes, allEdges);
    }, [currentNodeId, allNodes, allEdges]);
    
    // 根据搜索文本过滤变量
    const filteredVariables = useMemo(() => {
        return filterVariables(allVariables, triggerInfo.searchText);
    }, [allVariables, triggerInfo.searchText]);
    
    // 按节点分组
    const groupedVariables = useMemo(() => {
        return groupVariablesByNode(filteredVariables);
    }, [filteredVariables]);
    
    // 计算下拉框的位置
    const getDropdownStyle = useCallback(() => {
        if (!inputRef.current) return {};
        
        const inputRect = inputRef.current.getBoundingClientRect();
        const gap = 8; // 间距
        
        if (dropdownPosition === 'top') {
            // 显示在上方
            return {
                bottom: window.innerHeight - inputRect.top + window.scrollY + gap,
                left: inputRect.left + window.scrollX,
                width: inputRect.width,
            };
        } else {
            // 显示在下方
            return {
                top: inputRect.bottom + window.scrollY + gap,
                left: inputRect.left + window.scrollX,
                width: inputRect.width,
            };
        }
    }, [dropdownPosition]);
    
    // 点击外部关闭建议框
    useEffect(() => {
        if (!showSuggestions) return;
        
        const handleClickOutside = (event: MouseEvent) => {
            const target = event.target as Node;
            
            // 检查是否点击了输入框或下拉列表
            const isClickInside = 
                (containerRef.current && containerRef.current.contains(target)) ||
                (dropdownRef.current && dropdownRef.current.contains(target));
            
            if (!isClickInside) {
                setShowSuggestions(false);
            }
        };
        
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, [showSuggestions]);
    
    // 计算下拉框位置（上方或下方）
    useEffect(() => {
        if (!showSuggestions || !inputRef.current || !dropdownRef.current) return;
        
        const inputRect = inputRef.current.getBoundingClientRect();
        const dropdownHeight = 320; // 估算的下拉框高度
        const spaceBelow = window.innerHeight - inputRect.bottom;
        const spaceAbove = inputRect.top;
        
        // 如果下方空间不足，且上方空间更多，则显示在上方
        if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
            setDropdownPosition('top');
        } else {
            setDropdownPosition('bottom');
        }
    }, [showSuggestions]);
    
    // 当显示建议时，重置选中索引
    useEffect(() => {
        if (showSuggestions) {
            setSelectedIndex(0);
        }
    }, [showSuggestions]);
    
    // 同步输入框和高亮层的样式
    useEffect(() => {
        if (!inputRef.current || !highlightRef.current) return;
        
        const inputElement = inputRef.current;
        const highlightElement = highlightRef.current;
        
        const syncStyles = () => {
            if (!inputElement || !highlightElement) return;
            
            const inputStyles = window.getComputedStyle(inputElement);
            
            // 复制所有影响文本定位的样式（精确同步）
            highlightElement.style.paddingTop = inputStyles.paddingTop;
            highlightElement.style.paddingRight = inputStyles.paddingRight;
            highlightElement.style.paddingBottom = inputStyles.paddingBottom;
            highlightElement.style.paddingLeft = inputStyles.paddingLeft;
            highlightElement.style.fontSize = inputStyles.fontSize;
            highlightElement.style.fontFamily = inputStyles.fontFamily;
            highlightElement.style.fontWeight = inputStyles.fontWeight;
            highlightElement.style.lineHeight = inputStyles.lineHeight;
            highlightElement.style.letterSpacing = inputStyles.letterSpacing;
            highlightElement.style.wordSpacing = inputStyles.wordSpacing;
            highlightElement.style.whiteSpace = variant === 'textarea' ? 'pre-wrap' : 'nowrap';
            highlightElement.style.wordWrap = 'break-word';
            highlightElement.style.overflowWrap = inputStyles.overflowWrap;
            highlightElement.style.verticalAlign = inputStyles.verticalAlign;
            highlightElement.style.boxSizing = inputStyles.boxSizing;
            
            // 关键：同步文本对齐属性，确保光标位置准确
            highlightElement.style.textAlign = inputStyles.textAlign;
            highlightElement.style.direction = inputStyles.direction;
            highlightElement.style.textIndent = inputStyles.textIndent;
        };
        
        // 同步滚动位置（仅 textarea）
        const syncScroll = () => {
            if (!inputElement || !highlightElement || variant !== 'textarea') return;
            
            highlightElement.scrollTop = inputElement.scrollTop;
            highlightElement.scrollLeft = inputElement.scrollLeft;
        };
        
        // 初始同步（多次延迟确保 DOM 完全渲染，包括 Modal/Sheet 的样式应用）
        syncStyles();
        setTimeout(syncStyles, 0);
        setTimeout(syncStyles, 10);
        setTimeout(syncStyles, 50);
        setTimeout(syncStyles, 100);
        
        // 监听窗口大小变化（可能影响字体大小）
        const resizeObserver = new ResizeObserver(syncStyles);
        resizeObserver.observe(inputElement);
        
        // 监听父元素属性变化（例如 Modal/Sheet 的显示状态）
        const mutationObserver = new MutationObserver(syncStyles);
        let parent = inputElement.parentElement;
        while (parent && parent !== document.body) {
            mutationObserver.observe(parent, {
                attributes: true,
                attributeFilter: ['class', 'style'],
            });
            parent = parent.parentElement;
        }
        
        // 监听滚动事件（仅 textarea）
        if (variant === 'textarea') {
            inputElement.addEventListener('scroll', syncScroll);
        }
        
        return () => {
            resizeObserver.disconnect();
            mutationObserver.disconnect();
            if (variant === 'textarea') {
                inputElement.removeEventListener('scroll', syncScroll);
            }
        };
        // ✅ 性能优化：移除 value 依赖，避免每次输入都重新同步样式
        // ResizeObserver 会自动处理元素大小变化
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [variant]);
    
    // 当 value 变化时，确保样式同步（特别是首次输入时）
    useEffect(() => {
        if (!inputRef.current || !highlightRef.current || !value) return;
        
        const syncCriticalStyles = () => {
            const inputElement = inputRef.current;
            const highlightContainer = highlightRef.current;
            if (!inputElement || !highlightContainer) return;
            
            const inputStyles = window.getComputedStyle(inputElement);
            
            // 同步关键样式
            highlightContainer.style.paddingTop = inputStyles.paddingTop;
            highlightContainer.style.paddingBottom = inputStyles.paddingBottom;
            highlightContainer.style.paddingLeft = inputStyles.paddingLeft;
            highlightContainer.style.paddingRight = inputStyles.paddingRight;
            highlightContainer.style.lineHeight = inputStyles.lineHeight;
            highlightContainer.style.fontSize = inputStyles.fontSize;
            highlightContainer.style.fontFamily = inputStyles.fontFamily;
        };
        
        // 多次延迟确保样式完全应用
        syncCriticalStyles();
        const timer1 = setTimeout(syncCriticalStyles, 0);
        const timer2 = setTimeout(syncCriticalStyles, 10);
        const timer3 = setTimeout(syncCriticalStyles, 50);
        
        return () => {
            clearTimeout(timer1);
            clearTimeout(timer2);
            clearTimeout(timer3);
        };
    }, [value]);
    
    // 监听滚动和窗口大小变化，更新下拉框位置
    useEffect(() => {
        if (!showSuggestions) return;
        
        const handlePositionUpdate = () => {
            // 强制重新渲染以更新位置
            if (dropdownRef.current) {
                const style = getDropdownStyle();
                Object.assign(dropdownRef.current.style, style);
            }
        };
        
        window.addEventListener('scroll', handlePositionUpdate, true);
        window.addEventListener('resize', handlePositionUpdate);
        
        return () => {
            window.removeEventListener('scroll', handlePositionUpdate, true);
            window.removeEventListener('resize', handlePositionUpdate);
        };
    }, [showSuggestions, getDropdownStyle]);
    
    // 处理输入变化
    const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
        const newValue = e.target.value;
        const cursorPos = e.target.selectionStart || 0;
        
        onChange(newValue);
        
        // 检测是否应该触发变量建议
        const trigger = detectTrigger(newValue, cursorPos);
        setTriggerInfo(trigger);
        setShowSuggestions(trigger.shouldShow && !disabled);
    };
    
    // 处理键盘事件
    const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
        const target = e.target as HTMLInputElement | HTMLTextAreaElement;
        
        // 处理变量整体删除（Backspace）
        if (e.key === 'Backspace' && !showSuggestions) {
            const result = handleBackspaceDelete(
                value,
                target.selectionStart || 0,
                target.selectionEnd || 0
            );
            
            if (result) {
                e.preventDefault();
                onChange(result.newText);
                
                // 恢复光标位置
                setTimeout(() => {
                    if (inputRef.current) {
                        inputRef.current.setSelectionRange(result.newCursorPos, result.newCursorPos);
                    }
                }, 0);
                return;
            }
        }
        
        // 处理变量整体删除（Delete）
        if (e.key === 'Delete' && !showSuggestions) {
            const result = handleDeleteKey(
                value,
                target.selectionStart || 0,
                target.selectionEnd || 0
            );
            
            if (result) {
                e.preventDefault();
                onChange(result.newText);
                
                // 恢复光标位置
                setTimeout(() => {
                    if (inputRef.current) {
                        inputRef.current.setSelectionRange(result.newCursorPos, result.newCursorPos);
                    }
                }, 0);
                return;
            }
        }
        
        // 建议框快捷键
        if (!showSuggestions) return;
        
        switch (e.key) {
            case 'Escape':
                // Esc 键关闭建议框
                setShowSuggestions(false);
                e.preventDefault();
                break;
                
            case 'ArrowDown':
                // ↓ 键向下选择
                e.preventDefault();
                setSelectedIndex(prev => 
                    prev < filteredVariables.length - 1 ? prev + 1 : prev
                );
                break;
                
            case 'ArrowUp':
                // ↑ 键向上选择
                e.preventDefault();
                setSelectedIndex(prev => prev > 0 ? prev - 1 : prev);
                break;
                
            case 'Enter':
                // Enter 键选中当前变量
                e.preventDefault();
                if (filteredVariables[selectedIndex]) {
                    const variable = filteredVariables[selectedIndex];
                    handleSelectVariable(variable.nodeName, variable.fieldName);
                }
                break;
        }
    };
    
    // 插入变量
    const handleSelectVariable = (nodeName: string, fieldName: string) => {
        if (!inputRef.current) return;

        const cursorPos = inputRef.current.selectionStart || 0;

        // 使用工具函数插入变量
        const { newText, newCursorPos } = insertVariable(
            value,
            cursorPos,
            triggerInfo.startPos,
            nodeName,
            fieldName
        );

        // 更新值
        onChange(newText);

        // 关闭建议框
        setShowSuggestions(false);

        // 恢复焦点并设置光标位置
        setTimeout(() => {
            if (inputRef.current) {
                inputRef.current.focus();
                inputRef.current.setSelectionRange(newCursorPos, newCursorPos);
            }
        }, 0);
    };
    
    // 渲染输入框
    const renderInput = () => {
        const baseStyle = {
            // 关键：使用 WebKit 专属属性使文字完全透明，但保留光标和选区
            WebkitTextFillColor: 'transparent',
            color: 'transparent', // 降级方案
            caretColor: 'hsl(var(--foreground))',
            // 保留选区高亮
            WebkitUserSelect: 'text',
            userSelect: 'text',
        } as React.CSSProperties;
        
        // 只有有值时才设置透明，这样 placeholder 可以正常显示
        const commonProps = {
            ref: inputRef as any,
            value,
            onChange: handleChange,
            onKeyDown: handleKeyDown,
            placeholder,
            disabled,
            className: 'variable-input',
            style: value ? baseStyle : { caretColor: 'hsl(var(--foreground))' },
        };
        
        if (variant === 'input') {
            return <Input {...commonProps} />;
        }
        
        return <Textarea {...commonProps} rows={rows} />;
    };
    
    // 渲染变量提示
    const renderSuggestions = () => {
        if (allVariables.length === 0) {
            return (
                <div className="p-4 text-center text-sm text-muted-foreground">
                    当前没有可用变量（没有前序节点或前序节点无输出）
                </div>
            );
        }
        
        if (filteredVariables.length === 0) {
            return (
                <div className="p-4 text-center text-sm text-muted-foreground">
                    未找到匹配的变量
                </div>
            );
        }
        
        let globalIndex = 0; // 全局索引，用于跟踪所有变量
        
        return (
            <div className="max-h-80 overflow-y-auto">
                {Array.from(groupedVariables.entries()).map(([nodeName, variables]) => (
                    <div key={nodeName} className="py-2">
                        <div className="px-3 py-1 text-xs font-semibold text-muted-foreground">
                            📦 {nodeName}
                        </div>
                        <div className="space-y-0.5">
                            {variables.map((variable) => {
                                const currentIndex = globalIndex++;
                                const isSelected = currentIndex === selectedIndex;
                                
                                return (
                                    <div
                                        key={`${variable.nodeId}.${variable.fieldName}`}
                                        className={`flex items-center justify-between px-3 py-2 cursor-pointer rounded-sm transition-colors ${
                                            isSelected ? 'bg-accent text-accent-foreground' : 'hover:bg-accent'
                                        }`}
                                        onClick={() => handleSelectVariable(variable.nodeName, variable.fieldName)}
                                        onMouseEnter={() => setSelectedIndex(currentIndex)}
                                        ref={isSelected ? (el) => el?.scrollIntoView({ block: 'nearest' }) : undefined}
                                    >
                                        <span className="font-mono text-sm">{variable.fieldName}</span>
                                        <span className="ml-auto text-xs text-muted-foreground">{variable.fieldType}</span>
                                    </div>
                                );
                            })}
                        </div>
                    </div>
                ))}
            </div>
        );
    };
    
    // 渲染下拉列表（使用 Portal 渲染到 body）
    const renderDropdown = () => {
        if (!showSuggestions) return null;
        
        return createPortal(
            <div 
                ref={dropdownRef}
                className="fixed z-[99999]"
                style={getDropdownStyle()}
            >
                <div className="w-full max-w-[500px] bg-popover text-popover-foreground rounded-md border shadow-lg">
                    {renderSuggestions()}
                    <div className="px-3 py-2 border-t text-xs text-muted-foreground bg-muted/30">
                        💡 输入 <code className="px-1 py-0.5 bg-background rounded">${'{'}</code> 触发变量提示，
                        <kbd className="px-1 py-0.5 bg-background rounded border">↑↓</kbd> 选择，
                        <kbd className="px-1 py-0.5 bg-background rounded border">Enter</kbd> 确认。
                        选择后光标在 <code className="px-1 py-0.5 bg-background rounded">{'}'}</code> 前，可继续输入比较逻辑
                    </div>
                </div>
            </div>,
            document.body
        );
    };
    
    return (
        <div ref={containerRef} className="relative">
            {/* 包装容器：输入框 + 高亮层 */}
            <div className="relative">
                {/* 底层：实际的输入框（文字透明，光标可见） */}
                {renderInput()}
                
                {/* 顶层：高亮层（绝对定位，覆盖在输入框上） */}
                {value && (
                    <div 
                        ref={highlightRef}
                        className="absolute inset-0 pointer-events-none"
                        style={{
                            overflow: 'hidden',
                            display: variant === 'input' ? 'flex' : 'block',
                            alignItems: variant === 'input' ? 'center' : 'flex-start',
                        }}
                    >
                        {/* Input 需要包装 div 避免 flex 影响文字，Textarea 直接渲染 */}
                        {variant === 'input' ? (
                            <div style={{ width: '100%' }}>
                                <HighlightLayer value={value} />
                            </div>
                        ) : (
                            <HighlightLayer value={value} />
                        )}
                    </div>
                )}
            </div>
            
            {/* 变量提示弹窗 - 使用 Portal 渲染到 body */}
            {renderDropdown()}
        </div>
    );
};

export default VariableInput;

