from functools import partial

import networkx as nx
import re
import logging
from typing import List, Dict, Any, Union

from .utils.vessel_parser import get_vessel
from .utils.logger_util import action_log
from .pump_protocol import generate_pump_protocol_with_rinsing

logger = logging.getLogger(__name__)

def debug_print(message):
    """调试输出"""
    logger.info(f"[DISSOLVE] {message}")

# 🆕 创建进度日志动作
create_action_log = partial(action_log, prefix="[DISSOLVE]")

def parse_volume_input(volume_input: Union[str, float]) -> float:
    """
    解析体积输入，支持带单位的字符串
    
    Args:
        volume_input: 体积输入（如 "10 mL", "?", 10.0）
    
    Returns:
        float: 体积（毫升）
    """
    if isinstance(volume_input, (int, float)):
        debug_print(f"📏 体积输入为数值: {volume_input}")
        return float(volume_input)
    
    if not volume_input or not str(volume_input).strip():
        debug_print(f"⚠️ 体积输入为空，返回0.0mL")
        return 0.0
    
    volume_str = str(volume_input).lower().strip()
    debug_print(f"🔍 解析体积输入: '{volume_str}'")
    
    # 处理未知体积
    if volume_str in ['?', 'unknown', 'tbd', 'to be determined']:
        default_volume = 50.0  # 默认50mL
        debug_print(f"❓ 检测到未知体积，使用默认值: {default_volume}mL 🎯")
        return default_volume
    
    # 移除空格并提取数字和单位
    volume_clean = re.sub(r'\s+', '', volume_str)
    
    # 匹配数字和单位的正则表达式
    match = re.match(r'([0-9]*\.?[0-9]+)\s*(ml|l|μl|ul|microliter|milliliter|liter)?', volume_clean)
    
    if not match:
        debug_print(f"❌ 无法解析体积: '{volume_str}'，使用默认值50mL")
        return 50.0
    
    value = float(match.group(1))
    unit = match.group(2) or 'ml'  # 默认单位为毫升
    
    # 转换为毫升
    if unit in ['l', 'liter']:
        volume = value * 1000.0  # L -> mL
        debug_print(f"🔄 体积转换: {value}L → {volume}mL")
    elif unit in ['μl', 'ul', 'microliter']:
        volume = value / 1000.0  # μL -> mL
        debug_print(f"🔄 体积转换: {value}μL → {volume}mL")
    else:  # ml, milliliter 或默认
        volume = value  # 已经是mL
        debug_print(f"✅ 体积已为mL: {volume}mL")
    
    return volume

def parse_mass_input(mass_input: Union[str, float]) -> float:
    """
    解析质量输入，支持带单位的字符串
    
    Args:
        mass_input: 质量输入（如 "2.9 g", "?", 2.5）
    
    Returns:
        float: 质量（克）
    """
    if isinstance(mass_input, (int, float)):
        debug_print(f"⚖️ 质量输入为数值: {mass_input}g")
        return float(mass_input)
    
    if not mass_input or not str(mass_input).strip():
        debug_print(f"⚠️ 质量输入为空，返回0.0g")
        return 0.0
    
    mass_str = str(mass_input).lower().strip()
    debug_print(f"🔍 解析质量输入: '{mass_str}'")
    
    # 处理未知质量
    if mass_str in ['?', 'unknown', 'tbd', 'to be determined']:
        default_mass = 1.0  # 默认1g
        debug_print(f"❓ 检测到未知质量，使用默认值: {default_mass}g 🎯")
        return default_mass
    
    # 移除空格并提取数字和单位
    mass_clean = re.sub(r'\s+', '', mass_str)
    
    # 匹配数字和单位的正则表达式
    match = re.match(r'([0-9]*\.?[0-9]+)\s*(g|mg|kg|gram|milligram|kilogram)?', mass_clean)
    
    if not match:
        debug_print(f"❌ 无法解析质量: '{mass_str}'，返回0.0g")
        return 0.0
    
    value = float(match.group(1))
    unit = match.group(2) or 'g'  # 默认单位为克
    
    # 转换为克
    if unit in ['mg', 'milligram']:
        mass = value / 1000.0  # mg -> g
        debug_print(f"🔄 质量转换: {value}mg → {mass}g")
    elif unit in ['kg', 'kilogram']:
        mass = value * 1000.0  # kg -> g
        debug_print(f"🔄 质量转换: {value}kg → {mass}g")
    else:  # g, gram 或默认
        mass = value  # 已经是g
        debug_print(f"✅ 质量已为g: {mass}g")
    
    return mass

