import 'dart:convert';

class UserModel {
  final String? id;
  final String? name;
  final int? userId;
  final String? teamId;

  final String? email;
  final String? password;
  final String? twoFactorKey;
  final String? apiKey;
  final String? apiBindKey;
  final int? protectRole;
  final int? risks;

  final String? mcName;
  final Map<String, int>? userName2userId;
  final String? lxKey;
  final String? dfUsername;
  final String? dfPassword;
  final int? nuoId;
  final String? botId;
  final String? spasolBotId;
  final String? githubId;

  final int? rating;
  final int? ratingMax;
  final int? iconId;
  final int? plateId;
  final List<int>? plateIds;
  final int? frameId;
  final List<int>? charaSlots;
  final String? qiandaoDay;
  final String? inviter;
  final List<List<int>>? successLogoutTime;
  final int? lastLoginTime;
  final List<String>? friendIds;
  final String? bio;
  final String? friendBio;
  final String? sex;
  final bool? isDisagreeRecommend;
  final bool? isDisagreeFriend;

  final int? points;
  final int? planPoints;
  final List<String>? cardIds;
  final List<Card>? userCards;
  final List<String>? tags;

  final bool? useBeta;
  final bool? useNuo;
  final String? useServer;
  final int? useB50Type;

  final Map<String, int>? userHot;
  final Map<String, int>? chatInGroupNumbers;
  final int? sc;
  final Map<String, int>? id2pcNuo;

  final Map<String, String>? mai2links;
  final Map<String, String>? key2KeychipEn;
  final Map<String, String>? key2key2KeychipEn;
  final String? mai2link;

  final RegionData? userRegion;

  final String? rinUsernameOrEmail;
  final String? rinPassword;
  final dynamic rinChusanUser;

  final List<SegaCard>? segaCards;

  final Map<String, int>? placeList;
  final String? lastKeyChip;
  final String? token;
  final Map<String, RegionData>? timesRegionData;

  final Map<String, String>? yearTotal;
  final Map<String, String>? yearTotalComment;

  final Map<String, UserCollCard>? userCollCardMap;
  final Map<String, List<String>>? collName2musicIds;
  final bool? ai;

  final int? pkScore;
  final String? pkScoreStr;
  final int? pkScoreReality;
  final int? pkUserId;
  final int? limitPkTimestamp;
  final int? hasAcceptPk;
  final int? pkPlayNum;
  final bool? pkWin;

  final dynamic userData;
  final int? banState;

  UserModel({
    this.id,
    this.name,
    this.userId,
    this.teamId,
    this.email,
    this.password,
    this.twoFactorKey,
    this.apiKey,
    this.apiBindKey,
    this.protectRole,
    this.risks,
    this.mcName,
    this.userName2userId,
    this.lxKey,
    this.dfUsername,
    this.dfPassword,
    this.nuoId,
    this.botId,
    this.spasolBotId,
    this.githubId,
    this.rating,
    this.ratingMax,
    this.iconId,
    this.plateId,
    this.plateIds,
    this.frameId,
    this.charaSlots,
    this.qiandaoDay,
    this.inviter,
    this.successLogoutTime,
    this.lastLoginTime,
    this.friendIds,
    this.bio,
    this.friendBio,
    this.sex,
    this.isDisagreeRecommend,
    this.isDisagreeFriend,
    this.points,
    this.planPoints,
    this.cardIds,
    this.userCards,
    this.tags,
    this.useBeta,
    this.useNuo,
    this.useServer,
    this.useB50Type,
    this.userHot,
    this.chatInGroupNumbers,
    this.sc,
    this.id2pcNuo,
    this.mai2links,
    this.key2KeychipEn,
    this.key2key2KeychipEn,
    this.mai2link,
    this.userRegion,
    this.rinUsernameOrEmail,
    this.rinPassword,
    this.rinChusanUser,
    this.segaCards,
    this.placeList,
    this.lastKeyChip,
    this.token,
    this.timesRegionData,
    this.yearTotal,
    this.yearTotalComment,
    this.userCollCardMap,
    this.collName2musicIds,
    this.ai,
    this.pkScore,
    this.pkScoreStr,
    this.pkScoreReality,
    this.pkUserId,
    this.limitPkTimestamp,
    this.hasAcceptPk,
    this.pkPlayNum,
    this.pkWin,
    this.userData,
    this.banState,
  });

