/// Domain Entity: Chat Room
///
/// Represents a chat conversation room.
library;

/// Room type enum
enum RoomType {
  /// Direct message between two users
  direct,

  /// Group chat
  group,

  /// Support chat with staff
  support,

  /// Order-related chat
  order,

  /// Quote-related chat
  quote;

  /// Get display name for room type
  String get displayName {
    switch (this) {
      case RoomType.direct:
        return 'Direct';
      case RoomType.group:
        return 'Group';
      case RoomType.support:
        return 'Support';
      case RoomType.order:
        return 'Order';
      case RoomType.quote:
        return 'Quote';
    }
  }
}

/// Chat Room Entity
///
/// Contains information about a chat room:
/// - Room type and participants
/// - Related entities (order, quote)
/// - Activity tracking
class ChatRoom {
  /// Unique chat room identifier
  final String chatRoomId;

  /// Room type
  final RoomType roomType;

  /// Related quote ID (if quote chat)
  final String? relatedQuoteId;

  /// Related order ID (if order chat)
  final String? relatedOrderId;

  /// Participant user IDs
  final List<String> participants;

  /// Room name (for group chats)
  final String? roomName;

  /// Room is active
  final bool isActive;

  /// Last activity timestamp
  final DateTime? lastActivity;

  /// Room creation timestamp
  final DateTime createdAt;

  /// User ID who created the room
  final String? createdBy;

  const ChatRoom({
    required this.chatRoomId,
    required this.roomType,
    this.relatedQuoteId,
    this.relatedOrderId,
    required this.participants,
    this.roomName,
    required this.isActive,
    this.lastActivity,
    required this.createdAt,
    this.createdBy,
  });

  /// Check if room is direct message
  bool get isDirect => roomType == RoomType.direct;

  /// Check if room is group chat
  bool get isGroup => roomType == RoomType.group;

  /// Check if room is support chat
  bool get isSupport => roomType == RoomType.support;

  /// Check if room has order context
  bool get hasOrderContext =>
      roomType == RoomType.order && relatedOrderId != null;

  /// Check if room has quote context
  bool get hasQuoteContext =>
      roomType == RoomType.quote && relatedQuoteId != null;

  /// Get number of participants
  int get participantCount => participants.length;

  /// Get display name for room
  String get displayName {
    if (roomName != null && roomName!.isNotEmpty) return roomName!;
    if (isSupport) return 'Customer Support';
    if (hasOrderContext) return 'Order Chat';
    if (hasQuoteContext) return 'Quote Discussion';
    return 'Chat';
  }

  /// Get time since last activity
  Duration? get timeSinceLastActivity {
    if (lastActivity == null) return null;
    return DateTime.now().difference(lastActivity!);
  }

  /// Check if user is participant
  bool isParticipant(String userId) {
    return participants.contains(userId);
  }

  /// Copy with method for immutability
  ChatRoom copyWith({
    String? chatRoomId,
    RoomType? roomType,
    String? relatedQuoteId,
    String? relatedOrderId,
    List<String>? participants,
    String? roomName,
    bool? isActive,
    DateTime? lastActivity,
    DateTime? createdAt,
    String? createdBy,
  }) {
    return ChatRoom(
      chatRoomId: chatRoomId ?? this.chatRoomId,
      roomType: roomType ?? this.roomType,
      relatedQuoteId: relatedQuoteId ?? this.relatedQuoteId,
      relatedOrderId: relatedOrderId ?? this.relatedOrderId,
      participants: participants ?? this.participants,
      roomName: roomName ?? this.roomName,
      isActive: isActive ?? this.isActive,
      lastActivity: lastActivity ?? this.lastActivity,
      createdAt: createdAt ?? this.createdAt,
      createdBy: createdBy ?? this.createdBy,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is ChatRoom &&
        other.chatRoomId == chatRoomId &&
        other.roomType == roomType &&
        other.relatedQuoteId == relatedQuoteId &&
        other.relatedOrderId == relatedOrderId &&
        other.isActive == isActive;
  }

  @override
  int get hashCode {
    return Object.hash(
      chatRoomId,
      roomType,
      relatedQuoteId,
      relatedOrderId,
      isActive,
    );
  }

  @override
  String toString() {
    return 'ChatRoom(chatRoomId: $chatRoomId, roomType: $roomType, '
        'displayName: $displayName, participantCount: $participantCount, '
        'isActive: $isActive)';
  }
}
