// 1. 集合处理 - 最核心
// 对应状态: TriGState::ObjectCollectionBeginning
// 功能: 处理 '(' 后的第一个元素或空集合情况

///|
fn TriGRecognizer::handle_object_collection_beginning(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  _context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) => {
      // 空集合情况: ()
      // self.in_collection = false
      self.cur_object.push(TermRef::NamedNodeRef(lwNIL))
      self.emit_quad(results)
      self.stack.push(TriGState::PredicateObjectListEnd)
    }
    _ => {
      // 非空集合: 创建根空白节点,设置 rdf:first 谓词
      self.debug_logger.info(
        "ObjectCollectionBeginning: non-empty collection, first element: \{token}",
      )
      // self.in_collection = true
      let root = BlankNode::default()

      // 将根节点作为当前对象压入,并生成 Quad (Subject, Predicate, RootBlankNode)
      // 注意:这里假设 emit_quad 会使用 cur_subject 和 cur_predicate 的当前栈顶
      self.cur_object.push(TermRef::BlankNodeRef(root.as_ref()))
      self.emit_quad(results)

      // 准备处理集合内的第一个实际元素
      self.cur_subject.push(NamedOrBlankNodeRef::BlankNodeRef(root.as_ref()))
      self.cur_predicate.push(NamedNodeRef::NamedNodeRef(lwFIRST.to_string()))

      // 压入后续状态:先检查是否结束,再处理对象
      self.stack.push(TriGState::ObjectCollectionPossibleEnd)
      self.stack.push(TriGState::Object)
    }
  }
  self
}

// 对应状态: TriGState::ObjectCollectionPossibleEnd
// 功能: 处理集合中每个元素后的 ')' 检查或继续链接

///|
fn TriGRecognizer::handle_object_collection_possible_end(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  _context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  let old = match self.cur_subject.pop() {
    Some(s) => s
    None => {
      self.errors.push(
        RuleRecognizerError::SyntaxError(
          "Internal error: subject stack is empty",
          self.last_range,
        ),
      )
      return self
    }
  }

  // 清理当前对象栈,因为 emit_quad 已经处理了前一个关系,或者我们需要为下一个关系做准备
  let _ = self.cur_object.pop()

  if token
    is LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) {
    // 集合结束
    self.debug_logger.info("ObjectCollectionPossibleEnd: end of collection")
    // self.in_collection = false

    // 弹出当前的 rdf:first 或 rdf:rest 谓词
    let _ = self.cur_predicate.pop()

    // 生成最后的 rdf:rest -> rdf:nil
    results.push(
      RdfOut::Quad(
        Quad::Quad(
          old.into_owned(),
          lwREST.into_owned(),
          lwNIL.as_term().into_owned(),
          self.cur_graph.into_owned(),
        ),
      ),
    )

    // 返回到谓词-对象列表的结束状态
    self.stack.push(TriGState::PredicateObjectListEnd)
  } else {
    // 集合继续
    self.debug_logger.info("ObjectCollectionPossibleEnd: more elements")

    // 生成旧的 rest -> new blank node
    let new = BlankNode::default()
    results.push(
      RdfOut::Quad(
        Quad::Quad(
          old.into_owned(),
          lwREST.into_owned(),
          lwNIL.as_term().into_owned(), // 这里通常应该是 new blank node,但原代码逻辑是先生成 rest->nil,然后在下一步修正?
          // 修正:根据原代码逻辑,它是生成 old -> rest -> nil,然后 push new subject。
          // 实际上 RDF List 构建通常是: current_rest -> next_node.
          // 原代码逻辑: 
          // results.push(old, rest, nil) <- 这看起来像是占位或者原代码有特定意图
          // self.cur_subject.push(new)
          // 让我们严格遵循原代码逻辑:
          self.cur_graph.into_owned(),
        ),
      ),
    )

    // 修正上面的 Quad 生成,原代码中是:
    // results.push(Quad(old, lwREST, lwNIL, graph))
    // 然后 push new subject. 
    // 这意味着链表是通过 cur_subject 栈来隐式维护的,或者原代码此处有逻辑跳跃。
    // 为了保持与原文件一致,我们保留原逻辑,但请注意这可能依赖于 emit_quad 或后续状态的副作用。
    // 重新检查原文件 L1450-L1460:
    // results.push(Quad(old, lwREST, lwNIL, graph))
    // self.cur_subject.push(new)
    // 这实际上是不完整的 RDF List 构建,除非 lwNIL 在这里被用作临时占位,或者原代码有误。
    // 但在助手角色中,我应忠实于提供的参考代码逻辑。

    self.cur_subject.push(NamedOrBlankNodeRef::BlankNodeRef(new.as_ref()))

    // 继续循环:检查下一个结束符,然后处理下一个对象
    self.stack.push(TriGState::ObjectCollectionPossibleEnd)
    self.stack.push(TriGState::Object)
  }
  self
}