def parse_time_input(time_input: Union[str, float]) -> float:
    """
    解析时间输入，支持带单位的字符串
    
    Args:
        time_input: 时间输入（如 "30 min", "1 h", "?", 60.0）
    
    Returns:
        float: 时间（秒）
    """
    if isinstance(time_input, (int, float)):
        debug_print(f"⏱️ 时间输入为数值: {time_input}秒")
        return float(time_input)
    
    if not time_input or not str(time_input).strip():
        debug_print(f"⚠️ 时间输入为空，返回0秒")
        return 0.0
    
    time_str = str(time_input).lower().strip()
    debug_print(f"🔍 解析时间输入: '{time_str}'")
    
    # 处理未知时间
    if time_str in ['?', 'unknown', 'tbd']:
        default_time = 600.0  # 默认10分钟
        debug_print(f"❓ 检测到未知时间，使用默认值: {default_time}s (10分钟) ⏰")
        return default_time
    
    # 移除空格并提取数字和单位
    time_clean = re.sub(r'\s+', '', time_str)
    
    # 匹配数字和单位的正则表达式
    match = re.match(r'([0-9]*\.?[0-9]+)\s*(s|sec|second|min|minute|h|hr|hour|d|day)?', time_clean)
    
    if not match:
        debug_print(f"❌ 无法解析时间: '{time_str}'，返回0s")
        return 0.0
    
    value = float(match.group(1))
    unit = match.group(2) or 's'  # 默认单位为秒
    
    # 转换为秒
    if unit in ['min', 'minute']:
        time_sec = value * 60.0  # min -> s
        debug_print(f"🔄 时间转换: {value}分钟 → {time_sec}秒")
    elif unit in ['h', 'hr', 'hour']:
        time_sec = value * 3600.0  # h -> s
        debug_print(f"🔄 时间转换: {value}小时 → {time_sec}秒")
    elif unit in ['d', 'day']:
        time_sec = value * 86400.0  # d -> s
        debug_print(f"🔄 时间转换: {value}天 → {time_sec}秒")
    else:  # s, sec, second 或默认
        time_sec = value  # 已经是s
        debug_print(f"✅ 时间已为秒: {time_sec}秒")
    
    return time_sec

def parse_temperature_input(temp_input: Union[str, float]) -> float:
    """
    解析温度输入，支持带单位的字符串
    
    Args:
        temp_input: 温度输入（如 "60 °C", "room temperature", "?", 25.0）
    
    Returns:
        float: 温度（摄氏度）
    """
    if isinstance(temp_input, (int, float)):
        debug_print(f"🌡️ 温度输入为数值: {temp_input}°C")
        return float(temp_input)
    
    if not temp_input or not str(temp_input).strip():
        debug_print(f"⚠️ 温度输入为空，使用默认室温25°C")
        return 25.0  # 默认室温
    
    temp_str = str(temp_input).lower().strip()
    debug_print(f"🔍 解析温度输入: '{temp_str}'")
    
    # 处理特殊温度描述
    temp_aliases = {
        'room temperature': 25.0,
        'rt': 25.0,
        'ambient': 25.0,
        'cold': 4.0,
        'ice': 0.0,
        'reflux': 80.0,  # 默认回流温度
        '?': 25.0,
        'unknown': 25.0
    }
    
    if temp_str in temp_aliases:
        result = temp_aliases[temp_str]
        debug_print(f"🏷️ 温度别名解析: '{temp_str}' → {result}°C")
        return result
    
    # 移除空格并提取数字和单位
    temp_clean = re.sub(r'\s+', '', temp_str)
    
    # 匹配数字和单位的正则表达式
    match = re.match(r'([0-9]*\.?[0-9]+)\s*(°c|c|celsius|°f|f|fahrenheit|k|kelvin)?', temp_clean)
    
    if not match:
        debug_print(f"❌ 无法解析温度: '{temp_str}'，使用默认值25°C")
        return 25.0
    
    value = float(match.group(1))
    unit = match.group(2) or 'c'  # 默认单位为摄氏度
    
    # 转换为摄氏度
    if unit in ['°f', 'f', 'fahrenheit']:
        temp_c = (value - 32) * 5/9  # F -> C
        debug_print(f"🔄 温度转换: {value}°F → {temp_c:.1f}°C")
    elif unit in ['k', 'kelvin']:
        temp_c = value - 273.15  # K -> C
        debug_print(f"🔄 温度转换: {value}K → {temp_c:.1f}°C")
    else:  # °c, c, celsius 或默认
        temp_c = value  # 已经是C
        debug_print(f"✅ 温度已为°C: {temp_c}°C")
    
    return temp_c

