///|
/// Prism — SDK 主入口
///
/// 使用方式(L1 应用开发者):
/// ```
/// let prism = Prism::new().with_provider("openai")
/// let json = prism.encode_request("Hello", PrismOptions::default())
/// // json 是提供商 JSON 请求体,Host 发送 HTTP 请求
/// // Host 收到响应后调用 prism.decode_response(json)
/// ```

///|
/// ConversionMeta — 转换来源元信息(D8)
///
/// 回答"这个 LUX 值是从哪个协议解码来的",并附带转换损失诊断
/// 与厂商特有字段(provider_payload / extra_fields)。
/// 开发者可用 `source_provider` 做按需特判(if 分支),主路径代码仍只写一次。
pub struct ConversionMeta {
  source_provider : String
  diagnostics : Array[@lux.ConversionDiagnostic]
  provider_payload : Json?
  extra_fields : Map[String, Json]?
}

///|
pub fn ConversionMeta::new(
  source_provider : String,
  diagnostics : Array[@lux.ConversionDiagnostic],
  provider_payload : Json?,
  extra_fields : Map[String, Json]?,
) -> ConversionMeta {
  { source_provider, diagnostics, provider_payload, extra_fields }
}

///|
/// DecodedResponse — 解码结果:主路径文本 + 溯源元信息
pub struct DecodedResponse {
  text : String
  meta : ConversionMeta
}

///|
pub fn DecodedResponse::new(
  text : String,
  meta : ConversionMeta,
) -> DecodedResponse {
  { text, meta }
}

///|
/// PrismOptions — SDK 请求选项
pub struct PrismOptions {
  model : String?
  temperature : Double?
  max_tokens : Int?
  store : Bool?
  extras : Map[String, Json]?
}

///|
pub fn PrismOptions::default() -> PrismOptions {
  {
    model: None,
    temperature: None,
    max_tokens: None,
    store: None,
    extras: None,
  }
}

///|
pub fn PrismOptions::new(
  model : String?,
  temperature : Double?,
  max_tokens : Int?,
  store : Bool?,
  extras : Map[String, Json]?,
) -> PrismOptions {
  { model, temperature, max_tokens, store, extras }
}

///|
/// Prism — 主实例
pub struct Prism {
  provider : String
}

///|
pub fn Prism::new() -> Prism {
  { provider: "openai" }
}

///|
/// 设置 provider 名称
pub fn Prism::with_provider(_self : Prism, name : String) -> Prism {
  { provider: name }
}

///|
/// === 请求编码 / 响应解码 ===

///|
/// 将文本请求编码为提供商 JSON(L1:文本进,JSON 出)
pub fn Prism::encode_request(
  self : Prism,
  text : String,
  opts : PrismOptions,
) -> Result[String, String] {
  let ctx = Context::new()
  let ctx = ctx.add_user(text)
  let model = match opts.model {
    Some(m) => m
    None => "gpt-4o"
  }
  let req = context_to_lux_request(ctx, model, opts)
  self.encode_lux_request(req)
}

///|
/// 将提供商 JSON 响应解码为纯文本(L1:JSON 进,文本出)
pub fn Prism::decode_response(
  self : Prism,
  json_str : String,
) -> Result[String, String] {
  match self.decode_to_lux(json_str) {
    Ok(resp) => Ok(resp.get_text())
    Err(e) => Err(e)
  }
}

///|
/// 将提供商 JSON 响应解码为 DecodedResponse(文本 + 来源元信息)。
///
/// meta.source_provider 为运行时从注册表解析的规范 provider 名
/// (精确匹配/别名/模型正则),开发者可据此做按需特判。
pub fn Prism::decode_response_with_meta(
  self : Prism,
  json_str : String,
) -> Result[DecodedResponse, String] {
  let source = match match_provider_name(self.provider) {
    Some(reg) => reg.name
    None => self.provider
  }
  match self.decode_to_lux(json_str) {
    Ok(resp) => {
      let meta = ConversionMeta::new(source, [], resp.provider_payload, None)
      Ok(DecodedResponse::new(resp.get_text(), meta))
    }
    Err(e) => Err(e)
  }
}

///|
/// 将提供商响应解码为完整 LucentResponse,并返回结构化校验诊断。
pub fn Prism::decode_response_with_diagnostics(
  self : Prism,
  json_str : String,
) -> Result[@lux.ConversionResult[@lux.LucentResponse], String] {
  match self.decode_to_lux(json_str) {
    Ok(resp) => {
      let result = @lux.ConversionResult::new(resp)
      match get_schema(self.provider) {
        Some(schema) => {
          let mut checked = result
          for error in schema.validate_response(resp) {
            checked = checked.with_diagnostic(
              @lux.ConversionDiagnostic::new("response", Invalid, Some(error)),
            )
          }
          Ok(checked)
        }
        None => Ok(result)
      }
    }
    Err(e) => Err(e)
  }
}

///|
/// 将文本请求编码为提供商 JSON,并返回结构化校验诊断。
pub fn Prism::encode_request_with_diagnostics(
  self : Prism,
  text : String,
  opts : PrismOptions,
) -> Result[@lux.ConversionResult[String], String] {
  let ctx = Context::new()
  let ctx = ctx.add_user(text)
  let model = match opts.model {
    Some(m) => m
    None => "gpt-4o"
  }
  let req = context_to_lux_request(ctx, model, opts)
  let mut result = @lux.ConversionResult::new(req)
  match get_schema(self.provider) {
    Some(schema) =>
      for error in schema.validate_request(req) {
        result = result.with_diagnostic(
          @lux.ConversionDiagnostic::new("request", Invalid, Some(error)),
        )
      }
    None => ()
  }
  match self.encode_lux_request(result.value()) {
    Ok(json) => {
      let mut encoded = @lux.ConversionResult::new(json)
      for diagnostic in result.diagnostics() {
        encoded = encoded.with_diagnostic(diagnostic)
      }
      Ok(encoded)
    }
    Err(e) => Err(e)
  }
}