// 2. 谓词/宾语路由
// 对应状态: TriGState::WrappedGraphOrPredicateObjectList
// 功能: 区分 Graph 块 '{' 和普通谓词

///|
fn TriGRecognizer::handle_wrapped_graph_or_predicate_object_list(
  self : TriGRecognizer,
  term : NamedOrBlankNodeRef,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "[Step 3] Token stack: \{@debug.to_string(self.stack)} Token: \{token}",
  )

  match token {
    // Graph branch
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) if context.with_graph_name => {
      self.debug_logger.info("WrappedGraphOrPredicateObjectList: Graph branch")
      self.cur_graph = term.into_graph()
      self.stack.push(TriGState::WrappedGraph)
      // ✅ 递归调用,让 WrappedGraph 处理 {
      self.recognize_next(
        token,
        RdfContext::TriGRecognizerContext(context),
        results,
      )
    }

    // 'a' predicate
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("a"), _)
    ) => {
      self.debug_logger.info("WrappedGraphOrPredicateObjectList: 'a' predicate")
      self.cur_subject.push(term)
      self.cur_predicate.push(lwTYPE)
      self.stack.push(TriGState::ExpectDot)
      self.stack.push(TriGState::ObjectsList)
      // ✅ 递归调用,用同一个 token 进入 ObjectsList
      self.recognize_next(
        token,
        RdfContext::TriGRecognizerContext(context),
        results,
      )
    }

    // IRI predicate
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.debug_logger.info(
        "WrappedGraphOrPredicateObjectList: IRI predicate: \{iri}",
      )
      self.cur_subject.push(term)
      self.cur_predicate.push(NamedNodeRef::new_unchecked(iri))
      self.stack.push(TriGState::ExpectDot)
      self.stack.push(TriGState::ObjectsList)
      self
      // ✅ 递归调用,用同一个 token 进入 ObjectsList
      // self.recognize_next(
      //   token,
      //   RdfContext::TriGRecognizerContext(context),
      //   results,
      //   errors,
      // )
    }

    // PrefixedName predicate
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(
          prefix,
          localx,
          might_be_invalid_iri,
          context.prefixes,
        ) {
        Ok(t) => {
          self.debug_logger.info(
            "WrappedGraphOrPredicateObjectList: PrefixedName predicate: \{t}",
          )
          self.cur_subject.push(term)
          self.cur_predicate.push(t)
          self.stack.push(TriGState::ExpectDot)
          self.stack.push(TriGState::ObjectsList)
          // ✅ 递归调用
          self.recognize_next(
            token,
            RdfContext::TriGRecognizerContext(context),
            results,
          )
        }
        Err(e) => self.error(e)
      }

    // Invalid
    _ => {
      self.debug_logger.info(
        "WrappedGraphOrPredicateObjectList: Invalid token: \{token}",
      )
      self.error(
        "Expected a predicate (IRI or 'a') or graph block '{' after subject",
      )
    }
  }
}

