import 'dart:typed_data';
import 'dart:io';

enum MessageStatus { encrypting, sending, sent, delivered, read, failed }

enum MessageType { text, image, video, file, videoNote, voiceNote }

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 File? localFile;
  final MessageType messageType;
  final String? fileId;
  final String? encryptedFileKey;
  final String? fileName;
  final int? fileSize;

  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.localFile,
    this.messageType = MessageType.text,
    this.fileId,
    this.encryptedFileKey,
    this.fileName,
    this.fileSize
  });

  MessageModel copyWith({
    int? id,
    int? tempId,
    int? senderId,
    int? receiverId,
    String? text,
    DateTime? createdAt,
    bool? isMe,
    MessageStatus? status,
    int? replyToId,
    String? replyToText,
    DateTime? editedAt,
    File? localFile,
    MessageType? messageType,
    String? fileId,
    String? encryptedFileKey,
    String? fileName,
    int? fileSize,
  }) {
    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,
      localFile: localFile ?? this.localFile,
      messageType: messageType ?? this.messageType,
      fileId: fileId ?? this.fileId,
      encryptedFileKey: encryptedFileKey ?? this.encryptedFileKey,
      fileName: fileName ?? this.fileName,
      fileSize: fileSize ?? this.fileSize,
    );
  }

  factory MessageModel.fromJson(Map<String, dynamic> 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();
    final messageTypeStr = json['message_type']?.toString() ?? 'text';

    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: MessageModel.parseMessageType(messageTypeStr),
      fileId: json['file_id']?.toString(),
      encryptedFileKey: json['encrypted_key']?.toString(),
      fileName: json['file_name']?.toString(),
      fileSize: json['file_size'] == null ? null : int.tryParse(json['file_size'].toString()),
    );
  }

  static MessageType parseMessageType(String typeStr) {
    switch (typeStr.toLowerCase()) {
      case 'image':
        return MessageType.image;
      case 'video':
        return MessageType.video;
      case 'file':
        return MessageType.file;
      case 'video_note':
      case 'videonote':
        return MessageType.videoNote;
      case 'voice_note':
      case 'voicenote':
        return MessageType.voiceNote;
      case 'text':
      default:
        return MessageType.text;
    }
  }

  
  static String getMediaPreview(MessageType type) {
    switch (type) {
      case MessageType.videoNote:
        return '[Кружок]';
      case MessageType.voiceNote:
        return '[Голосовое]';
      case MessageType.image:
        return '[Фото]';
      case MessageType.video:
        return '[Видео]';
      case MessageType.file:
        return '[Файл]';
      case MessageType.text:
        return '';
    }
  }

  Map<String, dynamic> 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.name,
      'file_id': fileId,
      'encrypted_key': encryptedFileKey,
      'file_name': fileName,
      'file_size': fileSize,
    };
  }
}