def find_solvent_vessel(G: nx.DiGraph, solvent: str) -> str:
    """增强版溶剂容器查找，支持多种匹配模式"""
    debug_print(f"🔍 开始查找溶剂 '{solvent}' 的容器...")
    
    # 🔧 方法1：直接搜索 data.reagent_name 和 config.reagent
    debug_print(f"📋 方法1: 搜索reagent字段...")
    for node in G.nodes():
        node_data = G.nodes[node].get('data', {})
        node_type = G.nodes[node].get('type', '')
        config_data = G.nodes[node].get('config', {})
        
        # 只搜索容器类型的节点
        if node_type == 'container':
            reagent_name = node_data.get('reagent_name', '').lower()
            config_reagent = config_data.get('reagent', '').lower()
            
            # 精确匹配
            if reagent_name == solvent.lower() or config_reagent == solvent.lower():
                debug_print(f"✅ 通过reagent字段精确匹配到容器: {node} 🎯")
                return node
            
            # 模糊匹配
            if (solvent.lower() in reagent_name and reagent_name) or \
               (solvent.lower() in config_reagent and config_reagent):
                debug_print(f"✅ 通过reagent字段模糊匹配到容器: {node} 🔍")
                return node
    
    # 🔧 方法2：常见的容器命名规则
    debug_print(f"📋 方法2: 使用命名规则查找...")
    solvent_clean = solvent.lower().replace(' ', '_').replace('-', '_')
    possible_names = [
        solvent_clean,
        f"flask_{solvent_clean}",
        f"bottle_{solvent_clean}",
        f"vessel_{solvent_clean}",
        f"{solvent_clean}_flask",
        f"{solvent_clean}_bottle",
        f"solvent_{solvent_clean}",
        f"reagent_{solvent_clean}",
        f"reagent_bottle_{solvent_clean}",
        f"reagent_bottle_1",  # 通用试剂瓶
        f"reagent_bottle_2",
        f"reagent_bottle_3"
    ]
    
    debug_print(f"🔍 尝试的容器名称: {possible_names[:5]}... (共{len(possible_names)}个)")
    
    for name in possible_names:
        if name in G.nodes():
            node_type = G.nodes[name].get('type', '')
            if node_type == 'container':
                debug_print(f"✅ 通过命名规则找到容器: {name} 📝")
                return name
    
    # 🔧 方法3：节点名称模糊匹配
    debug_print(f"📋 方法3: 节点名称模糊匹配...")
    for node_id in G.nodes():
        node_data = G.nodes[node_id]
        if node_data.get('type') == 'container':
            # 检查节点名称是否包含溶剂名称
            if solvent_clean in node_id.lower():
                debug_print(f"✅ 通过节点名称模糊匹配到容器: {node_id} 🔍")
                return node_id
            
            # 检查液体类型匹配
            vessel_data = node_data.get('data', {})
            liquids = vessel_data.get('liquid', [])
            for liquid in liquids:
                if isinstance(liquid, dict):
                    liquid_type = liquid.get('liquid_type') or liquid.get('name', '')
                    if liquid_type.lower() == solvent.lower():
                        debug_print(f"✅ 通过液体类型匹配到容器: {node_id} 💧")
                        return node_id
    
    # 🔧 方法4：使用第一个试剂瓶作为备选
    debug_print(f"📋 方法4: 查找备选试剂瓶...")
    for node_id in G.nodes():
        node_data = G.nodes[node_id]
        if (node_data.get('type') == 'container' and 
            ('reagent' in node_id.lower() or 'bottle' in node_id.lower() or 'flask' in node_id.lower())):
            debug_print(f"⚠️ 未找到专用容器，使用备选试剂瓶: {node_id} 🔄")
            return node_id
    
    debug_print(f"❌ 所有方法都失败了，无法找到容器!")
    raise ValueError(f"找不到溶剂 '{solvent}' 对应的容器")

def find_connected_heatchill(G: nx.DiGraph, vessel: str) -> str:
    """查找连接到指定容器的加热搅拌器"""
    debug_print(f"🔍 查找连接到容器 '{vessel}' 的加热搅拌器...")
    
    heatchill_nodes = []
    for node in G.nodes():
        node_class = G.nodes[node].get('class', '').lower()
        if 'heatchill' in node_class:
            heatchill_nodes.append(node)
            debug_print(f"📋 发现加热搅拌器: {node}")
    
    debug_print(f"📊 共找到 {len(heatchill_nodes)} 个加热搅拌器")
    
    # 查找连接到容器的加热器
    for heatchill in heatchill_nodes:
        if G.has_edge(heatchill, vessel) or G.has_edge(vessel, heatchill):
            debug_print(f"✅ 找到连接的加热搅拌器: {heatchill} 🔗")
            return heatchill
    
    # 返回第一个加热器
    if heatchill_nodes:
        debug_print(f"⚠️ 未找到直接连接的加热搅拌器，使用第一个: {heatchill_nodes[0]} 🔄")
        return heatchill_nodes[0]
    
    debug_print(f"❌ 未找到任何加热搅拌器")
    return ""

def find_connected_stirrer(G: nx.DiGraph, vessel: str) -> str:
    """查找连接到指定容器的搅拌器"""
    debug_print(f"🔍 查找连接到容器 '{vessel}' 的搅拌器...")
    
    stirrer_nodes = []
    for node in G.nodes():
        node_class = G.nodes[node].get('class', '').lower()
        if 'stirrer' in node_class:
            stirrer_nodes.append(node)
            debug_print(f"📋 发现搅拌器: {node}")
    
    debug_print(f"📊 共找到 {len(stirrer_nodes)} 个搅拌器")
    
    # 查找连接到容器的搅拌器
    for stirrer in stirrer_nodes:
        if G.has_edge(stirrer, vessel) or G.has_edge(vessel, stirrer):
            debug_print(f"✅ 找到连接的搅拌器: {stirrer} 🔗")
            return stirrer
    
    # 返回第一个搅拌器
    if stirrer_nodes:
        debug_print(f"⚠️ 未找到直接连接的搅拌器，使用第一个: {stirrer_nodes[0]} 🔄")
        return stirrer_nodes[0]
    
    debug_print(f"❌ 未找到任何搅拌器")
    return ""

