syntax = "proto3";

package next_edu_cloud.ai.v1;

// AiService 定义 AI 网关契约（D6 智能洞察领域 · 生成子域）
// 端口：HTTP 3008 + gRPC 50058（port-allocation.md §3/§5/§7 权威源）
// HTTP 保留作 Gateway 直连降级 + 前端 SSE 流式；gRPC 为 BFF 主入口
// 响应信封遵循 ActionState（004 §11.5），降级采用方案 B（总裁裁决 §2.6）
service AiService {
  // 非流式聊天
  rpc Chat(ChatRequest) returns (ChatResponse);
  // 流式聊天（SSE over gRPC）
  rpc StreamChat(ChatRequest) returns (stream ChatChunk);
  // 生成题目（非流式）
  rpc GenerateQuestion(GenerateQuestionRequest) returns (GeneratedQuestion);
  // 题目逐字流式生成
  rpc StreamGenerateQuestion(GenerateQuestionRequest) returns (stream GeneratedQuestionChunk);
  // 优化表达
  rpc OptimizeExpression(OptimizeExpressionRequest) returns (OptimizedExpression);
  // 备课工作流启动（4 步编排：分析学情 → 推荐知识点 → 生成题目 → 教师审核）
  rpc GenerateLessonPlan(GenerateLessonPlanRequest) returns (LessonPlanResponse);
  // 查询备课工作流状态
  rpc GetLessonPlanStatus(GetLessonPlanStatusRequest) returns (LessonPlanStatus);
  // 教师确认备课结果入库（调 content.CreateQuestions）
  rpc ConfirmLessonPlan(ConfirmLessonPlanRequest) returns (ConfirmResult);
}

// === 聊天 ===
message ChatRequest {
  repeated ChatMessage messages = 1;
  string model = 2;
  double temperature = 3;
  // 可选上下文（ai12 增补：BFF 透传用户身份与数据范围）
  optional string user_id = 4;
  optional string session_id = 5;
  optional string data_scope = 6;  // JSON 序列化的 DataScope
}

message ChatMessage {
  string role = 1;     // system / user / assistant
  string content = 2;
}

message ChatResponse {
  string content = 1;
  string model = 2;
  Usage usage = 3;
  bool degraded = 4;            // 降级标记（方案 B：success=true + data 内 degraded）
  string degraded_reason = 5;   // 降级原因（如 llm_unavailable / redis_unavailable）
}

message Usage {
  int32 prompt_tokens = 1;
  int32 completion_tokens = 2;
  int32 total_tokens = 3;
  int32 latency_ms = 4;
}

message ChatChunk {
  string content = 1;
  bool done = 2;
}

// === 题目生成 ===
message GenerateQuestionRequest {
  string prompt = 1;
  string subject = 2;
  string difficulty = 3;  // easy / medium / hard
  // 扩展字段（ai12 增补）
  optional string grade = 4;
  repeated string knowledge_point_ids = 5;
  optional string question_type = 6;  // single_choice / multi_choice / fill_blank / short_answer / essay
  optional int32 count = 7;           // 生成数量，默认 1
}

message GeneratedQuestion {
  string question = 1;
  string answer = 2;
  string explanation = 3;
  string question_type = 4;
  string difficulty = 5;
  repeated string knowledge_point_ids = 6;
  optional double evaluation_score = 7;  // 质量评分（0.0-1.0，评估三道防线输出）
  bool degraded = 8;
  string degraded_reason = 9;
}

message GeneratedQuestionChunk {
  string content = 1;                       // 逐字内容
  bool done = 2;
  optional GeneratedQuestion complete_question = 3;  // done=true 时携带完整题目
}

// === 表达优化 ===
message OptimizeExpressionRequest {
  string text = 1;
  string context = 2;
}

message OptimizedExpression {
  string optimized = 1;
  repeated string suggestions = 2;
  bool degraded = 3;
  string degraded_reason = 4;
}

// === 备课工作流 ===
message GenerateLessonPlanRequest {
  string class_id = 1;
  string subject_id = 2;
  string topic = 3;
  string target_difficulty = 4;  // easy / medium / hard
  int32 question_count = 5;
  string user_id = 6;
  string data_scope = 7;  // JSON 序列化的 DataScope
}

message LessonPlanResponse {
  string workflow_id = 1;
  string status = 2;  // pending / analyzing / generating / pending_review / persisted / failed
  int32 estimated_completion_seconds = 3;
  bool degraded = 4;
  string degraded_reason = 5;
}

message GetLessonPlanStatusRequest {
  string workflow_id = 1;
}

message LessonPlanStatus {
  string workflow_id = 1;
  string status = 2;
  repeated GeneratedQuestion questions = 3;
  optional string error = 4;
  bool degraded = 5;
  string degraded_reason = 6;
}

message ConfirmLessonPlanRequest {
  string workflow_id = 1;
  map<string, string> modifications = 2;  // question_id → 修改后内容（可选，教师审核修改）
}

message ConfirmResult {
  bool success = 1;
  repeated string persisted_question_ids = 2;
  optional string error = 3;
}
