import type { FlowNode } from '@/pages/Workflow/Design/types';

/**
 * 正则1：匹配 ${...} 块
 */
const BLOCK_PATTERN = /\$\{([^}]+)\}/g;

/**
 * 正则2：在表达式内匹配 节点名.字段 引用
 * 支持中文节点名、UUID格式节点ID
 */
const NODE_REF_PATTERN = /([a-zA-Z0-9_\u4e00-\u9fa5\-]+)\.([a-zA-Z0-9_.]+)/g;

/**
 * 将显示名称格式转换为UUID格式
 * ${节点名称.字段名} → ${节点UUID.字段名}
 * 
 * @param displayText 包含显示名称的文本
 * @param allNodes 所有节点列表（用于查找UUID）
 * @returns 转换后的UUID格式文本
 * 
 * @example
 * convertToUUID("构建${Jenkins构建.buildStatus}完成", allNodes)
 * // 返回: "构建${uuid-123.buildStatus}完成"
 */
export const convertToUUID = (
    displayText: string,
    allNodes: FlowNode[]
): string => {
    if (!displayText || typeof displayText !== 'string') {
        return displayText;
    }
    
    // 阶段1：处理 ${...} 块
    return displayText.replace(BLOCK_PATTERN, (blockMatch, blockContent) => {
        // 阶段2：在块内容中查找并替换所有 节点名.字段 引用
        const transformedContent = blockContent.replace(NODE_REF_PATTERN, (refMatch: string, nodeNameOrId: string, fieldPath: string) => {
            // 特殊处理：表单字段
            if (nodeNameOrId === '启动表单' || nodeNameOrId === 'form' || nodeNameOrId === 'notification') {
                return `${nodeNameOrId}.${fieldPath}`;
            }
            
            // 尝试通过名称查找节点
            const nodeByName = allNodes.find(n => {
                const nodeName = n.data?.label || n.data?.nodeDefinition?.nodeName;
                return nodeName === nodeNameOrId;
            });
            
            if (nodeByName) {
                return `${nodeByName.id}.${fieldPath}`;
            }
            
            // 可能已经是UUID格式，保持原样
            return refMatch;
        });
        
        return `\${${transformedContent}}`;
    });
};

/**
 * 将UUID格式转换为显示名称格式
 * ${节点UUID.字段名} → ${节点名称.字段名}
 * 
 * @param uuidText 包含UUID的文本
 * @param allNodes 所有节点列表（用于查找显示名称）
 * @returns 转换后的显示名称格式文本
 * 
 * @example
 * convertToDisplayName("构建${uuid-123.buildStatus}完成", allNodes)
 * // 返回: "构建${Jenkins构建.buildStatus}完成"
 */
export const convertToDisplayName = (
    uuidText: string,
    allNodes: FlowNode[]
): string => {
    if (!uuidText || typeof uuidText !== 'string') {
        return uuidText;
    }
    
    // 阶段1：处理 ${...} 块
    return uuidText.replace(BLOCK_PATTERN, (blockMatch, blockContent) => {
        // 阶段2：在块内容中查找并替换所有 UUID.字段 引用为 节点名.字段
        const transformedContent = blockContent.replace(NODE_REF_PATTERN, (refMatch: string, nodeIdOrName: string, fieldPath: string) => {
            // 特殊处理：表单字段
            if (nodeIdOrName === 'form' || nodeIdOrName === '启动表单' || nodeIdOrName === 'notification') {
                return `${nodeIdOrName}.${fieldPath}`;
            }
            
            // 尝试通过UUID查找节点
            const nodeById = allNodes.find(n => n.id === nodeIdOrName);
            
            if (nodeById) {
                // 找到了，替换为显示名称
                const nodeName = nodeById.data?.label || nodeById.data?.nodeDefinition?.nodeName || nodeIdOrName;
                return `${nodeName}.${fieldPath}`;
            }
            
            // 可能已经是显示名称格式，保持原样
            return refMatch;
        });
        
        return `\${${transformedContent}}`;
    });
};

/**
 * 转换对象中的所有字符串值（从显示名称到UUID）
 * 递归处理嵌套对象和数组
 * 
 * @param obj 要转换的对象
 * @param allNodes 所有节点列表
 * @returns 转换后的对象
 */
export const convertObjectToUUID = <T extends Record<string, any>>(
    obj: T,
    allNodes: FlowNode[]
): T => {
    if (!obj || typeof obj !== 'object') {
        return obj;
    }
    
    const result: any = Array.isArray(obj) ? [] : {};
    
    for (const key in obj) {
        const value = obj[key];
        
        if (typeof value === 'string') {
            // 字符串类型：进行转换
            result[key] = convertToUUID(value, allNodes);
        } else if (value && typeof value === 'object') {
            // 对象或数组：递归转换
            result[key] = convertObjectToUUID(value, allNodes);
        } else {
            // 其他类型：保持原样
            result[key] = value;
        }
    }
    
    return result as T;
};

/**
 * 转换对象中的所有字符串值（从UUID到显示名称）
 * 递归处理嵌套对象和数组
 * 
 * @param obj 要转换的对象
 * @param allNodes 所有节点列表
 * @returns 转换后的对象
 */
export const convertObjectToDisplayName = <T extends Record<string, any>>(
    obj: T,
    allNodes: FlowNode[]
): T => {
    if (!obj || typeof obj !== 'object') {
        return obj;
    }
    
    const result: any = Array.isArray(obj) ? [] : {};
    
    for (const key in obj) {
        const value = obj[key];
        
        if (typeof value === 'string') {
            // 字符串类型：进行转换
            result[key] = convertToDisplayName(value, allNodes);
        } else if (value && typeof value === 'object') {
            // 对象或数组：递归转换
            result[key] = convertObjectToDisplayName(value, allNodes);
        } else {
            // 其他类型：保持原样
            result[key] = value;
        }
    }
    
    return result as T;
};

