import 'package:jiffy/jiffy.dart';
import 'package:json_annotation/json_annotation.dart';

import '../../../apiResponse.dart';
import '../room/getRoomResponse.dart';

part 'getChatResponse.g.dart';

@JsonSerializable(explicitToJson: true)
class GetChatResponse extends ApiResponse {
  Set<GetChatResponseObject> data;

  GetChatResponse(this.data);

  factory GetChatResponse.fromJson(Map<String, dynamic> json) => _$GetChatResponseFromJson(json);
  Map<String, dynamic> toJson() => _$GetChatResponseToJson(this);

  List<GetChatResponseObject> sortByTimestamp() {
    List<GetChatResponseObject> sorted = data.toList();
    sorted.sort((a, b) => a.timestamp.compareTo(b.timestamp));
    return sorted;
  }
}

@JsonSerializable(explicitToJson: true)
class GetChatResponseObject {
  int id;
  String token;
  GetRoomResponseObjectMessageActorType actorType;
  String actorId;
  String actorDisplayName;
  int timestamp;
  String systemMessage;
  GetRoomResponseObjectMessageType messageType;
  bool isReplyable;
  String referenceId;
  String message;
  Map<String, int>? reactions;
  List<String>? reactionsSelf;
  @JsonKey(fromJson: _fromJson) Map<String, RichObjectString>? messageParameters;

  GetChatResponseObject(
      this.id,
      this.token,
      this.actorType,
      this.actorId,
      this.actorDisplayName,
      this.timestamp,
      this.systemMessage,
      this.messageType,
      this.isReplyable,
      this.referenceId,
      this.message,
      this.messageParameters,
      this.reactions,
      this.reactionsSelf
  );

  factory GetChatResponseObject.fromJson(Map<String, dynamic> json) => _$GetChatResponseObjectFromJson(json);
  Map<String, dynamic> toJson() => _$GetChatResponseObjectToJson(this);

  static GetChatResponseObject getDateDummy(int timestamp) {
    DateTime elementDate = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);

    return GetChatResponseObject(
        0,
        "",
        GetRoomResponseObjectMessageActorType.user,
        "",
        "",
        timestamp,
        elementDate.toIso8601String(),
        GetRoomResponseObjectMessageType.system,
        false,
        "",
        Jiffy.parseFromDateTime(elementDate).format(pattern: "dd.MM.yyyy"),
        null,
        null,
        null
    );
  }

}

Map<String, RichObjectString>? _fromJson(json) {
  if(json is Map<String, dynamic>) {
    Map<String, RichObjectString> data = {};
    for (var element in json.keys) {
      data.putIfAbsent(element, () => RichObjectString.fromJson(json[element]));
    }
    return data;
  }

  return null;
}

@JsonSerializable(explicitToJson: true)
class RichObjectString {
  RichObjectStringObjectType type;
  String id;
  String name;

  String? path;
  String? link;

  RichObjectString(this.type, this.id, this.name, this.path, this.link);

  factory RichObjectString.fromJson(Map<String, dynamic> json) => _$RichObjectStringFromJson(json);
  Map<String, dynamic> toJson() => _$RichObjectStringToJson(this);
}

enum RichObjectStringObjectType {
  @JsonValue("user") user,
  @JsonValue("group") group,
  @JsonValue("file") file,
  @JsonValue("guest") guest,
  @JsonValue("highlight") highlight,
  @JsonValue("talk-poll") talkPoll,
}