import 'dart:typed_data'; enum MessageStatus { sending, sent, delivered, read, failed } enum MessageType { text, image } class MessageModel { final int? id; // server id (null пока не подтверждено сервером) final int? tempId; // client temp id (для сопоставления ack) final int senderId; final int receiverId; final String text; // текст для UI (у нас уже расшифрованный) final DateTime createdAt; final bool isMe; final MessageStatus status; final int? replyToId; // ID сообщения, на которое отвечают final String? replyToText; // текст сообщения, на которое отвечают (для отображения) final DateTime? editedAt; final Uint8List? localFileBytes; final MessageType messageType; final String? fileId; final String? encryptedFileKey; MessageModel({ this.id, this.tempId, required this.senderId, required this.receiverId, required this.text, required this.createdAt, required this.isMe, this.status = MessageStatus.sent, this.replyToId, this.replyToText, this.editedAt, this.localFileBytes, this.messageType = MessageType.text, this.fileId, this.encryptedFileKey, }); MessageModel copyWith({ int? id, int? tempId, int? senderId, int? receiverId, String? text, DateTime? createdAt, bool? isMe, MessageStatus? status, int? replyToId, String? replyToText, DateTime? editedAt, Uint8List? localFileBytes, MessageType? messageType, String? fileId, String? encryptedFileKey, }) { return MessageModel( id: id ?? this.id, tempId: tempId ?? this.tempId, senderId: senderId ?? this.senderId, receiverId: receiverId ?? this.receiverId, text: text ?? this.text, createdAt: createdAt ?? this.createdAt, isMe: isMe ?? this.isMe, status: status ?? this.status, replyToId: replyToId ?? this.replyToId, replyToText: replyToText ?? this.replyToText, editedAt: editedAt ?? this.editedAt, localFileBytes: localFileBytes ?? this.localFileBytes, messageType: messageType ?? this.messageType, fileId: fileId ?? this.fileId, encryptedFileKey: encryptedFileKey ?? this.encryptedFileKey, ); } factory MessageModel.fromJson(Map json, int currentUserId) { final senderId = int.parse(json['sender_id'].toString()); final receiverId = int.parse((json['receiver_id'] ?? json['recipient_id']).toString()); final createdAtRaw = (json['created_at'] ?? json['timestamp']).toString(); return MessageModel( id: json['id'] == null ? null : int.tryParse(json['id'].toString()), tempId: json['temp_id'] == null ? null : int.tryParse(json['temp_id'].toString()), senderId: senderId, receiverId: receiverId, text: (json['text'] ?? json['content'] ?? '').toString(), createdAt: DateTime.tryParse(createdAtRaw) ?? DateTime.now(), isMe: senderId == currentUserId, status: MessageStatus.sent, replyToId: json['reply_to_id'] == null ? null : int.tryParse(json['reply_to_id'].toString()), replyToText: json['reply_to_text'] == null ? null : json['reply_to_text'].toString(), editedAt: json['edited_at'] == null ? null : DateTime.tryParse(json['edited_at'].toString()), messageType: json['message_type'] == 'image' ? MessageType.image : MessageType.text, fileId: json['file_id']?.toString(), encryptedFileKey: json['encrypted_key']?.toString(), ); } Map toJson() { return { 'id': id, 'temp_id': tempId, 'sender_id': senderId, 'receiver_id': receiverId, 'text': text, 'created_at': createdAt.toIso8601String(), 'status': status.name, 'reply_to_id': replyToId, 'reply_to_text': replyToText, 'edited_at': editedAt?.toIso8601String(), 'message_type': messageType == MessageType.image ? 'image' : 'text', 'file_id': fileId, 'encrypted_key': encryptedFileKey, }; } }