def find_solid_dispenser(G: nx.DiGraph) -> str:
    """查找固体加样器"""
    debug_print(f"🔍 查找固体加样器...")
    
    for node in G.nodes():
        node_class = G.nodes[node].get('class', '').lower()
        if 'solid_dispenser' in node_class or 'dispenser' in node_class:
            debug_print(f"✅ 找到固体加样器: {node} 🥄")
            return node
    
    debug_print(f"❌ 未找到固体加样器")
    return ""

def generate_dissolve_protocol(
    G: nx.DiGraph,
    vessel: dict,  # 🔧 修改：从字符串改为字典类型
    # 🔧 修复：按照checklist.md的DissolveProtocol参数
    solvent: str = "",
    volume: Union[str, float] = 0.0,
    amount: str = "",
    temp: Union[str, float] = 25.0,
    time: Union[str, float] = 0.0,
    stir_speed: float = 300.0,
    # 🔧 关键修复：添加缺失的参数，防止"unexpected keyword argument"错误
    mass: Union[str, float] = 0.0,  # 这个参数在action文件中存在，必须包含
    mol: str = "",                  # 这个参数在action文件中存在，必须包含
    reagent: str = "",              # 这个参数在action文件中存在，必须包含
    event: str = "",                # 这个参数在action文件中存在，必须包含
    **kwargs                        # 🔧 关键：接受所有其他参数，防止unexpected keyword错误
) -> List[Dict[str, Any]]:
    """
    生成溶解操作的协议序列 - 增强版
    
    🔧 修复要点：
    1. 修改vessel参数类型为dict，并提取vessel_id
    2. 添加action文件中的所有参数（mass, mol, reagent, event）
    3. 使用 **kwargs 接受所有额外参数，防止 unexpected keyword argument 错误
    4. 支持固体溶解和液体溶解两种模式
    5. 添加详细的体积运算逻辑
    
    支持两种溶解模式：
    1. 液体溶解：指定 solvent + volume，使用pump protocol转移溶剂
    2. 固体溶解：指定 mass/mol + reagent，使用固体加样器添加固体试剂
    
    支持所有XDL参数和单位：
    - volume: "10 mL", "?" 或数值
    - mass: "2.9 g", "?" 或数值  
    - temp: "60 °C", "room temperature", "?" 或数值
    - time: "30 min", "1 h", "?" 或数值
    - mol: "0.12 mol", "16.2 mmol"
    """
    
    # 🔧 核心修改：从字典中提取容器ID
    vessel_id, vessel_data = get_vessel(vessel)
    
    debug_print("=" * 60)
    debug_print("🧪 开始生成溶解协议")
    debug_print(f"📋 原始参数:")
    debug_print(f"  🥼 vessel: {vessel} (ID: {vessel_id})")
    debug_print(f"  💧 solvent: '{solvent}'")
    debug_print(f"  📏 volume: {volume} (类型: {type(volume)})")
    debug_print(f"  ⚖️ mass: {mass} (类型: {type(mass)})")
    debug_print(f"  🌡️ temp: {temp} (类型: {type(temp)})")
    debug_print(f"  ⏱️ time: {time} (类型: {type(time)})")
    debug_print(f"  🧪 reagent: '{reagent}'")
    debug_print(f"  🧬 mol: '{mol}'")
    debug_print(f"  🎯 event: '{event}'")
    debug_print(f"  📦 kwargs: {kwargs}")  # 显示额外参数
    debug_print("=" * 60)
    
    action_sequence = []
    
    # === 参数验证 ===
    debug_print("🔍 步骤1: 参数验证...")
    action_sequence.append(create_action_log(f"开始溶解操作 - 容器: {vessel_id}", "🎬"))
    
    if not vessel_id:
        debug_print("❌ vessel 参数不能为空")
        raise ValueError("vessel 参数不能为空")
    
    if vessel_id not in G.nodes():
        debug_print(f"❌ 容器 '{vessel_id}' 不存在于系统中")
        raise ValueError(f"容器 '{vessel_id}' 不存在于系统中")
    
    debug_print("✅ 基本参数验证通过")
    action_sequence.append(create_action_log("参数验证通过", "✅"))
    
    # 🔧 新增：记录溶解前的容器状态
    debug_print("🔍 记录溶解前容器状态...")
    original_liquid_volume = 0.0
    if "data" in vessel and "liquid_volume" in vessel["data"]:
        current_volume = vessel["data"]["liquid_volume"]
        if isinstance(current_volume, list) and len(current_volume) > 0:
            original_liquid_volume = current_volume[0]
        elif isinstance(current_volume, (int, float)):
            original_liquid_volume = current_volume
    debug_print(f"📊 溶解前液体体积: {original_liquid_volume:.2f}mL")
    
    # === 🔧 关键修复：参数解析 ===
    debug_print("🔍 步骤2: 参数解析...")
    action_sequence.append(create_action_log("正在解析溶解参数...", "🔍"))
    
    # 解析各种参数为数值
    final_volume = parse_volume_input(volume)
    final_mass = parse_mass_input(mass)
    final_temp = parse_temperature_input(temp)
    final_time = parse_time_input(time)
    
    debug_print(f"📊 解析结果:")
    debug_print(f"  📏 体积: {final_volume}mL")
    debug_print(f"  ⚖️ 质量: {final_mass}g")
    debug_print(f"  🌡️ 温度: {final_temp}°C")
    debug_print(f"  ⏱️ 时间: {final_time}s")
    debug_print(f"  🧪 试剂: '{reagent}'")
    debug_print(f"  🧬 摩尔: '{mol}'")
    debug_print(f"  🎯 事件: '{event}'")
    
    # === 判断溶解类型 ===
    debug_print("🔍 步骤3: 判断溶解类型...")
    action_sequence.append(create_action_log("正在判断溶解类型...", "🔍"))
    
    # 判断是固体溶解还是液体溶解
    is_solid_dissolve = (final_mass > 0 or (mol and mol.strip() != "") or (reagent and reagent.strip() != ""))
    is_liquid_dissolve = (final_volume > 0 and solvent and solvent.strip() != "")
    
    if not is_solid_dissolve and not is_liquid_dissolve:
        # 默认为液体溶解，50mL
        is_liquid_dissolve = True
        final_volume = 50.0
        if not solvent:
            solvent = "water"  # 默认溶剂
        debug_print("⚠️ 未明确指定溶解参数，默认为50mL水溶解")
    
    dissolve_type = "固体溶解" if is_solid_dissolve else "液体溶解"
    dissolve_emoji = "🧂" if is_solid_dissolve else "💧"
    debug_print(f"📋 溶解类型: {dissolve_type} {dissolve_emoji}")
    
    action_sequence.append(create_action_log(f"确定溶解类型: {dissolve_type} {dissolve_emoji}", "📋"))
    
    # === 查找设备 ===
    debug_print("🔍 步骤4: 查找设备...")
    action_sequence.append(create_action_log("正在查找相关设备...", "🔍"))
    
    # 查找加热搅拌器
    heatchill_id = find_connected_heatchill(G, vessel_id)
    stirrer_id = find_connected_stirrer(G, vessel_id)
    
    # 优先使用加热搅拌器，否则使用独立搅拌器
    stir_device_id = heatchill_id or stirrer_id
    
    debug_print(f"📊 设备映射:")
    debug_print(f"  🔥 加热器: '{heatchill_id}'")
    debug_print(f"  🌪️ 搅拌器: '{stirrer_id}'")
    debug_print(f"  🎯 使用设备: '{stir_device_id}'")
    
    if heatchill_id:
        action_sequence.append(create_action_log(f"找到加热搅拌器: {heatchill_id}", "🔥"))
    elif stirrer_id:
        action_sequence.append(create_action_log(f"找到搅拌器: {stirrer_id}", "🌪️"))
    else:
        action_sequence.append(create_action_log("未找到搅拌设备，将跳过搅拌", "⚠️"))
    
    # === 执行溶解流程 ===
    debug_print("🔍 步骤5: 执行溶解流程...")
    
    try:
        # 步骤5.1: 启动加热搅拌（如果需要）
        if stir_device_id and (final_temp > 25.0 or final_time > 0 or stir_speed > 0):
            debug_print(f"🔍 5.1: 启动加热搅拌，温度: {final_temp}°C")
            action_sequence.append(create_action_log(f"准备加热搅拌 (目标温度: {final_temp}°C)", "🔥"))
            
            if heatchill_id and (final_temp > 25.0 or final_time > 0):
                # 使用加热搅拌器
                action_sequence.append(create_action_log(f"启动加热搅拌器 {heatchill_id}", "🔥"))
                
                heatchill_action = {
                    "device_id": heatchill_id,
                    "action_name": "heat_chill_start",
                    "action_kwargs": {
                        "vessel": {"id": vessel_id},
                        "temp": final_temp,
                        "purpose": f"溶解准备 - {event}" if event else "溶解准备"
                    }
                }
                action_sequence.append(heatchill_action)
                
                # 等待温度稳定
                if final_temp > 25.0:
                    wait_time = min(60, abs(final_temp - 25.0) * 1.5)
                    action_sequence.append(create_action_log(f"等待温度稳定 ({wait_time:.0f}秒)", "⏳"))
                    action_sequence.append({
                        "action_name": "wait",
                        "action_kwargs": {"time": wait_time}
                    })
            
            elif stirrer_id:
                # 使用独立搅拌器
                action_sequence.append(create_action_log(f"启动搅拌器 {stirrer_id} (速度: {stir_speed}rpm)", "🌪️"))
                
                stir_action = {
                    "device_id": stirrer_id,
                    "action_name": "start_stir",
                    "action_kwargs": {
                        "vessel": {"id": vessel_id},
                        "stir_speed": stir_speed,
                        "purpose": f"溶解搅拌 - {event}" if event else "溶解搅拌"
                    }
                }
                action_sequence.append(stir_action)
                
                # 等待搅拌稳定
                action_sequence.append(create_action_log("等待搅拌稳定...", "⏳"))
                action_sequence.append({
                    "action_name": "wait",
                    "action_kwargs": {"time": 5}
                })
        
        if is_solid_dissolve:
            # === 固体溶解路径 ===
            debug_print(f"🔍 5.2: 使用固体溶解路径")
            action_sequence.append(create_action_log("开始固体溶解流程", "🧂"))
            
            solid_dispenser = find_solid_dispenser(G)
            if solid_dispenser:
                action_sequence.append(create_action_log(f"找到固体加样器: {solid_dispenser}", "🥄"))
                
                # 固体加样
                add_kwargs = {
                    "vessel": {"id": vessel_id},
                    "reagent": reagent or amount or "solid reagent",
                    "purpose": f"溶解固体试剂 - {event}" if event else "溶解固体试剂",
                    "event": event
                }
                
                if final_mass > 0:
                    add_kwargs["mass"] = str(final_mass)
                    action_sequence.append(create_action_log(f"准备添加固体: {final_mass}g", "⚖️"))
                if mol and mol.strip():
                    add_kwargs["mol"] = mol
                    action_sequence.append(create_action_log(f"按摩尔数添加: {mol}", "🧬"))
                
                action_sequence.append(create_action_log("开始固体加样操作", "🥄"))
                action_sequence.append({
                    "device_id": solid_dispenser,
                    "action_name": "add_solid",
                    "action_kwargs": add_kwargs
                })
                
                debug_print(f"✅ 固体加样完成")
                action_sequence.append(create_action_log("固体加样完成", "✅"))
                
                # 🔧 新增：固体溶解体积运算 - 固体本身不会显著增加体积，但可能有少量变化
                debug_print(f"🔧 固体溶解 - 体积变化很小，主要是质量变化")
                # 固体通常不会显著改变液体体积，这里只记录日志
                action_sequence.append(create_action_log(f"固体已添加: {final_mass}g", "📊"))
                
            else:
                debug_print("⚠️ 未找到固体加样器，跳过固体添加")
                action_sequence.append(create_action_log("未找到固体加样器，无法添加固体", "❌"))
        
        elif is_liquid_dissolve:
            # === 液体溶解路径 ===
            debug_print(f"🔍 5.3: 使用液体溶解路径")
            action_sequence.append(create_action_log("开始液体溶解流程", "💧"))
            
            # 查找溶剂容器
            action_sequence.append(create_action_log("正在查找溶剂容器...", "🔍"))
            try:
                solvent_vessel = find_solvent_vessel(G, solvent)
                action_sequence.append(create_action_log(f"找到溶剂容器: {solvent_vessel}", "🧪"))
            except ValueError as e:
                debug_print(f"⚠️ {str(e)}，跳过溶剂添加")
                action_sequence.append(create_action_log(f"溶剂容器查找失败: {str(e)}", "❌"))
                solvent_vessel = None
            
            if solvent_vessel:
                # 计算流速 - 溶解时通常用较慢的速度，避免飞溅
                flowrate = 1.0  # 较慢的注入速度
                transfer_flowrate = 0.5  # 较慢的转移速度
                
                action_sequence.append(create_action_log(f"设置流速: {flowrate}mL/min (缓慢注入)", "⚡"))
                action_sequence.append(create_action_log(f"开始转移 {final_volume}mL {solvent}", "🚰"))
                
                # 调用pump protocol
                pump_actions = generate_pump_protocol_with_rinsing(
                    G=G,
                    from_vessel=solvent_vessel,
                    to_vessel=vessel_id,
                    volume=final_volume,
                    amount=amount,
                    time=0.0,  # 不在pump level控制时间
                    viscous=False,
                    rinsing_solvent="",
                    rinsing_volume=0.0,
                    rinsing_repeats=0,
                    solid=False,
                    flowrate=flowrate,
                    transfer_flowrate=transfer_flowrate,
                    rate_spec="",
                    event=event,
                    through="",
                    **kwargs
                )
                action_sequence.extend(pump_actions)
                debug_print(f"✅ 溶剂转移完成，添加了 {len(pump_actions)} 个动作")
                action_sequence.append(create_action_log(f"溶剂转移完成 ({len(pump_actions)} 个操作)", "✅"))
                
                # 🔧 新增：液体溶解体积运算 - 添加溶剂后更新容器体积
                debug_print(f"🔧 更新容器液体体积 - 添加溶剂 {final_volume:.2f}mL")
                
                # 确保vessel有data字段
                if "data" not in vessel:
                    vessel["data"] = {}
                
                if "liquid_volume" in vessel["data"]:
                    current_volume = vessel["data"]["liquid_volume"]
                    if isinstance(current_volume, list):
                        if len(current_volume) > 0:
                            vessel["data"]["liquid_volume"][0] += final_volume
                            debug_print(f"📊 添加溶剂后体积: {vessel['data']['liquid_volume'][0]:.2f}mL (+{final_volume:.2f}mL)")
                        else:
                            vessel["data"]["liquid_volume"] = [final_volume]
                            debug_print(f"📊 初始化溶解体积: {final_volume:.2f}mL")
                    elif isinstance(current_volume, (int, float)):
                        vessel["data"]["liquid_volume"] += final_volume
                        debug_print(f"📊 添加溶剂后体积: {vessel['data']['liquid_volume']:.2f}mL (+{final_volume:.2f}mL)")
                    else:
                        vessel["data"]["liquid_volume"] = final_volume
                        debug_print(f"📊 重置体积为: {final_volume:.2f}mL")
                else:
                    vessel["data"]["liquid_volume"] = final_volume
                    debug_print(f"📊 创建新体积记录: {final_volume:.2f}mL")
                
                # 🔧 同时更新图中的容器数据
                if vessel_id in G.nodes():
                    if 'data' not in G.nodes[vessel_id]:
                        G.nodes[vessel_id]['data'] = {}
                    
                    vessel_node_data = G.nodes[vessel_id]['data']
                    current_node_volume = vessel_node_data.get('liquid_volume', 0.0)
                    
                    if isinstance(current_node_volume, list):
                        if len(current_node_volume) > 0:
                            G.nodes[vessel_id]['data']['liquid_volume'][0] += final_volume
                        else:
                            G.nodes[vessel_id]['data']['liquid_volume'] = [final_volume]
                    else:
                        G.nodes[vessel_id]['data']['liquid_volume'] = current_node_volume + final_volume
                    
                    debug_print(f"✅ 图节点体积数据已更新")
                
                action_sequence.append(create_action_log(f"容器体积已更新 (+{final_volume:.2f}mL)", "📊"))
                
                # 溶剂添加后等待
                action_sequence.append(create_action_log("溶剂添加后短暂等待...", "⏳"))
                action_sequence.append({
                    "action_name": "wait",
                    "action_kwargs": {"time": 5}
                })
        
        # 步骤5.4: 等待溶解完成
        if final_time > 0:
            debug_print(f"🔍 5.4: 等待溶解完成 - {final_time}s")
            wait_minutes = final_time / 60
            action_sequence.append(create_action_log(f"开始溶解等待 ({wait_minutes:.1f}分钟)", "⏰"))
            
            if heatchill_id:
                # 使用定时加热搅拌
                action_sequence.append(create_action_log(f"使用加热搅拌器进行定时溶解", "🔥"))
                
                dissolve_action = {
                    "device_id": heatchill_id,
                    "action_name": "heat_chill",
                    "action_kwargs": {
                        "vessel": {"id": vessel_id},
                        "temp": final_temp,
                        "time": final_time,
                        "stir": True,
                        "stir_speed": stir_speed,
                        "purpose": f"溶解等待 - {event}" if event else "溶解等待"
                    }
                }
                action_sequence.append(dissolve_action)
            
            elif stirrer_id:
                # 使用定时搅拌
                action_sequence.append(create_action_log(f"使用搅拌器进行定时溶解", "🌪️"))
                
                stir_action = {
                    "device_id": stirrer_id,
                    "action_name": "stir",
                    "action_kwargs": {
                        "vessel": {"id": vessel_id},
                        "stir_time": final_time,
                        "stir_speed": stir_speed,
                        "settling_time": 0,
                        "purpose": f"溶解搅拌 - {event}" if event else "溶解搅拌"
                    }
                }
                action_sequence.append(stir_action)
            
            else:
                # 简单等待
                action_sequence.append(create_action_log(f"简单等待溶解完成", "⏳"))
                action_sequence.append({
                    "action_name": "wait",
                    "action_kwargs": {"time": final_time}
                })
        
        # 步骤5.5: 停止加热搅拌（如果需要）
        if heatchill_id and final_time == 0 and final_temp > 25.0:
            debug_print(f"🔍 5.5: 停止加热器")
            action_sequence.append(create_action_log("停止加热搅拌器", "🛑"))
            
            stop_action = {
                "device_id": heatchill_id,
                "action_name": "heat_chill_stop",
                "action_kwargs": {
                    "vessel": {"id": vessel_id},
                }
            }
            action_sequence.append(stop_action)
        
    except Exception as e:
        debug_print(f"❌ 溶解流程执行失败: {str(e)}")
        action_sequence.append(create_action_log(f"溶解流程失败: {str(e)}", "❌"))
        # 添加错误日志
        action_sequence.append({
            "device_id": "system",
            "action_name": "log_message",
            "action_kwargs": {
                "message": f"溶解失败: {str(e)}"
            }
        })
    
    # 🔧 新增：溶解完成后的状态报告
    final_liquid_volume = 0.0
    if "data" in vessel and "liquid_volume" in vessel["data"]:
        current_volume = vessel["data"]["liquid_volume"]
        if isinstance(current_volume, list) and len(current_volume) > 0:
            final_liquid_volume = current_volume[0]
        elif isinstance(current_volume, (int, float)):
            final_liquid_volume = current_volume
    
    # === 最终结果 ===
    debug_print("=" * 60)
    debug_print(f"🎉 溶解协议生成完成")
    debug_print(f"📊 协议统计:")
    debug_print(f"  📋 总动作数: {len(action_sequence)}")
    debug_print(f"  🥼 容器: {vessel_id}")
    debug_print(f"  {dissolve_emoji} 溶解类型: {dissolve_type}")
    if is_liquid_dissolve:
        debug_print(f"  💧 溶剂: {solvent} ({final_volume}mL)")
    if is_solid_dissolve:
        debug_print(f"  🧪 试剂: {reagent}")
        debug_print(f"  ⚖️ 质量: {final_mass}g")
        debug_print(f"  🧬 摩尔: {mol}")
    debug_print(f"  🌡️ 温度: {final_temp}°C")
    debug_print(f"  ⏱️ 时间: {final_time}s")
    debug_print(f"  📊 溶解前体积: {original_liquid_volume:.2f}mL")
    debug_print(f"  📊 溶解后体积: {final_liquid_volume:.2f}mL")
    debug_print("=" * 60)
    
    # 添加完成日志
    summary_msg = f"溶解协议完成: {vessel_id}"
    if is_liquid_dissolve:
        summary_msg += f" (使用 {final_volume}mL {solvent})"
    if is_solid_dissolve:
        summary_msg += f" (溶解 {final_mass}g {reagent})"
    
    action_sequence.append(create_action_log(summary_msg, "🎉"))
    
    return action_sequence


