class PostCreator {
  final String id;
  final String displayName;

  PostCreator({
    required this.id,
    required this.displayName,
  });

  factory PostCreator.fromJson(Map<String, dynamic> json) {
    return PostCreator(
      id: json['id']?.toString() ?? '',
      displayName: json['displayName'] ?? '',
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'displayName': displayName,
    };
  }
}

class Post {
  final String id;
  final String creatorId;
  final PostCreator creator;
  final String body;
  final int likes;
  final int comments;
  final DateTime creationDate;
  final bool liked;

  Post({
    required this.id,
    required this.creatorId,
    required this.creator,
    required this.body,
    required this.likes,
    required this.comments,
    required this.creationDate,
    this.liked = false,
  });

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json['id']?.toString() ?? '',
      creatorId: json['creatorId']?.toString() ?? '',
      creator: PostCreator.fromJson(json['creator'] ?? {}),
      body: json['body'] ?? '',
      likes: int.tryParse(json['likes']?.toString() ?? '0') ?? 0,
      comments: int.tryParse(json['comments']?.toString() ?? '0') ?? 0,
      creationDate: DateTime.parse(json['creationDate'] ?? DateTime.now().toIso8601String()),
      liked: json['liked'] == true,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'creatorId': creatorId,
      'creator': creator.toJson(),
      'body': body,
      'likes': likes,
      'comments': comments,
      'creationDate': creationDate.toIso8601String(),
      'liked': liked,
    };
  }

  Post copyWith({
    String? id,
    String? creatorId,
    PostCreator? creator,
    String? body,
    int? likes,
    int? comments,
    DateTime? creationDate,
    bool? liked,
  }) {
    return Post(
      id: id ?? this.id,
      creatorId: creatorId ?? this.creatorId,
      creator: creator ?? this.creator,
      body: body ?? this.body,
      likes: likes ?? this.likes,
      comments: comments ?? this.comments,
      creationDate: creationDate ?? this.creationDate,
      liked: liked ?? this.liked,
    );
  }
}

class LikedUser {
  final String id;
  final String displayName;
  final DateTime likeTime;

  LikedUser({
    required this.id,
    required this.displayName,
    required this.likeTime,
  });

  factory LikedUser.fromJson(Map<String, dynamic> json) {
    return LikedUser(
      id: json['id']?.toString() ?? '',
      displayName: json['displayName'] ?? '',
      likeTime: DateTime.parse(json['likeTime'] ?? DateTime.now().toIso8601String()),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'displayName': displayName,
      'likeTime': likeTime.toIso8601String(),
    };
  }
}

class DetailedPost {
  final String id;
  final PostCreator creator;
  final String body;
  final int likes;
  final int comments;
  final bool liked;
  final DateTime creationDate;
  final List<LikedUser> likedUsers;

  DetailedPost({
    required this.id,
    required this.creator,
    required this.body,
    required this.likes,
    required this.comments,
    required this.liked,
    required this.creationDate,
    required this.likedUsers,
  });

  factory DetailedPost.fromJson(Map<String, dynamic> json) {
    return DetailedPost(
      id: json['id']?.toString() ?? '',
      creator: PostCreator.fromJson(json['creator'] ?? {}),
      body: json['body'] ?? '',
      likes: int.tryParse(json['likes']?.toString() ?? '0') ?? 0,
      comments: int.tryParse(json['comments']?.toString() ?? '0') ?? 0,
      liked: json['liked'] == true,
      creationDate: DateTime.parse(json['creationDate'] ?? DateTime.now().toIso8601String()),
      likedUsers: (json['likedUsers'] as List?)
          ?.map((user) => LikedUser.fromJson(user))
          .toList() ?? [],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'creator': creator.toJson(),
      'body': body,
      'likes': likes,
      'comments': comments,
      'liked': liked,
      'creationDate': creationDate.toIso8601String(),
      'likedUsers': likedUsers.map((user) => user.toJson()).toList(),
    };
  }
}

class CreatePostRequest {
  final String body;

  CreatePostRequest({required this.body});

  Map<String, dynamic> toJson() {
    return {
      'body': body,
    };
  }
}