import type { FlowNode, FlowEdge } from '../types';

/**
 * 网关模式（BPMN 2.0 标准）
 */
export enum GatewayMode {
    /** 分支模式（Diverging）：1入口 → 多出口 */
    DIVERGING = 'diverging',
    /** 汇聚模式（Converging）：多入口 → 1出口 */
    CONVERGING = 'converging',
    /** 混合模式（Mixed）：多入口 → 多出口（不推荐） */
    MIXED = 'mixed',
    /** 未完成：连线不足或无效 */
    INCOMPLETE = 'incomplete'
}

/**
 * 网关节点验证结果
 */
export interface GatewayValidationResult {
    valid: boolean;
    errors: string[];
    warnings: string[];
}

/**
 * 检测网关模式（基于连线数量）
 * @param incomingCount 入口连线数量
 * @param outgoingCount 出口连线数量
 * @returns 网关模式
 */
export const detectGatewayMode = (
    incomingCount: number,
    outgoingCount: number
): GatewayMode => {
    // 分支模式：1入口 + 多出口（≥2）
    if (incomingCount === 1 && outgoingCount >= 2) {
        return GatewayMode.DIVERGING;
    }
    
    // 汇聚模式：多入口（≥2）+ 1出口
    if (incomingCount >= 2 && outgoingCount === 1) {
        return GatewayMode.CONVERGING;
    }
    
    // 混合模式：多入口 + 多出口（不推荐，视为分支处理）
    if (incomingCount >= 2 && outgoingCount >= 2) {
        return GatewayMode.MIXED;
    }
    
    // 其他情况：未完成或无效
    return GatewayMode.INCOMPLETE;
};

/**
 * 验证网关节点配置（支持分支和汇聚模式）
 * @param node 网关节点
 * @param edges 所有边
 * @returns 验证结果
 */