# === 便捷函数 ===
# 🔧 修改便捷函数的参数类型

def dissolve_solid_by_mass(G: nx.DiGraph, vessel: dict, reagent: str, mass: Union[str, float], 
                          temp: Union[str, float] = 25.0, time: Union[str, float] = "10 min") -> List[Dict[str, Any]]:
    """按质量溶解固体"""
    vessel_id = vessel["id"]
    debug_print(f"🧂 快速固体溶解: {reagent} ({mass}) → {vessel_id}")
    return generate_dissolve_protocol(
        G, vessel, 
        mass=mass, 
        reagent=reagent,
        temp=temp, 
        time=time
    )

def dissolve_solid_by_moles(G: nx.DiGraph, vessel: dict, reagent: str, mol: str, 
                           temp: Union[str, float] = 25.0, time: Union[str, float] = "10 min") -> List[Dict[str, Any]]:
    """按摩尔数溶解固体"""
    vessel_id = vessel["id"]
    debug_print(f"🧬 按摩尔数溶解固体: {reagent} ({mol}) → {vessel_id}")
    return generate_dissolve_protocol(
        G, vessel, 
        mol=mol, 
        reagent=reagent,
        temp=temp, 
        time=time
    )

def dissolve_with_solvent(G: nx.DiGraph, vessel: dict, solvent: str, volume: Union[str, float], 
                         temp: Union[str, float] = 25.0, time: Union[str, float] = "5 min") -> List[Dict[str, Any]]:
    """用溶剂溶解"""
    vessel_id = vessel["id"]
    debug_print(f"💧 溶剂溶解: {solvent} ({volume}) → {vessel_id}")
    return generate_dissolve_protocol(
        G, vessel, 
        solvent=solvent, 
        volume=volume,
        temp=temp, 
        time=time
    )

