Files
999/lib/models/syncretic_session_model.dart
T

173 lines
5.7 KiB
Dart

import 'dart:convert';
import 'word_model.dart';
/// Single item in a divination reading (e.g. a drawn Rune, Card, Hexagram, or Sign)
class ReadingSignItem {
final String title;
final String? subtitle;
final String? symbol;
final String? lore;
final bool isReversed;
final WordItem? linkedWord;
final Map<String, dynamic>? meta;
const ReadingSignItem({
required this.title,
this.subtitle,
this.symbol,
this.lore,
this.isReversed = false,
this.linkedWord,
this.meta,
});
Map<String, dynamic> toMap() => {
'title': title,
if (subtitle != null) 'subtitle': subtitle,
if (symbol != null) 'symbol': symbol,
if (lore != null) 'lore': lore,
'isReversed': isReversed,
if (linkedWord != null) 'linkedWord': linkedWord!.toMap(),
if (meta != null) 'meta': meta,
};
factory ReadingSignItem.fromMap(Map<String, dynamic> map) => ReadingSignItem(
title: map['title'] as String? ?? '',
subtitle: map['subtitle'] as String?,
symbol: map['symbol'] as String?,
lore: map['lore'] as String?,
isReversed: map['isReversed'] as bool? ?? false,
linkedWord: map['linkedWord'] != null
? WordItem.fromMap(map['linkedWord'] as Map<String, dynamic>)
: null,
meta: map['meta'] as Map<String, dynamic>?,
);
}
/// A single completed divination reading inside a day session
class SyncreticReading {
final String id;
final String systemId; // 'cleromancy', 'matrix', 'runes', 'lenormand', 'tarot', 'iching', 'ogham', 'geomancy'
final String systemName;
final String systemIcon;
final DateTime timestamp;
final String layoutTitle; // e.g. 'Бросок 2d12', 'Ленорман d6+d12', 'Триптих Норн'
final String inputMethod; // 'dice' | 'manual'
final List<ReadingSignItem> items;
final String? note;
final String? question;
const SyncreticReading({
required this.id,
required this.systemId,
required this.systemName,
required this.systemIcon,
required this.timestamp,
required this.layoutTitle,
this.inputMethod = 'dice',
required this.items,
this.note,
this.question,
});
String get formattedTime {
final hour = timestamp.hour.toString().padLeft(2, '0');
final min = timestamp.minute.toString().padLeft(2, '0');
return '$hour:$min';
}
Map<String, dynamic> toMap() => {
'id': id,
'systemId': systemId,
'systemName': systemName,
'systemIcon': systemIcon,
'timestamp': timestamp.toIso8601String(),
'layoutTitle': layoutTitle,
'inputMethod': inputMethod,
'items': items.map((i) => i.toMap()).toList(),
if (note != null) 'note': note,
if (question != null) 'question': question,
};
factory SyncreticReading.fromMap(Map<String, dynamic> map) => SyncreticReading(
id: map['id'] as String? ?? '',
systemId: map['systemId'] as String? ?? '',
systemName: map['systemName'] as String? ?? '',
systemIcon: map['systemIcon'] as String? ?? '🔮',
timestamp: DateTime.tryParse(map['timestamp'] as String? ?? '') ?? DateTime.now(),
layoutTitle: map['layoutTitle'] as String? ?? '',
inputMethod: map['inputMethod'] as String? ?? 'dice',
items: (map['items'] as List<dynamic>?)
?.map((i) => ReadingSignItem.fromMap(i as Map<String, dynamic>))
.toList() ??
[],
note: map['note'] as String?,
question: map['question'] as String?,
);
}
/// A day-long (or question-long) Syncretic Session accumulating multiple readings across systems
class SyncreticSession {
final String id;
final DateTime date;
final String? mainQuestion;
final List<SyncreticReading> readings;
final String? comparativeAiSynthesis;
const SyncreticSession({
required this.id,
required this.date,
this.mainQuestion,
this.readings = const [],
this.comparativeAiSynthesis,
});
String get dateKey =>
'${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
String get formattedDate {
final day = date.day.toString().padLeft(2, '0');
final month = date.month.toString().padLeft(2, '0');
final year = date.year.toString();
return '$day.$month.$year';
}
SyncreticSession copyWith({
String? id,
DateTime? date,
String? mainQuestion,
List<SyncreticReading>? readings,
String? comparativeAiSynthesis,
}) {
return SyncreticSession(
id: id ?? this.id,
date: date ?? this.date,
mainQuestion: mainQuestion ?? this.mainQuestion,
readings: readings ?? this.readings,
comparativeAiSynthesis: comparativeAiSynthesis ?? this.comparativeAiSynthesis,
);
}
Map<String, dynamic> toMap() => {
'id': id,
'date': date.toIso8601String(),
if (mainQuestion != null) 'mainQuestion': mainQuestion,
'readings': readings.map((r) => r.toMap()).toList(),
if (comparativeAiSynthesis != null) 'comparativeAiSynthesis': comparativeAiSynthesis,
};
factory SyncreticSession.fromMap(Map<String, dynamic> map) => SyncreticSession(
id: map['id'] as String? ?? '',
date: DateTime.tryParse(map['date'] as String? ?? '') ?? DateTime.now(),
mainQuestion: map['mainQuestion'] as String?,
readings: (map['readings'] as List<dynamic>?)
?.map((r) => SyncreticReading.fromMap(r as Map<String, dynamic>))
.toList() ??
[],
comparativeAiSynthesis: map['comparativeAiSynthesis'] as String?,
);
String toJson() => jsonEncode(toMap());
factory SyncreticSession.fromJson(String str) => SyncreticSession.fromMap(jsonDecode(str));
}