syntax = "proto3";

package next_edu_cloud.msg.v1;

// Msg 服务契约（P5 沟通通知中台）。
//
// 三服务：
// - NotificationService：通知发送 / 列表 / 已读 / 检索 / 撤回
// - NotificationPreferenceService：用户通知偏好
// - NotificationTemplateService：通知模板 CRUD + 渲染
//
// 仲裁依据：coord-final-decisions.md M1（gRPC 50056 启用）+ msg_contract.md §1.1

// ============================================================
// NotificationService
// ============================================================
service NotificationService {
  rpc SendNotification(SendNotificationRequest) returns (Notification);
  rpc BatchSendNotification(BatchSendNotificationRequest) returns (BatchSendNotificationResponse);
  rpc ListNotifications(ListNotificationsRequest) returns (ListNotificationsResponse);
  rpc GetUnreadCount(GetUnreadCountRequest) returns (GetUnreadCountResponse);
  rpc MarkAsRead(MarkAsReadRequest) returns (Empty);
  rpc BatchMarkAsRead(BatchMarkAsReadRequest) returns (Empty);
  rpc MarkAllAsRead(MarkAllAsReadRequest) returns (Empty);
  rpc SearchNotifications(SearchNotificationsRequest) returns (SearchNotificationsResponse);
  rpc RecallNotification(RecallNotificationRequest) returns (RecallNotificationResponse);
}

// ============================================================
// NotificationPreferenceService
// ============================================================
service NotificationPreferenceService {
  rpc GetPreferences(GetPreferencesRequest) returns (GetPreferencesResponse);
  rpc UpdatePreferences(UpdatePreferencesRequest) returns (Empty);
}

// ============================================================
// NotificationTemplateService
// ============================================================
service NotificationTemplateService {
  rpc CreateTemplate(CreateTemplateRequest) returns (NotificationTemplate);
  rpc GetTemplate(GetTemplateRequest) returns (NotificationTemplate);
  rpc ListTemplates(ListTemplatesRequest) returns (ListTemplatesResponse);
  rpc UpdateTemplate(UpdateTemplateRequest) returns (NotificationTemplate);
  rpc DeleteTemplate(DeleteTemplateRequest) returns (Empty);
  rpc RenderTemplate(RenderTemplateRequest) returns (RenderedNotification);
}

// ============================================================
// Notification 聚合
// ============================================================
message Notification {
  string id = 1;
  string user_id = 2;
  string type = 3;
  string title = 4;
  string content = 5;
  string channel = 6;
  bool is_read = 7;
  int64 created_at = 8;
  // 扩展字段（P5）
  string status = 9;
  string related_entity_type = 10;
  string related_entity_id = 11;
  string group_id = 12;
  string sender_id = 13;
  string template_id = 14;
  string event_id = 15;
  int64 read_at = 16;
  int64 updated_at = 17;
  map<string, string> metadata = 18;
}

// ============================================================
// SendNotification
// ============================================================
message SendNotificationRequest {
  string user_id = 1;
  string type = 2;
  string title = 3;
  string content = 4;
  string channel = 5;
  map<string, string> metadata = 6;
  string related_entity_type = 7;
  string related_entity_id = 8;
  string group_id = 9;
  string sender_id = 10;
  string template_id = 11;
  string event_id = 12;
}

message BatchSendNotificationRequest {
  repeated SendNotificationRequest items = 1;
  string group_id = 2;
}

message BatchSendNotificationResponse {
  repeated string ids = 1;
  repeated BatchSendFailure failed = 2;
}

message BatchSendFailure {
  string user_id = 1;
  string error = 2;
}

// ============================================================
// ListNotifications
// ============================================================
message ListNotificationsRequest {
  string user_id = 1;
  bool only_unread = 2;
  string type = 3;
  int32 page = 4;
  int32 page_size = 5;
}

message ListNotificationsResponse {
  repeated Notification notifications = 1;
  int32 total = 2;
}

// ============================================================
// GetUnreadCount
// ============================================================
message GetUnreadCountRequest {
  string user_id = 1;
}

message GetUnreadCountResponse {
  int32 count = 1;
}

// ============================================================
// MarkAsRead
// ============================================================
message MarkAsReadRequest {
  string id = 1;
  string user_id = 2;
}

message BatchMarkAsReadRequest {
  repeated string ids = 1;
  string user_id = 2;
}

message MarkAllAsReadRequest {
  string user_id = 1;
  int64 before = 2;
}

// ============================================================
// SearchNotifications
// ============================================================
message SearchNotificationsRequest {
  string user_id = 1;
  string query = 2;
  string type = 3;
  int32 page = 4;
  int32 page_size = 5;
}

message SearchNotificationsResponse {
  repeated Notification notifications = 1;
  int32 total = 2;
}

// ============================================================
// RecallNotification
// ============================================================
message RecallNotificationRequest {
  string group_id = 1;
  string reason = 2;
}

message RecallNotificationResponse {
  int32 recalled_count = 1;
}

// ============================================================
// NotificationPreference
// ============================================================
message NotificationPreference {
  string id = 1;
  string user_id = 2;
  string type = 3;
  repeated string channels = 4;
  int32 frequency_limit = 5;
  string quiet_hours_start = 6;
  string quiet_hours_end = 7;
  string quiet_hours_timezone = 8;
  bool enabled = 9;
  int64 created_at = 10;
  int64 updated_at = 11;
}

message GetPreferencesRequest {
  string user_id = 1;
}

message GetPreferencesResponse {
  repeated NotificationPreference preferences = 1;
}

message UpdatePreferencesRequest {
  string user_id = 1;
  repeated NotificationPreference preferences = 2;
}

// ============================================================
// NotificationTemplate
// ============================================================
message NotificationTemplate {
  string id = 1;
  string code = 2;
  string type = 3;
  string title_template = 4;
  string content_template = 5;
  repeated string default_channels = 6;
  repeated string variables = 7;
  string locale = 8;
  string status = 9;
  int64 created_at = 10;
  int64 updated_at = 11;
}

message CreateTemplateRequest {
  string code = 1;
  string type = 2;
  string title_template = 3;
  string content_template = 4;
  repeated string default_channels = 5;
  repeated string variables = 6;
  string locale = 7;
}

message GetTemplateRequest {
  string id = 1;
}

message ListTemplatesRequest {
  string type = 1;
  string status = 2;
}

message ListTemplatesResponse {
  repeated NotificationTemplate templates = 1;
}

message UpdateTemplateRequest {
  string id = 1;
  string title_template = 2;
  string content_template = 3;
  repeated string default_channels = 4;
  repeated string variables = 5;
  string status = 6;
}

message DeleteTemplateRequest {
  string id = 1;
}

message RenderTemplateRequest {
  string code = 1;
  map<string, string> variables = 2;
  string locale = 3;
}

message RenderedNotification {
  string title = 1;
  string content = 2;
}

// ============================================================
// Empty
// ============================================================
message Empty {}