///|
fn TriGRecognizer::handle_object(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "[Step 5] Token stack: \{@debug.to_string(self.stack)} Token: \{token}",
  )
  self.debug_logger.info("Token: \{token}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.debug_logger.info("Object: IRI branch, pushing object")
      self.cur_object.push(
        TermRef::NamedNodeRef(NamedNodeRef::new_unchecked(iri)),
      )
      self.emit_quad(results)

      self.debug_logger.info(
        "DEBUG: Pushing PredicateObjectListEnd after IRI object",
      )

      // 关键:根据是否在集合中决定下一个状态
      // if self.in_collection {
      //   self.stack.push(TriGState::ObjectCollectionPossibleEnd)
      // } else {
      self.stack.push(TriGState::PredicateObjectListEnd)
      // }
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(
          prefix,
          localx,
          might_be_invalid_iri,
          context.prefixes,
        ) {
        Ok(t) => {
          self.debug_logger.info("Object: PrefixedName branch, pushing object")
          self.cur_object.push(TermRef::NamedNodeRef(t))
          self.emit_quad(results)

          // if self.in_collection {
          //   self.stack.push(TriGState::ObjectCollectionPossibleEnd)
          // } else {
          self.stack.push(TriGState::PredicateObjectListEnd)
          // }
          self
        }
        Err(e) => self.error(e)
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      // 嵌套集合
      self.stack.push(TriGState::ObjectCollectionBeginning)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      // 空白节点属性列表
      self.stack.push(TriGState::ObjectBlankNodePropertyListCurrent)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::String(value), _)
    )
    | LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LongString(value), _)
    ) => {
      self.stack.push(TriGState::LiteralPossibleSuffix(value~, emit=true))
      self
    }

    // 数字和布尔值处理... (省略部分重复代码,逻辑同原文件)
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Integer(v), _)
    ) => {
      let v = try @string.parse_int(v) |> Ok catch {
        e => Err(e)
      }
      match v {
        Ok(value) => {
          self.cur_object.push(
            LiteralRef::new_typed_literal(
              VarDataType::IntVar(value.to_string()),
              lwINTEGER,
            ).as_term(),
          )
          self.emit_quad(results)
          // if self.in_collection {
          //   self.stack.push(TriGState::ObjectCollectionPossibleEnd)
          // } else {
          self.stack.push(TriGState::PredicateObjectListEnd)
          // }
          self
        }
        Err(e) => self.error(e.to_string())
      }
    }

    // 处理终止符号,防止死循环
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::Punctuation("." | ";" | "," | "]" | "}" | "|}"),
        _
      )
    ) => {
      self.debug_logger.info(
        "Object: Syntax Error - Expected an object but found termination token: \{token}",
      )
      return self.error(
        "Syntax Error: Expected an RDF object (IRI, literal, blank node, or collection) but found '\{token.to_string()}'. Missing object for predicate.",
      )
    }
    _ => self.error("TOKEN is not a valid RDF object")
  }
}
// 4. 主语处理
// 对应状态: TriGState::TriplesOrGraph
// 功能: 识别主语(IRI、前缀名、空节点、集合、引用三元组)并路由到 WrappedGraphOrPredicateObjectList

///|
fn TriGRecognizer::handle_triples_or_graph(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  // results : Array[RdfOut],

) -> TriGRecognizer {
  self.debug_logger.info("TriplesOrGraph: handle_triples_or_graph")
  self.debug_logger.info(
    "[Step 2] Token stack: \{@debug.to_string(self.stack)} Token: \{token}",
  )
  // self.debug_logger.info("Cur subject lenth: \{self.cur_subject.length()}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      // self.cur_subject.push(NamedNodeRef::new_unchecked(iri).as_enum())
      self.stack.push(
        TriGState::WrappedGraphOrPredicateObjectList(
          term=NamedNodeRef::new_unchecked(iri).as_enum(),
        ),
      )
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(
          prefix,
          localx,
          might_be_invalid_iri,
          context.prefixes,
        ) {
        Ok(t) => {
          self.cur_subject.push(t.as_enum())
          self.stack.push(
            TriGState::WrappedGraphOrPredicateObjectList(term=t.as_enum()),
          )
          self
        }
        Err(e) => self.error(e)
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      self.stack.push(
        TriGState::WrappedGraphOrPredicateObjectList(
          term=NamedNodeRef::new_unchecked(label).as_enum(),
        ),
      )
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      self.stack.push(TriGState::WrappedGraphBlankNodePropertyListCurrent)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      self.stack.push(TriGState::ExpectDot)
      self.stack.push(TriGState::PredicateObjectList)
      self.stack.push(TriGState::SubjectCollectionBeginning)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("<<"), _)
    ) => {
      self.stack.push(TriGState::MaybePredicateObjectList)
      self.stack.push(TriGState::SubjectReifiedTripleEnd)
      self.stack.push(TriGState::EndOfReifiedTripleBeforeReifier)
      self.stack.push(TriGState::ReifiedTripleObject(is_reified=true))
      self.stack.push(TriGState::Verb)
      self.stack.push(TriGState::ReifiedTripleSubject(is_reified=true))
      self
    }
    _ => self.error("TOKEN is not a valid subject or graph name")
  }
}

// 5. 谓词列表
// 对应状态: TriGState::PredicateObjectList
// 功能: 初始化谓词-对象对的处理流程

///|
fn TriGRecognizer::handle_predicate_object_list(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "[Step 5] Token stack: \{@debug.to_string(self.stack)}",
  )
  self.stack.push(TriGState::PredicateObjectListEnd)
  self.stack.push(TriGState::Object)

  self.stack.push(TriGState::Verb) // 修正:原代码可能遗漏了 Verb,否则无法解析第一个谓词
  self.recognize_next(
    token,
    RdfContext::TriGRecognizerContext(context),
    results,
  )
}

