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

/**
 * 变量表达式的正则模式
 * 匹配 ${xxx.yyy} 格式
 * xxx: 节点名称或UUID
 * yyy: 字段名
 */
const VARIABLE_PATTERN = /\$\{([^.}]+)\.([^}]+)\}/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;
    }
    
    return displayText.replace(VARIABLE_PATTERN, (match, nodeNameOrId, fieldName) => {
        // 尝试通过名称查找节点
        const nodeByName = allNodes.find(n => {
            const nodeName = n.data?.label || n.data?.nodeDefinition?.nodeName;
            return nodeName === nodeNameOrId;
        });
        
        if (nodeByName) {
            // 找到了，替换为UUID
            return `\${${nodeByName.id}.${fieldName}}`;
        }
        
        // 可能已经是UUID格式，或者节点已被删除
        // 保持原样
        return match;
    });
};

/**
 * 将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;
    }
    
    return uuidText.replace(VARIABLE_PATTERN, (match, nodeIdOrName, fieldName) => {
        // 尝试通过UUID查找节点
        const nodeById = allNodes.find(n => n.id === nodeIdOrName);
        
        if (nodeById) {
            // 找到了，替换为显示名称
            const nodeName = nodeById.data?.label || nodeById.data?.nodeDefinition?.nodeName || nodeIdOrName;
            return `\${${nodeName}.${fieldName}}`;
        }
        
        // 可能已经是显示名称格式，或者节点已被删除
        // 保持原样
        return match;
    });
};

/**
 * 转换对象中的所有字符串值（从显示名称到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;
};