///|
/// 将提供商 JSON 解码为 LucentResponse(基于 ProviderRegistration 注册表)
fn Prism::decode_to_lux(
  self : Prism,
  json_str : String,
) -> Result[@lux.LucentResponse, String] {
  let provider = self.provider
  match match_provider_name(provider) {
    Some(reg) =>
      match (reg.response_decode)(json_str) {
        Ok(cr) => Ok(cr.value())
        Err(e) => Err(e)
      }
    None => Err("unknown provider: " + provider)
  }
}

///|
/// 编码 LucentRequest 为提供商 JSON(基于 ProviderRegistration 注册表)
fn Prism::encode_lux_request(
  self : Prism,
  req : @lux.LucentRequest,
) -> Result[String, String] {
  let provider = self.provider
  match match_provider_name(provider) {
    Some(reg) =>
      match (reg.request_encode)(req) {
        Ok(cr) => Ok(cr.value())
        Err(e) => Err(e)
      }
    None => Err("unknown provider: " + provider)
  }
}

///|
/// === 流式接口 ===

///|
/// 将文本请求编码为流式提供商 JSON
pub fn Prism::encode_stream_request(
  self : Prism,
  text : String,
  opts : PrismOptions,
) -> Result[String, String] {
  let ctx = Context::new()
  let ctx = ctx.add_user(text)
  let model = match opts.model {
    Some(m) => m
    None => "gpt-4o"
  }
  let mut req = context_to_lux_request(ctx, model, opts)
  req = @lux.LucentRequest::with_stream(req, true)
  self.encode_lux_request(req)
}

///|
/// 将提供商 SSE 事件解码为 PrismEvent 数组
pub fn Prism::decode_sse(
  self : Prism,
  sse_str : String,
) -> Result[Array[PrismEvent], String] {
  let provider = self.provider
  match decode_sse_inner(provider, sse_str) {
    Ok(raw_events) => Ok(lucent_events_to_prism(raw_events))
    Err(e) => Err(e)
  }
}

///|
/// L1 零配置:文本进、文本出(HTTP 由 Host 注入 send)
pub fn Prism::complete(
  self : Prism,
  text : String,
  opts : PrismOptions,
  send : (String) -> Result[String, String],
) -> Result[String, String] {
  match self.encode_request(text, opts) {
    Ok(json) =>
      match send(json) {
        Ok(resp_json) => self.decode_response(resp_json)
        Err(e) => Err(e)
      }
    Err(e) => Err(e)
  }
}

///|
/// L2 Agent 循环:流式请求 + 5 事件解码(HTTP 由 Host 注入 send)
pub fn Prism::stream(
  self : Prism,
  ctx : Context,
  send : (String) -> Result[String, String],
) -> Result[Array[PrismEvent], String] {
  let model = "gpt-4o"
  let mut req = context_to_lux_request(ctx, model, PrismOptions::default())
  req = @lux.LucentRequest::with_stream(req, true)
  match self.encode_lux_request(req) {
    Ok(json) =>
      match send(json) {
        Ok(sse) => self.decode_sse(sse)
        Err(e) => Err(e)
      }
    Err(e) => Err(e)
  }
}

///|
/// 将提供商 SSE 解码为原始 LucentStreamEvent(基于注册表)
fn decode_sse_inner(
  provider : String,
  sse_str : String,
) -> Result[Array[@lux.LucentStreamEvent], String] {
  match match_provider_name(provider) {
    Some(reg) =>
      match (reg.events_decode)(sse_str) {
        Ok(cr) => Ok(cr.value())
        Err(e) => Err(e)
      }
    None => Err("unknown provider: " + provider)
  }
}

///|
/// 将 LucentStreamEvent 数组转为 PrismEvent 数组(SDK 内部)
fn lucent_events_to_prism(
  events : Array[@lux.LucentStreamEvent],
) -> Array[PrismEvent] {
  let result : Array[PrismEvent] = []
  let mut has_finish = false
  for ev in events {
    if has_finish {
      break
    }
    match ev {
      BlockDelta(_, TextDelta(s)) => result.push(TextDelta(s))
      BlockDelta(_, ToolArgumentsDelta(_s)) =>
        // L2: 工具参数增量,当前简化
        ()
      ItemStart(_, ToolCall(tu)) =>
        result.push(
          ToolCall({
            id: tu.id,
            name: tu.name,
            arguments_json: tu.arguments_json,
          }),
        )
      ItemStart(_, ToolResult(tr)) =>
        result.push(
          ToolResult({
            tool_use_id: tr.tool_use_id,
            content: @lux.lucent_content_to_text(tr.content),
            is_error: tr.is_error,
          }),
        )
      BlockStart(_, Thinking) => ()
      BlockDelta(_, ThinkingDelta(s)) =>
        result.push(Thinking({ text: s, signature: None, redacted: false }))
      Finish(fr) => {
        let pfr = match fr {
          Stop => Stop
          Length => Length
          ToolCalls => ToolCalls
          ContentFilter => ContentFilter
          _ => Error
        }
        result.push(Finish(pfr))
        has_finish = true
      }
      _ => ()
    }
  }
  result
}

///|
/// === 能力查询 ===

///|
/// 查询指定 provider 的能力声明(基于注册表)
pub fn Prism::capability(
  _self : Prism,
  provider_name : String,
) -> @lux.ProviderCapability? {
  match match_provider_name(provider_name) {
    Some(reg) => Some(reg.capability)
    None => None
  }
}