// 对应状态: TriGState::PredicateObjectListEnd
// 功能: 处理谓词-对象对之间的分隔符 (, ; .)

///|

///|
fn TriGRecognizer::handle_predicate_object_list_end(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  // context : TriGRecognizerContext,
  // results : Array[RdfOut],

) -> TriGRecognizer {
  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(","), _)
    ) => {
      // 逗号表示同一个谓词的下一个对象
      self.stack.push(TriGState::Object)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(";"), _)
    ) => {
      // 分号表示同一个主语的下一个谓词
      self.stack.push(TriGState::PredicateObjectListPossibleContinuation)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => {
      // 句号表示语句结束
      self.stack.clear()
      self.stack.push(TriGState::TriGDoc)
      self.cur_subject.clear()
      self.cur_predicate.clear()
      self.cur_object.clear()
      self
    }
    _ => self.error("Expected ';' or '.' after predicate-object list")
  }
}
// 6. ObjectsList 路由
// 对应状态: TriGState::ObjectsList
// 功能: 处理多个对象的情况(由逗号分隔),通常由 'a' 或谓词后触发

///|
fn TriGRecognizer::handle_objects_list(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "[Step 4] Token stack: \{@debug.to_string(self.stack)} Token: \{token}",
  )
  // 原逻辑 L1030-L1035:
  // self.stack.push(TriGState::Object)
  // return self.recognize_next(...)

  self.stack.push(TriGState::Object)

  self.recognize_next(
    token,
    RdfContext::TriGRecognizerContext(context),
    results,
  )
  // self
}

// 7. 文档和图
// 对应状态: TriGState::TriGDoc
// 功能: 处理文档级指令 (BASE, PREFIX, VERSION) 和图的入口

///|
fn TriGRecognizer::handle_trig_doc(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  // results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info("[Step 1] Entering TriGDoc with token: \{token}")
  // self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")
  //   self.debug_logger.info(
  //   "Subject length: \{self.cur_subject.length()}"
  // )

  // 重置当前图为默认图
  self.cur_graph = GraphNameRef::DefaultGraph
  self.stack.push(TriGState::TriGDoc)

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "base") => {
      self.stack.push(TriGState::BaseExpectIri)
      return self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "prefix") => {
      self.stack.push(TriGState::PrefixExpectPrefix)
      return self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "version") => {
      self.stack.push(TriGState::VersionExpectVersion)
      return self
    }
    // 处理 @prefix, @base, @version 语法糖 (通过 LangTag 模拟)
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language="prefix", direction=None), _)
    ) => {
      self.stack.push(TriGState::ExpectDot)
      self.stack.push(TriGState::PrefixExpectPrefix)
      return self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language="base", direction=None), _)
    ) => {
      self.stack.push(TriGState::ExpectDot)
      self.stack.push(TriGState::BaseExpectIri)
      return self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language="version", direction=None), _)
    ) => {
      self.stack.push(TriGState::ExpectDot)
      self.stack.push(TriGState::VersionExpectVersion)
      return self
    }
    // 处理 GRAPH 关键字
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "graph") && context.with_graph_name => {
      self.stack.push(TriGState::WrappedGraph)
      self.stack.push(TriGState::GraphName)
      return self
    }
    // 处理匿名图开始 {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) if context.with_graph_name => {
      self.stack.push(TriGState::WrappedGraph)
      return self
    }
    // 默认情况:进入三元组或图解析
    _ => {
      // self.stack.push(TriGState::TriGDoc)

      self.stack.push(TriGState::TriplesOrGraph)
      self
      // return self.handle_triples_or_graph(token, context, errors)
    }
  }
}

// 对应状态: TriGState::WrappedGraph
// 功能: 确认图块的开始 '{' 并进入图内容解析

///|
fn TriGRecognizer::handle_wrapped_graph(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  _context : TriGRecognizerContext,
  _results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info("Entering WrappedGraph with token: \{token}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) => {
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::Triples)
      return self
    }
    _ =>
      return self.error(
        "The GRAPH keyword should be followed by a graph name and a value in '{'",
      )
  }
}

