import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show rootBundle; import '../models/lenormand_pairs.dart'; /// Same shape as Lenormand pairs JSON: n, name, meaning, pairs[]. class TarotMajorsRepository { static final TarotMajorsRepository _instance = TarotMajorsRepository._internal(); factory TarotMajorsRepository() => _instance; TarotMajorsRepository._internal(); final Map _byN = {}; final Map _byId = {}; bool _loaded = false; bool get isLoaded => _loaded; List get cards => List.unmodifiable(_byN.values.toList()..sort((a, b) => a.n.compareTo(b.n))); LenormandCardEntry? byNumber(int n) => _byN[n]; LenormandCardEntry? byCanonId(String id) => _byId[id]; Future init() async { if (_loaded && _byN.isNotEmpty) return; Map? decoded; final cwd = Directory.current.path; for (final path in { 'assets/data/tarot_majors.json', '../assets/data/tarot_majors.json', '$cwd/assets/data/tarot_majors.json', '$cwd/../assets/data/tarot_majors.json', }) { try { final file = File(path); if (file.existsSync()) { decoded = json.decode(file.readAsStringSync()) as Map; break; } } catch (e) { debugPrint('tarot_majors.json skip $path: $e'); } } if (decoded == null) { try { final jsonStr = await rootBundle.loadString('assets/data/tarot_majors.json'); decoded = json.decode(jsonStr) as Map; } catch (e) { debugPrint('Could not load tarot_majors.json: $e'); } } if (decoded == null) { _loaded = true; return; } _byN.clear(); _byId.clear(); for (final raw in (decoded['cards'] as List? ?? const [])) { if (raw is! Map) continue; final card = LenormandCardEntry.fromMap(raw); _byN[card.n] = card; _byId[card.id] = card; } _loaded = true; } }