import 'dart:convert';
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/core/database/models/enums.dart';

part 'message_model.g.dart';

@HiveType(typeId: HiveTypeIds.messageModel)
class MessageModel extends HiveObject {
  MessageModel({
    required this.messageId,
    required this.chatRoomId,
    required this.senderId,
    required this.contentType,
    required this.content,
    this.attachmentUrl,
    this.productReference,
    required this.isRead,
    required this.isEdited,
    required this.isDeleted,
    this.readBy,
    required this.timestamp,
    this.editedAt,
  });

  @HiveField(0)
  final String messageId;
  @HiveField(1)
  final String chatRoomId;
  @HiveField(2)
  final String senderId;
  @HiveField(3)
  final ContentType contentType;
  @HiveField(4)
  final String content;
  @HiveField(5)
  final String? attachmentUrl;
  @HiveField(6)
  final String? productReference;
  @HiveField(7)
  final bool isRead;
  @HiveField(8)
  final bool isEdited;
  @HiveField(9)
  final bool isDeleted;
  @HiveField(10)
  final String? readBy;
  @HiveField(11)
  final DateTime timestamp;
  @HiveField(12)
  final DateTime? editedAt;

  factory MessageModel.fromJson(Map<String, dynamic> json) => MessageModel(
    messageId: json['message_id'] as String,
    chatRoomId: json['chat_room_id'] as String,
    senderId: json['sender_id'] as String,
    contentType: ContentType.values.firstWhere(
      (e) => e.name == json['content_type'],
    ),
    content: json['content'] as String,
    attachmentUrl: json['attachment_url'] as String?,
    productReference: json['product_reference'] as String?,
    isRead: json['is_read'] as bool? ?? false,
    isEdited: json['is_edited'] as bool? ?? false,
    isDeleted: json['is_deleted'] as bool? ?? false,
    readBy: json['read_by'] != null ? jsonEncode(json['read_by']) : null,
    timestamp: DateTime.parse(json['timestamp']?.toString() ?? ''),
    editedAt: json['edited_at'] != null
        ? DateTime.parse(json['edited_at']?.toString() ?? '')
        : null,
  );

  Map<String, dynamic> toJson() => {
    'message_id': messageId,
    'chat_room_id': chatRoomId,
    'sender_id': senderId,
    'content_type': contentType.name,
    'content': content,
    'attachment_url': attachmentUrl,
    'product_reference': productReference,
    'is_read': isRead,
    'is_edited': isEdited,
    'is_deleted': isDeleted,
    'read_by': readBy != null ? jsonDecode(readBy!) : null,
    'timestamp': timestamp.toIso8601String(),
    'edited_at': editedAt?.toIso8601String(),
  };

  List<String>? get readByList {
    if (readBy == null) return null;
    try {
      final decoded = jsonDecode(readBy!) as List;
      return decoded.map((e) => e.toString()).toList();
    } catch (e) {
      return null;
    }
  }
}