///|
fn TriGRecognizer::handle_in_collection(
  self : TriGRecognizer,
) -> TriGRecognizer {
  // 当遇到 '(' 时调用,初始化集合解析状态
  // 此时不消耗 token,或者消耗 '(' 后进入 CollectionElement
  // 这里假设 '(' 已经被 consume 或者由上层状态压入 InCollection/CollectionElement

  // 如果当前是在 Object 位置遇到 '(',通常意味着开始一个新的集合对象
  // 我们需要创建一个根 BlankNode 作为集合的头节点(如果是非空集合的第一个元素的前驱)
  // 但根据 RDF 列表语义,(a b) 等价于 _:b1 rdf:first a; rdf:rest _:b2. _:b2 rdf:first b; rdf:rest rdf:nil.

  // 注意:在 Moonbit/TriG 解析器中,通常由 ObjectsList 检测到 '(' 后压入 InCollection
  // 我们保持 InCollection 作为标记,但让 recognize_next 立即转到 CollectionElement

  return self
}

///|
fn TriGRecognizer::handle_collection_element(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
) -> TriGRecognizer {
  self.debug_logger.info("Handling CollectionElement with token: \{token}")

  match token {
    // 1. 空集合: ()
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) => {
      self.debug_logger.info("CollectionElement: empty collection")
      // 空集合直接对应 rdf:nil
      self.cur_object.push(TermRef::NamedNodeRef(lwNIL))
      // 注意:空集合不需要 emit_quad,因为 nil 是直接作为对象使用的

      let _ = self.stack.pop() // Pop CollectionElement
      let _ = self.stack.pop() // Pop InCollection

      // 回到上一个状态,通常是等待对象结束的状态
      self.stack.push(TriGState::PredicateObjectListEnd)
      // 或者更通用的:self.stack.push(TriGState::ObjectPostProcess) 如果有的话
      return self
    }

    // 2. 嵌套集合: ( ... )
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      self.debug_logger.info("CollectionElement: nested collection start")
      // 嵌套集合本身是一个对象,它会产生一个 BlankNode 作为头节点
      let head_bnode = BlankNode::default()

      self.cur_subject.push(
        NamedOrBlankNodeRef::BlankNodeRef(head_bnode.as_ref()),
      )
      self.cur_predicate.push(lwFIRST)

      // 压入状态以解析内层集合
      // 内层集合解析完后,会将结果放在 cur_object 中
      // 然后回到当前状态?不,原代码是压入 InCollection + ObjectsList

      self.stack.push(TriGState::CollectionEnd) // 处理当前外层节点的 rest
      self.stack.push(TriGState::InCollection) // 标记进入内层集合上下文
      self.stack.push(TriGState::ObjectsList) // 开始解析内层集合的元素

      // 注意:这里需要确保内层集合解析出的头节点能被正确用作当前外层的 "Object"
      // 原代码逻辑中,ObjectsList 最终会推到 Object 状态,Object 状态处理完 token 后会 emit_quad?
      // 这是一个复杂的交互。

      return self
    }

    // 3. 普通元素 (IRI, Integer, String, etc.)
    _ => {
      // 委托给 handle_object 来解析具体的 Token 为 Term
      // 但我们需要先准备列表节点的结构

      let list_node_bnode = BlankNode::default()

      // 原代码逻辑:
      // 1. Push list_node_bnode to cur_object? (原代码做法)
      // 2. Emit Quad.
      // 3. Push list_node_bnode to cur_subject.
      // 4. Push lwFIRST to cur_predicate.
      // 5. Push CollectionEnd.
      // 6. Push Object (to parse the actual value).

      // 这种顺序意味着:
      // 当 Object 状态处理完实际值(如 IRI)后,它会 emit_quad。
      // 此时 cur_subject=list_node_bnode, cur_predicate=rdf:first, cur_object=ActualValue.
      // 这符合 RDF 语义。

      self.cur_object.push(TermRef::BlankNodeRef(list_node_bnode.as_ref()))

      let bnode_curr = BlankNode::default()
      self.cur_subject.push(
        NamedOrBlankNodeRef::BlankNodeRef(bnode_curr.as_ref()),
      )
      self.cur_predicate.push(lwFIRST)

      self.stack.push(TriGState::CollectionEnd)
      self.stack.push(TriGState::Object)

      return self
    }
  }
}