  // ====================== 你要的 TOJSON 完整写好了 ======================
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'userId': userId,
      'teamId': teamId,
      'email': email,
      'password': password,
      'twoFactorKey': twoFactorKey,
      'apiKey': apiKey,
      'apiBindKey': apiBindKey,
      'protectRole': protectRole,
      'risks': risks,
      'mcName': mcName,
      'userName2userId': userName2userId,
      'lxKey': lxKey,
      'df_username': dfUsername,
      'df_password': dfPassword,
      'nuoId': nuoId,
      'botId': botId,
      'spasolBotId': spasolBotId,
      'githubId': githubId,
      'rating': rating,
      'rating_max': ratingMax,
      'iconId': iconId,
      'plateId': plateId,
      'plateIds': plateIds,
      'frameId': frameId,
      'charaSlots': charaSlots,
      'qiandaoDay': qiandaoDay,
      'inviter': inviter,
      'successLogoutTime': successLogoutTime,
      'lastLoginTime': lastLoginTime,
      'friendIds': friendIds,
      'bio': bio,
      'friend_bio': friendBio,
      'sex': sex,
      'isDisagreeRecommend': isDisagreeRecommend,
      'isDisagreeFriend': isDisagreeFriend,
      'points': points,
      'plan_points': planPoints,
      'cardIds': cardIds,
      'userCards': userCards?.map((e) => e.toJson()).toList(),
      'tags': tags,
      'useBeta': useBeta,
      'useNuo': useNuo,
      'useServer': useServer,
      'useB50Type': useB50Type,
      'userHot': userHot,
      'chatInGroupNumbers': chatInGroupNumbers,
      'sc': sc,
      'id2pcNuo': id2pcNuo,
      'mai2links': mai2links,
      'key2KeychipEn': key2KeychipEn,
      'key2key2KeychipEn': key2key2KeychipEn,
      'mai2link': mai2link,
      'userRegion': userRegion?.toJson(),
      'rin_usernameOrEmail': rinUsernameOrEmail,
      'rin_password': rinPassword,
      'rinChusanUser': rinChusanUser,
      'segaCards': segaCards?.map((e) => e.toJson()).toList(),
      'placeList': placeList,
      'lastKeyChip': lastKeyChip,
      'token': token,
      'timesRegionData': timesRegionData?.map((k, v) => MapEntry(k, v.toJson())),
      'yearTotal': yearTotal,
      'yearTotal_comment': yearTotalComment,
      'userCollCardMap': userCollCardMap?.map((k, v) => MapEntry(k, v.toJson())),
      'collName2musicIds': collName2musicIds,
      'ai': ai,
      'pkScore': pkScore,
      'pkScoreStr': pkScoreStr,
      'pk_score_reality': pkScoreReality,
      'pk_userId': pkUserId,
      'limit_pk_timestamp': limitPkTimestamp,
      'has_accept_pk': hasAcceptPk,
      'pk_play_num': pkPlayNum,
      'pk_win': pkWin,
      'userData': userData,
      'banState': banState,
    };
  }

  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['id'],
      name: json['name'],
      userId: json['userId'],
      teamId: json['teamId'],
      email: json['email'],
      password: json['password'],
      twoFactorKey: json['twoFactorKey'],
      apiKey: json['apiKey'],
      apiBindKey: json['apiBindKey'],
      protectRole: json['protectRole'],
      risks: json['risks'],
      mcName: json['mcName'],
      userName2userId: _mapStringInt(json['userName2userId']),
      lxKey: json['lxKey'],
      dfUsername: json['df_username'],
      dfPassword: json['df_password'],
      nuoId: json['nuoId'],
      botId: json['botId'],
      spasolBotId: json['spasolBotId'],
      githubId: json['githubId'],
      rating: json['rating'],
      ratingMax: json['rating_max'],
      iconId: json['iconId'],
      plateId: json['plateId'],
      plateIds: _listInt(json['plateIds']),
      frameId: json['frameId'],
      charaSlots: _listInt(json['charaSlots']),
      qiandaoDay: json['qiandaoDay'],
      inviter: json['inviter'],
      successLogoutTime: _listListInt(json['successLogoutTime']),
      lastLoginTime: json['lastLoginTime'],
      friendIds: _listString(json['friendIds']),
      bio: json['bio'],
      friendBio: json['friend_bio'],
      sex: json['sex'],
      isDisagreeRecommend: json['isDisagreeRecommend'],
      isDisagreeFriend: json['isDisagreeFriend'],
      points: json['points'],
      planPoints: json['plan_points'],
      cardIds: _listString(json['cardIds']),
      userCards: _listCard(json['userCards']),
      tags: _listString(json['tags']),
      useBeta: json['useBeta'],
      useNuo: json['useNuo'],
      useServer: json['useServer'],
      useB50Type: json['useB50Type'],
      userHot: _mapStringInt(json['userHot']),
      chatInGroupNumbers: _mapStringInt(json['chatInGroupNumbers']),
      sc: json['sc'],
      id2pcNuo: _mapStringInt(json['id2pcNuo']),
      mai2links: _mapStringString(json['mai2links']),
      key2KeychipEn: _mapStringString(json['key2KeychipEn']),
      key2key2KeychipEn: _mapStringString(json['key2key2KeychipEn']),
      mai2link: json['mai2link'],
      userRegion: json['userRegion'] != null ? RegionData.fromJson(json['userRegion']) : null,
      rinUsernameOrEmail: json['rin_usernameOrEmail'],
      rinPassword: json['rin_password'],
      rinChusanUser: json['rinChusanUser'],
      segaCards: _listSegaCard(json['segaCards']),
      placeList: _mapStringInt(json['placeList']),
      lastKeyChip: json['lastKeyChip'],
      token: json['token'],
      timesRegionData: _mapStringRegionData(json['timesRegionData']),
      yearTotal: _mapStringString(json['yearTotal']),
      yearTotalComment: _mapStringString(json['yearTotal_comment']),
      userCollCardMap: _mapStringUserCollCard(json['userCollCardMap']),
      collName2musicIds: _mapStringListString(json['collName2musicIds']),
      ai: json['ai'],
      pkScore: json['pkScore'],
      pkScoreStr: json['pkScoreStr'],
      pkScoreReality: json['pk_score_reality'],
      pkUserId: json['pk_userId'],
      limitPkTimestamp: json['limit_pk_timestamp'],
      hasAcceptPk: json['has_accept_pk'],
      pkPlayNum: json['pk_play_num'],
      pkWin: json['pk_win'],
      userData: json['userData'],
      banState: json['banState'],
    );
  }

  static List<int>? _listInt(dynamic data) {
    if (data is List) return List<int>.from(data);
    return null;
  }

  static List<String>? _listString(dynamic data) {
    if (data is List) return List<String>.from(data);
    return null;
  }

  static List<List<int>>? _listListInt(dynamic data) {
    if (data is List) {
      return data.map((e) => _listInt(e)).whereType<List<int>>().toList();
    }
    return null;
  }

  static List<Card>? _listCard(dynamic data) {
    if (data is List) return data.map((e) => Card.fromJson(e)).toList();
    return null;
  }

  static List<SegaCard>? _listSegaCard(dynamic data) {
    if (data is List) return data.map((e) => SegaCard.fromJson(e)).toList();
    return null;
  }

  static Map<String, int>? _mapStringInt(dynamic data) {
    if (data is Map) {
      return Map.from(data).map((k, v) => MapEntry(k.toString(), v as int));
    }
    return null;
  }

  static Map<String, String>? _mapStringString(dynamic data) {
    if (data is Map) {
      return Map.from(data).map((k, v) => MapEntry(k.toString(), v.toString()));
    }
    return null;
  }

  static Map<String, List<String>>? _mapStringListString(dynamic data) {
    if (data is Map) {
      return Map.from(data).map((k, v) {
        return MapEntry(k.toString(), _listString(v) ?? []);
      });
    }
    return null;
  }

  static Map<String, RegionData>? _mapStringRegionData(dynamic data) {
    if (data is Map) {
      return Map.from(data).map((k, v) {
        return MapEntry(k.toString(), RegionData.fromJson(v));
      });
    }
    return null;
  }

  static Map<String, UserCollCard>? _mapStringUserCollCard(dynamic data) {
    if (data is Map) {
      return Map.from(data).map((k, v) {
        return MapEntry(k.toString(), UserCollCard.fromJson(v));
      });
    }
    return null;
  }
}