export const validateGatewayNode = (
    node: FlowNode,
    edges: FlowEdge[]
): GatewayValidationResult => {
    const errors: string[] = [];
    const warnings: string[] = [];
    
    // 只验证网关节点
    if (node.data.nodeType !== 'GATEWAY_NODE') {
        return { valid: true, errors: [], warnings: [] };
    }
    
    // 获取网关类型（优先从 inputMapping，兼容 configs）
    const gatewayType = node.data.inputMapping?.gatewayType || node.data.configs?.gatewayType;
    const nodeName = node.data.label || '网关节点';
    
    // 获取入口和出口连线
    const incomingEdges = edges.filter(e => e.target === node.id);
    const outgoingEdges = edges.filter(e => e.source === node.id);
    
    // 1. 检测网关模式
    const mode = detectGatewayMode(incomingEdges.length, outgoingEdges.length);
    
    // 1.1 特殊情况：1入1出透传模式（兼容老数据）
    if (incomingEdges.length === 1 && outgoingEdges.length === 1) {
        warnings.push(
            `${nodeName}：网关只有1入1出，等同于直接连线，建议移除网关节点以简化流程`
        );
        // 透传模式不需要条件配置，直接返回通过
        return { valid: true, errors, warnings };
    }
    
    // 2. 根据模式进行验证
    if (mode === GatewayMode.DIVERGING || mode === GatewayMode.MIXED) {
        // ========== 分支模式验证 ==========
        // 分支网关：1入口 + 多出口（混合模式也按分支处理）
        
        // 2.1 验证连线数量
        if (incomingEdges.length !== 1) {
            errors.push(`${nodeName}（分支网关）：需要1条入口连线（当前${incomingEdges.length}条）`);
        }
        if (outgoingEdges.length < 2) {
            errors.push(`${nodeName}（分支网关）：至少需要2条出口连线（当前${outgoingEdges.length}条）`);
        }
        
        // 如果混合模式，给出警告
        if (mode === GatewayMode.MIXED) {
            warnings.push(`${nodeName}：检测到混合模式（多入多出），按分支网关处理，建议拆分为多个网关`);
        }
        
        // 如果连线数量不足，不再进行条件验证
        if (outgoingEdges.length < 2) {
            return { valid: false, errors, warnings };
        }
        
        // 2.2 排他网关 / 包容网关：验证条件配置
        if (gatewayType === 'exclusiveGateway' || gatewayType === 'inclusiveGateway') {
            // 检查默认分支
            const defaultBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'DEFAULT');
            if (defaultBranches.length === 0) {
                errors.push(`${nodeName}（分支）：${gatewayType === 'exclusiveGateway' ? '排他' : '包容'}网关必须有一个默认分支`);
            } else if (defaultBranches.length > 1) {
                errors.push(`${nodeName}（分支）：只能有一个默认分支（当前${defaultBranches.length}个）`);
            }
            
            // 检查条件分支
            const expressionBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'EXPRESSION');
            
            if (gatewayType === 'exclusiveGateway') {
                // 排他网关：检查优先级重复
                const priorities = expressionBranches.map(e => e.data?.condition?.priority);
                const uniquePriorities = new Set(priorities);
                if (priorities.length !== uniquePriorities.size) {
                    errors.push(`${nodeName}（分支）：排他网关的分支优先级不能重复`);
                }
                
                // 检查是否所有条件分支都有优先级
                const noPriorityBranches = expressionBranches.filter(e => 
                    e.data?.condition?.priority === undefined || 
                    e.data?.condition?.priority === null
                );
                if (noPriorityBranches.length > 0) {
                    errors.push(`${nodeName}（分支）：有${noPriorityBranches.length}条分支未设置优先级`);
                }
            }
            
            // 检查条件表达式是否为空
            const emptyExpressionBranches = expressionBranches.filter(e => 
                !e.data?.condition?.expression || 
                e.data?.condition?.expression.trim() === ''
            );
            if (emptyExpressionBranches.length > 0) {
                warnings.push(`${nodeName}（分支）：有${emptyExpressionBranches.length}条分支的条件表达式为空`);
            }
        }
        
        // 2.3 并行网关：不需要条件配置
        if (gatewayType === 'parallelGateway') {
            const expressionBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'EXPRESSION');
            if (expressionBranches.length > 0) {
                warnings.push(`${nodeName}（分支）：并行网关的所有分支都会执行，条件表达式将被忽略`);
            }
        }
        
    } else if (mode === GatewayMode.CONVERGING) {
        // ========== 汇聚模式验证 ==========
        // 汇聚网关：多入口 + 1出口，不需要条件配置
        
        // 2.4 验证连线数量
        if (incomingEdges.length < 2) {
            errors.push(`${nodeName}（汇聚网关）：至少需要2条入口连线（当前${incomingEdges.length}条）`);
        }
        if (outgoingEdges.length !== 1) {
            errors.push(`${nodeName}（汇聚网关）：只能有1条出口连线（当前${outgoingEdges.length}条）`);
        }
        
        // 2.5 汇聚网关不需要条件配置，如果配置了给出警告
        const hasConditions = outgoingEdges.some(e => 
            e.data?.condition?.type === 'EXPRESSION' || 
            e.data?.condition?.type === 'DEFAULT'
        );
        if (hasConditions) {
            warnings.push(`${nodeName}（汇聚网关）：汇聚模式不需要条件配置，条件将被忽略`);
        }
        
    } else {
        // ========== 未完成状态 ==========
        errors.push(
            `${nodeName}：网关连线配置不完整（当前：${incomingEdges.length}入${outgoingEdges.length}出）。` +
            `需要配置为分支模式（1入≥2出）或汇聚模式（≥2入1出）`
        );
    }
    
    // 3. 检查是否所有出口都有连接
    const unconnectedEdges = outgoingEdges.filter(e => !e.target);
    if (unconnectedEdges.length > 0) {
        errors.push(`${nodeName}：有${unconnectedEdges.length}条出口连线未连接到目标节点`);
    }
    
    return {
        valid: errors.length === 0,
        errors,
        warnings
    };
};

/**
 * 验证所有网关节点
 * @param nodes 所有节点
 * @param edges 所有边
 * @returns 验证结果数组
 */
export const validateAllGateways = (
    nodes: FlowNode[],
    edges: FlowEdge[]
): GatewayValidationResult[] => {
    const gatewayNodes = nodes.filter(n => n.data.nodeType === 'GATEWAY_NODE');
    return gatewayNodes.map(node => validateGatewayNode(node, edges));
};

/**
 * 检查工作流中是否存在网关验证错误
 * @param nodes 所有节点
 * @param edges 所有边
 * @returns 是否有错误
 */
export const hasGatewayErrors = (
    nodes: FlowNode[],
    edges: FlowEdge[]
): boolean => {
    const results = validateAllGateways(nodes, edges);
    return results.some(r => !r.valid);
};

/**
 * 获取所有网关验证错误信息
 * @param nodes 所有节点
 * @param edges 所有边
 * @returns 错误信息数组
 */
export const getGatewayErrors = (
    nodes: FlowNode[],
    edges: FlowEdge[]
): string[] => {
    const results = validateAllGateways(nodes, edges);
    return results.flatMap(r => r.errors);
};

/**
 * 获取所有网关验证警告信息
 * @param nodes 所有节点
 * @param edges 所有边
 * @returns 警告信息数组
 */
export const getGatewayWarnings = (
    nodes: FlowNode[],
    edges: FlowEdge[]
): string[] => {
    const results = validateAllGateways(nodes, edges);
    return results.flatMap(r => r.warnings);
};

