class ResponseModel<T> {
  final int code;
  final String msg;
  final T? data;
  final String uuid;
  final bool success;
  final int timestamp;

  ResponseModel({
    required this.code,
    required this.msg,
    this.data,
    required this.uuid,
    required this.success,
    required this.timestamp,
  });

  factory ResponseModel.fromJson(
    Map<String, dynamic> json, {
    required String uuid,
    T Function(dynamic)? fromJsonT,
  }) {
    final code = json['code'] as int? ?? -1;
    return ResponseModel<T>(
      code: code,
      msg: json['msg'] as String? ?? '未知错误',
      data: json['data'] != null && fromJsonT != null
          ? fromJsonT(json['data'])
          : json['data'] as T?,
      uuid: uuid,
      success: code == 200,
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  factory ResponseModel.error({
    required String uuid,
    required String msg,
    int code = -1,
  }) {
    return ResponseModel<T>(
      code: code,
      msg: msg,
      data: null,
      uuid: uuid,
      success: false,
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  Map<String, dynamic> toJson([Object? Function(T value)? toJsonT]) {
    return {
      'code': code,
      'msg': msg,
      'data': toJsonT != null && data != null ? toJsonT(data as T) : data,
      'uuid': uuid,
      'success': success,
      'timestamp': timestamp,
    };
  }

  ResponseModel<R> copyWith<R>({
    int? code,
    String? msg,
    R? data,
    String? uuid,
    bool? success,
    int? timestamp,
  }) {
    return ResponseModel<R>(
      code: code ?? this.code,
      msg: msg ?? this.msg,
      data: data,
      uuid: uuid ?? this.uuid,
      success: success ?? this.success,
      timestamp: timestamp ?? this.timestamp,
    );
  }

  @override
  String toString() {
    return 'ResponseModel(code: $code, msg: $msg, uuid: $uuid, success: $success)';
  }
}