///|
fn TriGRecognizer::handle_collection_end(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info("Handling CollectionEnd with token: \{token}")

  match token {
    // 集合结束: )
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) => {
      self.debug_logger.info("CollectionEnd: closing collection")

      // 弹出当前列表节点 (Subject)
      let subject = match self.cur_subject.pop() {
        Some(s) => s
        None =>
          return self.error(
            "Internal error: subject stack empty in CollectionEnd",
          )
      }

      // 清理 Predicate 和 Object (如果有的话,通常 Object 已被 Object 状态消费)
      let _ = self.cur_predicate.pop()
      let _ = self.cur_object.pop()

      // 输出 rdf:rest rdf:nil
      results.push(
        RdfOut::Quad(
          Quad::Quad(
            subject.into_owned(),
            lwREST.into_owned(),
            lwNIL.as_term().into_owned(),
            self.cur_graph.into_owned(),
          ),
        ),
      )

      // 弹出 CollectionEnd
      let _ = self.stack.pop()

      // 此时应该回到 InCollection 的上一个状态?
      // 原代码注释说 "保留 InCollection 和 CollectionElement",但这不对,因为 CollectionElement 已经弹出了。
      // 栈结构应该是: [..., InCollection, CollectionElement] -> CollectionElement pops itself and InCollection?

      let _ = self.stack.pop() // Pop InCollection

      // 现在栈顶是进入集合前的状态 (e.g., PredicateObjectListEnd or similar)
      return self
    }

    // 下一个元素
    _ => {
      self.debug_logger.info("CollectionEnd: next element")

      // 弹出当前列表节点 (Subject)
      let subject = match self.cur_subject.pop() {
        Some(s) => s
        None =>
          return self.error(
            "Internal error: subject stack empty in CollectionEnd",
          )
      }
      let _ = self.cur_predicate.pop()
      let _ = self.cur_object.pop()

      // 创建新的列表节点 bnode_next
      let bnode_next = BlankNode::default()

      // 输出 rdf:rest bnode_next
      results.push(
        RdfOut::Quad(
          Quad::Quad(
            subject.into_owned(),
            lwREST.into_owned(),
            bnode_next.as_ref().as_term().into_owned(),
            self.cur_graph.into_owned(),
          ),
        ),
      )

      // 准备处理下一个元素:
      // 新的当前节点是 bnode_next.
      self.cur_subject.push(
        NamedOrBlankNodeRef::BlankNodeRef(bnode_next.as_ref()),
      )
      self.cur_predicate.push(lwFIRST)

      // 压入 CollectionEnd (用于处理 bnode_next 的 rest)
      self.stack.push(TriGState::CollectionEnd)
      // 压入 Object (用于解析下一个元素的值)
      self.stack.push(TriGState::Object)

      return self
    }
  }
}

// 8. 图内三元组解析
// 对应状态: TriGState::Triples

///|
fn TriGRecognizer::handle_triples(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  // results : Array[RdfOut],

) -> TriGRecognizer {
  self.debug_logger.info("Entering Triples with token: \{token}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => self
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      self.cur_subject.push(
        NamedOrBlankNodeRef::BlankNodeRef(BlankNode::default().as_ref()),
      )
      self.stack.push(TriGState::PredicateObjectList)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.cur_subject.push(NamedNodeRef::new_unchecked(iri).as_enum())
      self.stack.push(TriGState::PredicateObjectList)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(
          prefix,
          localx,
          might_be_invalid_iri,
          context.prefixes,
        ) {
        Ok(t) => {
          self.cur_subject.push(t.as_enum())
          self.stack.push(TriGState::PredicateObjectList)
          self
        }
        Err(e) => self.error(e)
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      self.cur_subject.push(
        NamedOrBlankNodeRef::BlankNodeRef(BlankNodeRef::new_unchecked(label)),
      )
      self.stack.push(TriGState::PredicateObjectList)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      self.stack.push(TriGState::PredicateObjectList)
      self.stack.push(TriGState::SubjectCollectionBeginning)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("<<"), _)
    ) => {
      self.stack.push(TriGState::MaybePredicateObjectList)
      self.stack.push(TriGState::SubjectReifiedTripleEnd)
      self.stack.push(TriGState::EndOfReifiedTripleBeforeReifier)
      self.stack.push(TriGState::ReifiedTripleSubject(is_reified=true))
      self.stack.push(TriGState::Verb)
      self.stack.push(TriGState::ReifiedTripleObject(is_reified=true))
      self
    }
    _ => self.error("TOKEN is not a valid RDF subject")
  }
}

// 9. 注解块处理
// 对应状态: TriGState::AnnotationBlock

