import 'package:mymuseum_visitapp/Helpers/translationHelper.dart'; import 'package:mymuseum_visitapp/Models/visitContext.dart'; /// Questions proposées au visiteur quand il ouvre l'assistant. /// /// Dérivées du contenu réel de la configuration : les sections sont déjà en /// mémoire (`VisitAppContext.currentSections`, alimenté au chargement de la /// configuration) et leurs titres déjà traduits par le CMS. Un lieu sans agenda /// ne propose donc pas de question sur l'agenda. /// /// Miroir de `visitapp-web/src/lib/assistantSuggestions.ts` — garder les deux /// listes de phrases alignées. class AssistantSuggestions { static const int _max = 3; static const Map> _phrases = { 'aboutSection': { 'FR': 'Parlez-moi de « {name} »', 'NL': 'Vertel me over "{name}"', 'EN': 'Tell me about "{name}"', 'DE': 'Erzählen Sie mir von „{name}"', 'ES': 'Háblame de «{name}»', 'IT': 'Parlami di "{name}"', }, 'whatsOn': { 'FR': "Qu'est-ce qu'il y a cette semaine ?", 'NL': 'Wat is er deze week te doen?', 'EN': "What's on this week?", 'DE': 'Was gibt es diese Woche?', 'ES': '¿Qué hay esta semana?', 'IT': 'Cosa c’è questa settimana?', }, 'withKids': { 'FR': 'Que faire avec des enfants ?', 'NL': 'Wat kunnen we doen met kinderen?', 'EN': 'What can we do with children?', 'DE': 'Was können wir mit Kindern machen?', 'ES': '¿Qué hacer con niños?', 'IT': 'Cosa fare con i bambini?', }, 'highlights': { 'FR': "Qu'est-ce qu'il ne faut pas manquer ?", 'NL': 'Wat mag ik niet missen?', 'EN': "What shouldn't I miss?", 'DE': 'Was sollte ich nicht verpassen?', 'ES': '¿Qué no me puedo perder?', 'IT': 'Cosa non devo perdere?', }, 'inOneHour': { 'FR': "Que voir si je n'ai qu'une heure ?", 'NL': 'Wat zie ik als ik maar één uur heb?', 'EN': 'What should I see in one hour?', 'DE': 'Was sollte ich in einer Stunde sehen?', 'ES': '¿Qué ver si solo tengo una hora?', 'IT': 'Cosa vedere se ho solo un’ora?', }, 'openingHours': { 'FR': 'Quels sont les horaires ?', 'NL': 'Wat zijn de openingstijden?', 'EN': 'What are the opening hours?', 'DE': 'Wie sind die Öffnungszeiten?', 'ES': '¿Cuál es el horario?', 'IT': 'Quali sono gli orari?', }, }; static String _phrase(String key, String lang, [String? name]) { final table = _phrases[key]!; final template = table[lang] ?? table['FR']!; return name == null ? template : template.replaceAll('{name}', name); } static String _titleOf(Map section, String lang) { final titles = section['title']; if (titles is! List || titles.isEmpty) return ''; final match = titles.firstWhere( (t) => t is Map && t['language'] == lang && (t['value'] as String?)?.isNotEmpty == true, orElse: () => titles.first, ); if (match is! Map) return ''; return TranslationHelper.stripHtml((match['value'] as String?) ?? ''); } static List build(VisitAppContext context, {String? currentSectionId}) { final lang = (context.language ?? 'FR').toUpperCase(); final sections = (context.currentSections ?? []) .whereType>() .where((s) => s['isActive'] != false && s['isSubSection'] != true) .toList(); bool has(String type) => sections.any((s) => s['type'] == type); final suggestions = []; // La section ouverte passe en premier : c'est ce que le visiteur a sous les yeux. if (currentSectionId != null) { final current = sections.firstWhere( (s) => s['id'] == currentSectionId, orElse: () => {}, ); if (current.isNotEmpty) { final name = _titleOf(current, lang); if (name.isNotEmpty) suggestions.add(_phrase('aboutSection', lang, name)); } } if (has('Agenda')) suggestions.add(_phrase('whatsOn', lang)); if (has('Parcours') || has('Game')) suggestions.add(_phrase('withKids', lang)); // Génériques — trois, pour qu'un lieu minimal ait quand même le compte complet. suggestions.add(_phrase('highlights', lang)); suggestions.add(_phrase('inOneHour', lang)); suggestions.add(_phrase('openingHours', lang)); return suggestions.toSet().take(_max).toList(); } }