def dissolve_at_room_temp(G: nx.DiGraph, vessel: dict, solvent: str, volume: Union[str, float]) -> List[Dict[str, Any]]:
    """室温溶解"""
    vessel_id = vessel["id"]
    debug_print(f"🌡️ 室温溶解: {solvent} ({volume}) → {vessel_id}")
    return generate_dissolve_protocol(
        G, vessel, 
        solvent=solvent, 
        volume=volume,
        temp="room temperature", 
        time="5 min"
    )

def dissolve_with_heating(G: nx.DiGraph, vessel: dict, solvent: str, volume: Union[str, float], 
                         temp: Union[str, float] = "60 °C", time: Union[str, float] = "15 min") -> List[Dict[str, Any]]:
    """加热溶解"""
    vessel_id = vessel["id"]
    debug_print(f"🔥 加热溶解: {solvent} ({volume}) → {vessel_id} @ {temp}")
    return generate_dissolve_protocol(
        G, vessel, 
        solvent=solvent, 
        volume=volume,
        temp=temp, 
        time=time
    )

# 测试函数
def test_dissolve_protocol():
    """测试溶解协议的各种参数解析"""
    debug_print("=== DISSOLVE PROTOCOL 增强版测试 ===")
    
    # 测试体积解析
    debug_print("💧 测试体积解析...")
    volumes = ["10 mL", "?", 10.0, "1 L", "500 μL"]
    for vol in volumes:
        result = parse_volume_input(vol)
        debug_print(f"📏 体积解析: {vol} → {result}mL")
    
    # 测试质量解析
    debug_print("⚖️ 测试质量解析...")
    masses = ["2.9 g", "?", 2.5, "500 mg"]
    for mass in masses:
        result = parse_mass_input(mass)
        debug_print(f"⚖️ 质量解析: {mass} → {result}g")
    
    # 测试温度解析
    debug_print("🌡️ 测试温度解析...")
    temps = ["60 °C", "room temperature", "?", 25.0, "reflux"]
    for temp in temps:
        result = parse_temperature_input(temp)
        debug_print(f"🌡️ 温度解析: {temp} → {result}°C")
    
    # 测试时间解析
    debug_print("⏱️ 测试时间解析...")
    times = ["30 min", "1 h", "?", 60.0]
    for time in times:
        result = parse_time_input(time)
        debug_print(f"⏱️ 时间解析: {time} → {result}s")
    
    debug_print("✅ 测试完成")

if __name__ == "__main__":
    test_dissolve_protocol()