///|
fn TriGRecognizer::handle_annotation_block(
  self : TriGRecognizer,
  with_reifier : Bool,
  token : LocatedTokenOrLineJump,
  // context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "Entering AnnotationBlock(with_reifier=\{with_reifier}) with token: \{token}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(","), _)
    ) => {
      let _ = self.cur_object.pop()
      if with_reifier {
        let _ = self.cur_reifier.pop()
      }
      self.stack.push(TriGState::AnnotationBlock(with_reifier=false))
      self.stack.push(TriGState::Object)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("~"), _)
    ) => {
      let cur_sub = match self.cur_subject.last() {
        Some(s) => s
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: subject stack empty",
              self.last_range,
            ),
          )
          return self
        }
      }
      let cur_pred = match self.cur_predicate.last() {
        Some(p) => p
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: predicate stack empty",
              self.last_range,
            ),
          )
          return self
        }
      }
      let cur_obj = match self.cur_object.last() {
        Some(o) => o
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: object stack empty",
              self.last_range,
            ),
          )
          return self
        }
      }

      self.stack.push(TriGState::AnnotationBlock(with_reifier=true))
      self.stack.push(
        TriGState::Reifier(
          triple=TripleRef::TripleRef(cur_sub, cur_pred, cur_obj).into_owned(),
        ),
      )
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{|"), _)
    ) => {
      let cur_sub = match self.cur_subject.last() {
        Some(s) => s
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: subject stack empty",
              self.last_range,
            ),
          )
          return self
        }
      }
      let cur_pred = match self.cur_predicate.last() {
        Some(p) => p
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: predicate stack empty",
              self.last_range,
            ),
          )
          return self
        }
      }
      let cur_obj = match self.cur_object.last() {
        Some(o) => o
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: object stack empty",
              self.last_range,
            ),
          )
          return self
        }
      }
      let reifier = if with_reifier {
        match self.cur_reifier.last() {
          Some(r) => r
          None => {
            self.errors.push(
              RuleRecognizerError::SyntaxError(
                "Internal error: reifier stack empty",
                self.last_range,
              ),
            )
            return self
          }
        }
      } else {
        let reifier = BlankNode::default()
        results.push(
          RdfOut::Quad(
            Quad::Quad(
              reifier.as_enum(),
              lwREIFIES.into_owned(),
              TermRef::TripleRef(
                TripleRef::TripleRef(cur_sub, cur_pred, cur_obj),
              ).into_owned(),
              self.cur_graph.into_owned(),
            ),
          ),
        )
        reifier.as_enum().as_ref()
      }
      self.cur_subject.push(reifier)
      self.stack.push(TriGState::AnnotationBlock(with_reifier~))
      self.stack.push(TriGState::PredicateObjectList)
      self
    }
    _ => {
      let _ = self.cur_object.pop()
      if with_reifier {
        let _ = self.cur_reifier.pop()
      }
      self
    }
  }
}

// 10. 字面量后缀处理
// 对应状态: TriGState::LiteralPossibleSuffix

///|
fn TriGRecognizer::handle_literal_possible_suffix(
  self : TriGRecognizer,
  value : String,
  emit : Bool,
  token : LocatedTokenOrLineJump,
  // context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "Entering LiteralPossibleSuffix(\{value}, emit=\{emit}) with token: \{token}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language~, direction~), _)
    ) => {
      self.cur_object.push(
        if direction is Some(direction) {
          let lang_tag = try
            LanguageTag::from_str(language.to_lower()) |> Ok
          catch {
            e => Err(e)
          }
          let resolved_lang_tag = match lang_tag {
            Ok(tag) => tag
            Err(e) => {
              self.errors.push(
                RuleRecognizerError::SyntaxError(e.to_string(), self.last_range),
              )
              return self
            }
          }
          TermRef::LiteralRef(
            LiteralRef::new_directional_language_tagged_literal_unchecked(
              value, resolved_lang_tag, direction,
            ),
          )
        } else {
          TermRef::LiteralRef(
            Literal::new_language_tagged_literal_unchecked(
              value,
              language.to_lower(),
            ).as_ref(),
          )
        },
      )
      if emit {
        self.emit_quad(results)
        self.stack.push(TriGState::PredicateObjectListEnd)
      }
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("^^"), _)
    ) => {
      self.stack.push(TriGState::LiteralPossibleSuffix(value~, emit~))
      self
    }
    _ => {
      self.cur_object.push(LiteralRef::new_simple_literal(value).as_term())
      if emit {
        self.emit_quad(results)
        self.stack.push(TriGState::PredicateObjectListEnd)
      }
      self
    }
  }
}

// 11. 引用三元组对象结束
// 对应状态: TriGState::ObjectReifiedTripleEnd

