enum DivinationMethod { manual, auto } enum QuestionType { career, love, wealth, fortune, dream, health, study, search, other, } enum YaoType { undetermined, youngYang, youngYin, oldYang, oldYin } class DivinationParams { const DivinationParams({ required this.method, required this.questionType, required this.question, required this.divinationTime, required this.coinBalance, required this.userId, }); final DivinationMethod method; final QuestionType questionType; final String question; final DateTime divinationTime; final int coinBalance; final String userId; DivinationParams copyWith({ DivinationMethod? method, QuestionType? questionType, String? question, DateTime? divinationTime, int? coinBalance, String? userId, }) { return DivinationParams( method: method ?? this.method, questionType: questionType ?? this.questionType, question: question ?? this.question, divinationTime: divinationTime ?? this.divinationTime, coinBalance: coinBalance ?? this.coinBalance, userId: userId ?? this.userId, ); } Map toPayload() { return { 'method': method.name, 'questionType': questionType.name, 'question': question, 'divinationTime': divinationTime.toIso8601String(), 'coinBalance': coinBalance, 'userId': userId, }; } factory DivinationParams.fromPayload(Map payload) { return DivinationParams( method: divinationMethodFromName(_requiredString(payload, 'method')), questionType: questionTypeFromName( _requiredString(payload, 'questionType'), ), question: _requiredString(payload, 'question'), divinationTime: DateTime.parse( _requiredString(payload, 'divinationTime'), ), coinBalance: _requiredInt(payload, 'coinBalance'), userId: _requiredString(payload, 'userId'), ); } String toBinary(List yaoStates) { return yaoStates .map( (v) => switch (v) { YaoType.youngYang || YaoType.oldYang => '1', _ => '0', }, ) .join(); } String toChangedBinary(List yaoStates) { return yaoStates .map( (v) => switch (v) { YaoType.youngYang => '1', YaoType.youngYin => '0', YaoType.oldYang => '0', YaoType.oldYin => '1', YaoType.undetermined => '0', }, ) .join(); } } DivinationMethod divinationMethodFromName(String raw) { return DivinationMethod.values.firstWhere( (value) => value.name == raw, orElse: () => DivinationMethod.manual, ); } QuestionType questionTypeFromName(String raw) { return QuestionType.values.firstWhere( (value) => value.name == raw, orElse: () => QuestionType.other, ); } YaoType yaoTypeFromName(String raw) { return YaoType.values.firstWhere( (value) => value.name == raw, orElse: () => YaoType.undetermined, ); } String _requiredString(Map json, String key) { final value = json[key]; if (value is! String || value.isEmpty) { throw FormatException('Missing required string: $key'); } return value; } int _requiredInt(Map json, String key) { final value = json[key]; if (value is int) { return value; } if (value is num) { return value.toInt(); } throw FormatException('Missing required int: $key'); }