syntax = "proto3";

package flare.common.v1;


// 与 NotificationCommand 配合：先解 Command，再反序列化 content 为 NotificationMessage。

/// 通知类型（与 flare.core.commands.NotificationCommand.Type 一一对应）
enum NotificationKind {
  NOTIFICATION_KIND_UNSPECIFIED = 0;
  NOTIFICATION_KIND_SYSTEM       = 1;  // 系统通知（维护、版本更新、公告等）
  NOTIFICATION_KIND_BROADCAST   = 2;  // 广播消息
  NOTIFICATION_KIND_ALERT       = 3;  // 警告/提示（需用户关注）
  NOTIFICATION_KIND_USER        = 4;  // 用户状态变化（在线、输入中、已读等）
  NOTIFICATION_KIND_CONNECTION  = 5;  // 连接相关（重连建议、会话过期、被踢等）
  NOTIFICATION_KIND_CUSTOM     = 6;  // 业务自定义（payload 使用 custom）
}

/// 优先级（用于客户端展示与排序）
enum NotificationPriority {
  NOTIFICATION_PRIORITY_UNSPECIFIED = 0;
  NOTIFICATION_PRIORITY_LOW         = 1;
  NOTIFICATION_PRIORITY_NORMAL      = 2;
  NOTIFICATION_PRIORITY_HIGH        = 3;
  NOTIFICATION_PRIORITY_URGENT      = 4;
}

/// 系统通知载荷（维护、版本更新、公告）
message SystemNotificationPayload {
  string code = 1;           // 业务码（如 MAINTENANCE、VERSION_UPDATE、ANNOUNCEMENT）
  string message = 2;        // 详细说明
  string link_url = 3;       // 可选跳转链接
  optional int64 start_at = 4;
  optional int64 end_at = 5;
}

/// 广播通知载荷
message BroadcastNotificationPayload {
  string broadcast_id = 1;   // 广播 ID，用于去重/已读
  string body = 2;           // 正文
  string link_url = 3;
  map<string, string> attributes = 4;
}

/// 告警/提示载荷
message AlertNotificationPayload {
  string code = 1;           // 告警码（如 RATE_LIMIT、PERMISSION_DENIED、CONTENT_BLOCKED）
  string message = 2;
  string action_label = 3;   // 可选按钮文案（如「去设置」「重试」）
  string action_deeplink = 4;
}

/// 用户状态通知载荷（与 EVENT_PRESENCE / typing 等语义一致）
message UserStatusNotificationPayload {
  string user_id = 1;
  string status = 2;         // online / offline / busy / typing 等
  string conversation_id = 3; // 可选，表示在某一会话内输入
  int64 occurred_at = 4;
}

/// 连接相关通知载荷
message ConnectionNotificationPayload {
  string code = 1;           // 如 RECONNECT_SUGGESTED、SESSION_EXPIRED、KICKED、ANOTHER_DEVICE_LOGIN
  string message = 2;
  string suggested_action = 3; // 建议操作（reconnect / relogin / none）
  int32 retry_after_sec = 4;   // 可选，多少秒后可重试
}

/// 用户自定义通知载荷（业务扩展）
/// 客户端可根据 type 或 schema_url 反序列化 payload（JSON、protobuf 等）
message CustomNotificationPayload {
  string type = 1;           // 业务自定义类型（如 "order_shipped"、"reward_claim"），便于客户端路由
  bytes payload = 2;         // 自定义内容（JSON、protobuf、msgpack 等，由业务约定）
  string schema_url = 3;     // 可选：schema 或版本标识
  map<string, string> attributes = 4;  // 可选元数据（key-value，便于过滤或展示）
}

/// 通用通知消息（序列化后放入 NotificationCommand.content）
message NotificationMessage {
  NotificationKind kind = 1;
  string notification_id = 2;  // 去重/幂等键，客户端可据此去重
  string title = 3;            // 标题（可与 NotificationCommand.title 合并展示）
  string body = 4;             // 正文
  NotificationPriority priority = 5;
  optional int64 expire_at = 6;  // 过期时间，过期后客户端可不再展示
  int64 created_at = 7;

  /// 客户端行为：打开会话 / 打开 URL / 无操作
  oneof action {
    string deeplink = 10;      // 应用内 deeplink（如 flare://conversation/xxx）
    string url = 11;           // 外链
    string conversation_id = 12; // 打开指定会话
  }

  /// 按 kind 的强类型载荷（可选，无则仅用 title/body）
  oneof payload {
    SystemNotificationPayload system = 20;
    BroadcastNotificationPayload broadcast = 21;
    AlertNotificationPayload alert = 22;
    UserStatusNotificationPayload user_status = 23;
    ConnectionNotificationPayload connection = 24;
    CustomNotificationPayload custom = 25;  // 用户自定义载荷（kind 可为 CUSTOM 或任意）
  }

  map<string, string> attributes = 30;  // 扩展字段（如 locale、trace_id）
}