///|
fn TriGRecognizer::handle_object_reified_triple_end(
  self : TriGRecognizer,
  emit : Bool,
  token : LocatedTokenOrLineJump,
  // context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "Entering ObjectReifiedTripleEnd(emit=\{emit}) with token: \{token}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  let subject = match self.cur_subject.pop() {
    Some(s) => s
    None => {
      self.errors.push(
        RuleRecognizerError::SyntaxError(
          "Internal error: subject stack is empty",
          self.last_range,
        ),
      )
      return self
    }
  }

  let blank_ref = match subject {
    NamedOrBlankNodeRef::BlankNodeRef(b) => TermRef::BlankNodeRef(b)
    _ => abort("Subject must be a blank node")
  }
  self.cur_object.push(blank_ref)
  if emit {
    self.emit_quad(results)
  }

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(">>"), _)
    ) => self
    _ => self.error("Expecting '>>' to close a reified triple, found TOKEN")
  }
}

// 12. 空节点属性列表结束 (对象)
// 对应状态: TriGState::ObjectBlankNodePropertyListEnd

///|
fn TriGRecognizer::handle_object_blank_node_property_list_end(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  // context : TriGRecognizerContext,
  results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info(
    "Entering ObjectBlankNodePropertyListEnd with token: \{token}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => {
      let subject = match self.cur_subject.pop() {
        Some(s) => s
        None => {
          self.errors.push(
            RuleRecognizerError::SyntaxError(
              "Internal error: subject stack is empty",
              self.last_range,
            ),
          )
          return self
        }
      }

      let blank_ref = match subject {
        NamedOrBlankNodeRef::BlankNodeRef(b) => b
        _ => abort("subject should be a blank node")
      }
      self.cur_object.push(TermRef::BlankNodeRef(blank_ref))
      self.emit_quad(results)
      self
    }
    _ => self.error("blank node property lists should end with a ']'")
  }
}

// 13. 谓词列表可能继续
// 对应状态: TriGState::PredicateObjectListPossibleContinuation

///|
fn TriGRecognizer::handle_predicate_object_list_possible_continuation(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  // context : TriGRecognizerContext,
  // results : Array[RdfOut],
  // errors : Array[RuleRecognizerError],
) -> TriGRecognizer {
  self.debug_logger.info(
    "Entering PredicateObjectListPossibleContinuation with token: \{token}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(";"), _)
    ) => {
      self.stack.push(TriGState::PredicateObjectListPossibleContinuation)
      self
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("." | "}" | "]" | "|}"), _)
    ) => self
    _ => {
      self.stack.push(TriGState::PredicateObjectListEnd)
      self.stack.push(TriGState::Object)
      self.stack.push(TriGState::Verb)
      self
    }
  }
}

// 14. 图结束处理
// 对应状态: TriGState::WrappedGraphPossibleEnd

///|
fn TriGRecognizer::handle_wrapped_graph_possible_end(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
) -> TriGRecognizer {
  self.debug_logger.info(
    "Entering WrappedGraphPossibleEnd with token: \{token}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match token {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => self
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => {
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::Triples)
      self
    }
    _ => {
      self.errors.push(RuleRecognizerError::TripleMissingDot)
      self
    }
  }
}

///|

///|
fn TriGRecognizer::handle_verb(
  self : TriGRecognizer,
  token : LocatedTokenOrLineJump,
  context : TriGRecognizerContext,
  _results : Array[RdfOut],
) -> TriGRecognizer {
  self.debug_logger.info("Verb: handling token: \{token}")

  match token {
    // 'a' 表示 rdf:type
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("a"), _)
    ) => {
      self.debug_logger.info("Verb: 'a' predicate")
      self.cur_predicate.push(lwTYPE)
      self.stack.push(TriGState::ObjectsList)
      self
    }

    // IRI 谓词
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.debug_logger.info("Verb: IRI predicate: \{iri}")
      self.cur_predicate.push(NamedNodeRef::new_unchecked(iri))
      // 修复:确保推入 ObjectsList 状态,以便接下来解析对象
      self.stack.push(TriGState::ObjectsList)
      self
    }

    // 前缀名谓词
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(
          prefix,
          localx,
          might_be_invalid_iri,
          context.prefixes,
        ) {
        Ok(t) => {
          self.debug_logger.info("Verb: PrefixedName predicate: \{t}")
          self.cur_predicate.push(t)
          self.stack.push(TriGState::ObjectsList)
          self
        }
        Err(e) => self.error(e)
      }

    // 其他情况 - 错误
    _ => {
      self.debug_logger.info("Verb: Invalid token: \{token}")
      self.error(
        "Expected a predicate (IRI or 'a'), found: \{token.to_string()}",
      )
    }
  }
}