/**
 * src/lib/nlu/types.ts
 *
 * 真实 NLU 类型定义，对应 intelligent_cabin 的 ChatResponse。
 * 替代原 mock.ts 里的 MockNluResult。
 */

// ── HTTP 层：ChatResponse raw shape ────────────────────────────────────────

export type RoutingStage = {
  stage: string;
  score?: number;
  accepted?: boolean;
  reason?: string | null;
  candidates?: Array<{ intent_id: string; score: number }>;
  metadata?: Record<string, unknown>;
};

export type RoutingDebug = {
  selected_intent: string | null;
  decision: string;
  confidence_grade: "high" | "medium" | "low" | null;
  decision_reason?: string | null;
  stages: RoutingStage[];
};

/** 来自 POST /api/v1/agent/chat 的原始响应 */
export type ChatResponse = {
  session_id: string;
  reply_type: "text" | "ask_slot" | "ask_confirmation" | "workflow_result" | "fallback" | "clarify" | "reject";
  reply_text: string;
  intent: string | null;
  domain: string | null;
  decision: string | null;
  decision_reason: string | null;
  status: string;
  pending_slots: string[];
  filled_slots: Record<string, unknown>;
  routing_debug: RoutingDebug | null;
  trace_id: string;
  // 知识库查询结果（LLM function call 命中时）
  knowledge_doc_id?: string | null;
  knowledge_doc_title?: string | null;
  knowledge_content?: string | null;
};

// ── Canvas 层：NluResult（路由使用） ───────────────────────────────────────

export type RouteHint =
  | "tool_call"       // decision=execute + machine_control 域
  | "knowledge_query" // decision=route_to_cloud 或 equipment_knowledge 域
  | "smalltalk"       // decision=reject / social
  | "clarify"         // 需要补槽
  | "fallback";

/** Canvas 消费的统一 NLU 结果，从 ChatResponse 映射而来 */
export type NluResult = {
  sessionId: string;
  modelVersion: string;
  domain: string;
  intent: string;
  confidence: number;          // routing_debug.stages[classifier].score
  slots: Record<string, string | number | boolean>;
  routeHint: RouteHint;
  decisionGrade: "high" | "medium" | "low";
  rawDecision: string;
  replyText: string;
  pendingSlots: string[];
  traceId: string;
  // 知识库结果（LLM function call 命中时千充）
  knowledgeContent?: string | null;
  knowledgeDocId?: string | null;
  knowledgeDocTitle?: string | null;
};

// ── Pipeline 层：语音拦截事件 ───────────────────────────────────────────────

export type StopActionEvent = {
  type: "stop_action";
  sourceText: string;
};

export type VoiceClickEvent = {
  type: "voice_click_event";
  actionId: string;
  artifactId?: string;
  sourceText: string;
};

export type SlotFillEvent = {
  type: "slot_fill_event";
  value: string;
  sourceText: string;
};

export type PipelineEvent = StopActionEvent | VoiceClickEvent | SlotFillEvent;

/** pipeline 返回值：被前置拦截处理 → PipelineEvent，进入 BERT → NluResult */
export type PipelineResult = NluResult | PipelineEvent;

// ── 会话状态（供 pipeline 读取） ───────────────────────────────────────────

export type SessionStatus =
  | "idle"
  | "waiting_slot"
  | "waiting_confirmation"
  | "running"
  | "completed"
  | "stopped"
  | "social"
  | string;

export type VisibleAction = {
  actionId: string;
  artifactId?: string;
  matchPhrases: string[];  // 按钮文本 + voiceAliases，展平后
};

export type PipelineSession = {
  sessionId: string;
  status: SessionStatus;
  visibleActions: VisibleAction[];
};

// ── 工具函数 ────────────────────────────────────────────────────────────────

/** 从 ChatResponse 中提取 BERT 分类器的原始置信度 */
export function extractConfidence(debug: RoutingDebug | null): number {
  if (!debug) return 0;
  const classifierStage = debug.stages.find((s) => s.stage === "classifier");
  return classifierStage?.score ?? 0;
}

/** decision + domain → RouteHint */
export function mapDecisionToRouteHint(decision: string | null, domain: string | null): RouteHint {
  if (decision === "execute") {
    if (domain === "machine_control") return "tool_call";
    if (domain === "equipment_knowledge") return "knowledge_query";
    return "tool_call";
  }
  if (decision === "clarify") return "clarify";
  if (decision === "route_to_cloud") return "knowledge_query";
  if (decision === "knowledge_llm" || domain === "knowledge") return "knowledge_query";
  if (decision === "open_social") return "smalltalk";
  return "fallback";
}

/** 将 ChatResponse 映射成 NluResult */
export function adaptChatResponse(raw: ChatResponse): NluResult {
  return {
    sessionId: raw.session_id,
    modelVersion: "intelligent-cabin-nlu",
    domain: raw.domain ?? "unknown",
    intent: raw.intent ?? "unknown",
    confidence: extractConfidence(raw.routing_debug),
    slots: raw.filled_slots as Record<string, string | number | boolean>,
    routeHint: mapDecisionToRouteHint(raw.decision, raw.domain),
    decisionGrade: raw.routing_debug?.confidence_grade ?? "low",
    rawDecision: raw.decision ?? "reject",
    replyText: raw.reply_text,
    pendingSlots: raw.pending_slots,
    traceId: raw.trace_id,
    // 知识库结果禁传递
    knowledgeContent: raw.knowledge_content ?? null,
    knowledgeDocId: raw.knowledge_doc_id ?? null,
    knowledgeDocTitle: raw.knowledge_doc_title ?? null,
  };
}
