import jingrow
import json

@jingrow.whitelist()
def execute(context=None, inputs=None, config=None, **kwargs):
    if context is None:
        context = kwargs.get("context", {})
    if inputs is None:
        inputs = kwargs.get("inputs", {})
    if config is None:
        config = kwargs.get("config", {})
    
    # 获取配置参数
    pagetype_mode = config.get("pagetype_mode", "auto")
    write_mode = config.get("write_mode", "overwrite")
    
    # 优先用前端传递的 pagetype/name（inputs 或 config），否则自动查找 node_results 里唯一的 input_record 节点
    record_type = None
    record_name = None
    
    # 根据页面类型选择模式获取record_type
    if pagetype_mode == "manual":
        # 手动指定模式：从config获取pagetype
        record_type = config.get("pagetype")
    else:
        # 自动模式：按原有逻辑获取
        # 1. 优先从 inputs 获取
        if isinstance(inputs, dict):
            record_type = inputs.get("pagetype")
        # 2. 其次从 config 获取
        if (not record_type) and isinstance(config, dict):
            record_type = config.get("pagetype")
        # 3. 最后自动查找 node_results 里唯一的 input_record 节点
        if (not record_type) and context and "node_results" in context:
            input_record_nodes = [
                v for k, v in context["node_results"].items()
                if k.startswith("input_record") and isinstance(v, dict)
            ]
            if len(input_record_nodes) == 1:
                record_type = input_record_nodes[0].get("pagetype")
    
    # 获取record_name（保持原有逻辑）
    if isinstance(inputs, dict):
        record_name = inputs.get("name")
    if (not record_name) and isinstance(config, dict):
        record_name = config.get("name")
    if (not record_name) and context and "node_results" in context:
        input_record_nodes = [
            v for k, v in context["node_results"].items()
            if k.startswith("input_record") and isinstance(v, dict)
        ]
        if len(input_record_nodes) == 1:
            record_name = input_record_nodes[0].get("name")
    
    if not isinstance(record_type, str) or not isinstance(record_name, str) or not record_type or not record_name:
        raise Exception("recordType 和 recordName 必须为非空字符串，请检查流程主输入")
    
    field_map = config.get("field_map", [])
    append_prefix = config.get("append_prefix") or ","
    
    try:
        record = jingrow.get_pg(record_type, record_name)
        if not record:
            raise Exception(f"记录 {record_name} 不存在")
        
        # 构建 label->fieldname 和 fieldname->fieldname 映射
        meta = jingrow.get_meta(record_type)
        label_to_fieldname = {}
        fieldname_set = set()
        for df in getattr(meta, 'fields', []):
            if hasattr(df, 'label') and hasattr(df, 'fieldname'):
                if df.label:
                    label_to_fieldname[str(df.label).strip()] = str(df.fieldname).strip()
                if df.fieldname:
                    fieldname_set.add(str(df.fieldname).strip())
        
        updated = False
        updated_fields = {}
        
        for mapping in field_map:
            from_field = mapping.get("from")
            to_field_raw = mapping.get("to")
            value = None
            
            # 解析 to 字段，优先用 label 匹配，找不到再用字段名
            to_field = label_to_fieldname.get(str(to_field_raw).strip())
            if not to_field and str(to_field_raw).strip() in fieldname_set:
                to_field = str(to_field_raw).strip()
            if not to_field:
                # 既不是label也不是字段名
                continue
            
            # 先从 inputs 取（如有），否则从同一分支的上游节点取
            if isinstance(inputs, dict) and from_field in inputs:
                value = inputs[from_field]
            else:
                # 获取同一分支的所有上游节点数据
                current_node_id = context.get("current_node_id")
                flow_data = context.get("flow_data", {})
                branch_upstream_nodes = get_branch_upstream_nodes(current_node_id, flow_data)
                
                if context and "node_results" in context and branch_upstream_nodes:
                    node_results = context["node_results"]
                    for upstream_node_id in branch_upstream_nodes:
                        if upstream_node_id in node_results:
                            upstream_result = node_results[upstream_node_id]
                            if isinstance(upstream_result, dict):
                                # 如果有ai_raw_response，尝试解析JSON内容
                                if "ai_raw_response" in upstream_result and isinstance(upstream_result["ai_raw_response"], str):
                                    try:
                                        raw_response = upstream_result["ai_raw_response"].strip()
                                        start_brace = raw_response.find('{')
                                        end_brace = raw_response.rfind('}')
                                        
                                        if start_brace != -1 and end_brace != -1 and end_brace > start_brace:
                                            json_content = raw_response[start_brace:end_brace + 1]
                                            parsed_json = json.loads(json_content)
                                            if isinstance(parsed_json, dict) and from_field in parsed_json:
                                                value = parsed_json[from_field]
                                                break
                                    except:
                                        continue
                                
                                # 检查其他字段
                                if value is None and from_field in upstream_result:
                                    value = upstream_result[from_field]
                                    if value is not None:
                                        break
            
            if value is not None:
                # 在追加模式下，先检查是否重复
                if write_mode == "append":
                    current_value = getattr(record, to_field, "") or ""
                    current_str = str(current_value).strip()
                    new_value_str = str(value).strip()
                    
                    # 检查是否重复
                    if current_str:
                        current_values = [v.strip() for v in current_str.split(append_prefix) if v.strip()]
                        if new_value_str in current_values:
                            # 值已存在，跳过
                            continue
                    
                    # 追加模式：将新值添加到现有值后面
                    if current_str:
                        setattr(record, to_field, current_str + append_prefix + new_value_str)
                    else:
                        setattr(record, to_field, new_value_str)
                else:
                    # 覆盖模式：直接设置新值
                    setattr(record, to_field, str(value))
                
                updated = True
                updated_fields[to_field] = str(value)
        
        # 保存并提交更改
        if updated:
            record.save()
            jingrow.db.commit()
        
        result = {
            "success": True,
            "updated_record": {
                "name": record.name,
                "pagetype": record_type
            },
            "write_mode": write_mode,
            "pagetype_mode": pagetype_mode,
            "updated_fields": updated_fields
        }
        return result
    except Exception as e:
        error_result = {
            "success": False,
            "error": str(e)
        }
        return error_result

def get_branch_upstream_nodes(current_node_id, flow_data):
    """获取同一分支的所有上游节点ID列表"""
    if not current_node_id or not flow_data:
        return []
    
    edges = flow_data.get("edges", [])
    upstream_nodes = set()
    stack = [current_node_id]
    
    while stack:
        node_id = stack.pop()
        for edge in edges:
            if edge.get("target") == node_id:
                source_id = edge.get("source")
                if source_id and source_id not in upstream_nodes:
                    upstream_nodes.add(source_id)
                    stack.append(source_id)
    
    return list(upstream_nodes) 