// ==============================
// 1. UserCollCard
// ==============================
class UserCollCard {
  final int? titleId;
  final int? plateId;
  final int? frameId;
  final int? iconId;
  final List<int>? charaIds;
  final dynamic userData;

  UserCollCard({
    this.titleId,
    this.plateId,
    this.frameId,
    this.iconId,
    this.charaIds,
    this.userData,
  });

  factory UserCollCard.fromJson(Map<String, dynamic> json) {
    return UserCollCard(
      titleId: json['titleId'],
      plateId: json['plateId'],
      frameId: json['frameId'],
      iconId: json['iconId'],
      charaIds: UserModel._listInt(json['charaIds']),
      userData: json['userData'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'titleId': titleId,
      'plateId': plateId,
      'frameId': frameId,
      'iconId': iconId,
      'charaIds': charaIds,
      'userData': userData,
    };
  }
}

// ==============================
// 2. SegaCard
// ==============================
class SegaCard {
  final String? type;
  final String? segaId;
  final String? password;

  SegaCard({
    this.type,
    this.segaId,
    this.password,
  });

  factory SegaCard.fromJson(Map<String, dynamic> json) {
    return SegaCard(
      type: json['type'],
      segaId: json['segaId'],
      password: json['password'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'type': type,
      'segaId': segaId,
      'password': password,
    };
  }
}

// ==============================
// 3. Card
// ==============================
class Card {
  final String? username;
  final int? iconId;
  final String? uid;
  final int? plateId;
  final int? charaId;
  final int? rating;

  Card({
    this.username,
    this.iconId,
    this.uid,
    this.plateId,
    this.charaId,
    this.rating,
  });

  factory Card.fromJson(Map<String, dynamic> json) {
    return Card(
      username: json['username'],
      iconId: json['iconId'],
      uid: json['uid'],
      plateId: json['plateId'],
      charaId: json['charaId'],
      rating: json['rating'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'username': username,
      'iconId': iconId,
      'uid': uid,
      'plateId': plateId,
      'charaId': charaId,
      'rating': rating,
    };
  }
}

// ==============================
// 4. RegionData
// ==============================
class RegionData {
  final String? province;
  final int? playCount;
  final String? created;

  RegionData({
    this.province,
    this.playCount,
    this.created,
  });

  factory RegionData.fromJson(Map<String, dynamic> json) {
    return RegionData(
      province: json['province'],
      playCount: json['playCount'],
      created: json['created'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'province': province,
      'playCount': playCount,
      'created': created,
    };
  }
}