import '../../domain/entities/chat_message.dart';

/// Modèle de données pour les messages de chat (Data Transfer Object).
class ChatMessageModel {
  ChatMessageModel({
    required this.id,
    required this.conversationId,
    required this.senderId,
    required this.senderFirstName,
    required this.senderLastName,
    this.senderProfileImageUrl,
    required this.content,
    required this.timestamp,
    required this.isRead,
    this.isDelivered = false,
    this.attachmentUrl,
    this.attachmentType,
  });

  /// Factory pour créer un [ChatMessageModel] à partir d'un JSON.
  factory ChatMessageModel.fromJson(Map<String, dynamic> json) {
    return ChatMessageModel(
      id: _parseId(json, 'id', ''),
      conversationId: _parseString(json, 'conversationId', ''),
      senderId: _parseId(json, 'senderId', ''),
      senderFirstName: _parseString(json, 'senderFirstName', ''),
      senderLastName: _parseString(json, 'senderLastName', ''),
      senderProfileImageUrl: json['senderProfileImageUrl'] as String?,
      content: _parseString(json, 'content', ''),
      timestamp: DateTime.parse(json['timestamp'] as String),
      isRead: json['isRead'] as bool? ?? false,
      isDelivered: json['isDelivered'] as bool? ?? false,
      attachmentUrl: json['attachmentUrl'] as String?,
      attachmentType: _parseAttachmentType(json['attachmentType'] as String?),
    );
  }

  /// Factory pour créer un [ChatMessageModel] à partir d'une entité.
  factory ChatMessageModel.fromEntity(ChatMessage message) {
    return ChatMessageModel(
      id: message.id,
      conversationId: message.conversationId,
      senderId: message.senderId,
      senderFirstName: message.senderFirstName,
      senderLastName: message.senderLastName,
      senderProfileImageUrl: message.senderProfileImageUrl,
      content: message.content,
      timestamp: message.timestamp,
      isRead: message.isRead,
      isDelivered: message.isDelivered,
      attachmentUrl: message.attachmentUrl,
      attachmentType: message.attachmentType,
    );
  }

  final String id;
  final String conversationId;
  final String senderId;
  final String senderFirstName;
  final String senderLastName;
  final String? senderProfileImageUrl;
  final String content;
  final DateTime timestamp;
  final bool isRead;
  final bool isDelivered;
  final String? attachmentUrl;
  final AttachmentType? attachmentType;

  /// Convertit ce modèle en JSON pour l'envoi vers l'API.
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'conversationId': conversationId,
      'senderId': senderId,
      'senderFirstName': senderFirstName,
      'senderLastName': senderLastName,
      if (senderProfileImageUrl != null) 'senderProfileImageUrl': senderProfileImageUrl,
      'content': content,
      'timestamp': timestamp.toIso8601String(),
      'isRead': isRead,
      'isDelivered': isDelivered,
      if (attachmentUrl != null) 'attachmentUrl': attachmentUrl,
      if (attachmentType != null) 'attachmentType': _attachmentTypeToString(attachmentType!),
    };
  }

  /// Convertit ce modèle vers une entité de domaine [ChatMessage].
  ChatMessage toEntity() {
    return ChatMessage(
      id: id,
      conversationId: conversationId,
      senderId: senderId,
      senderFirstName: senderFirstName,
      senderLastName: senderLastName,
      senderProfileImageUrl: senderProfileImageUrl,
      content: content,
      timestamp: timestamp,
      isRead: isRead,
      isDelivered: isDelivered,
      attachmentUrl: attachmentUrl,
      attachmentType: attachmentType,
    );
  }

  // Méthodes de parsing
  static String _parseString(Map<String, dynamic> json, String key, String defaultValue) {
    return json[key] as String? ?? defaultValue;
  }

  static String _parseId(Map<String, dynamic> json, String key, String defaultValue) {
    final value = json[key];
    if (value == null) return defaultValue;
    return value.toString();
  }

  static AttachmentType? _parseAttachmentType(String? type) {
    if (type == null) return null;

    switch (type.toLowerCase()) {
      case 'image':
        return AttachmentType.image;
      case 'video':
        return AttachmentType.video;
      case 'audio':
        return AttachmentType.audio;
      case 'file':
        return AttachmentType.file;
      default:
        return null;
    }
  }

  static String _attachmentTypeToString(AttachmentType type) {
    return type.toString().split('.').last;
  }
}
