129 lines
3.3 KiB
Dart
129 lines
3.3 KiB
Dart
class AiRecommendationService {
|
|
Future<String> recommendForOccasion(String prompt) async {
|
|
final input = prompt.trim();
|
|
if (input.isEmpty) {
|
|
return 'Diz-me a ocasião ou destino e eu ajudo-te a preparar uma lista. Por exemplo: "uma viagem para Itália de 5 dias".';
|
|
}
|
|
|
|
await Future<void>.delayed(const Duration(milliseconds: 600));
|
|
|
|
final lower = input.toLowerCase();
|
|
final items = <String>{};
|
|
final tips = <String>[];
|
|
|
|
items.addAll([
|
|
'Documento de identificação ou passaporte',
|
|
'Carteira/cartões e algum dinheiro',
|
|
'Telemóvel e carregador',
|
|
'Power bank',
|
|
'Produtos de higiene pessoal',
|
|
'Roupa interior e meias suficientes',
|
|
'Medicamentos pessoais',
|
|
]);
|
|
|
|
if (_containsAny(lower, [
|
|
'viagem',
|
|
'viajar',
|
|
'italia',
|
|
'itália',
|
|
'paris',
|
|
'espanha',
|
|
'frança',
|
|
'fim de semana',
|
|
])) {
|
|
items.addAll([
|
|
'Adaptador de tomada se necessário',
|
|
'Mochila pequena para passeios',
|
|
'Garrafa de água reutilizável',
|
|
'Cópia digital dos documentos',
|
|
'Seguro/cartão europeu de saúde se aplicável',
|
|
]);
|
|
tips.add('Confirma o clima e as regras de bagagem antes de sair.');
|
|
}
|
|
|
|
if (_containsAny(lower, [
|
|
'italia',
|
|
'itália',
|
|
'roma',
|
|
'milão',
|
|
'veneza',
|
|
'florença',
|
|
])) {
|
|
items.addAll([
|
|
'Calçado muito confortável para caminhar',
|
|
'Óculos de sol',
|
|
'Roupa leve e versátil',
|
|
'Casaco leve para a noite',
|
|
'Roupa mais composta para igrejas ou locais religiosos',
|
|
]);
|
|
tips.add(
|
|
'Em Itália vais provavelmente caminhar bastante; prioriza conforto no calçado.',
|
|
);
|
|
tips.add(
|
|
'Para visitar igrejas, é útil levar roupa que cubra ombros/joelhos.',
|
|
);
|
|
}
|
|
|
|
if (_containsAny(lower, ['praia', 'piscina', 'verão', 'calor', 'quente'])) {
|
|
items.addAll([
|
|
'Protetor solar',
|
|
'Fato de banho',
|
|
'Toalha de praia',
|
|
'Chinelos',
|
|
'Chapéu ou boné',
|
|
]);
|
|
}
|
|
|
|
if (_containsAny(lower, ['frio', 'inverno', 'neve', 'montanha'])) {
|
|
items.addAll([
|
|
'Casaco quente',
|
|
'Cachecol',
|
|
'Luvas',
|
|
'Camisolas térmicas',
|
|
'Calçado impermeável',
|
|
]);
|
|
}
|
|
|
|
if (_containsAny(lower, [
|
|
'trabalho',
|
|
'reunião',
|
|
'conferência',
|
|
'evento profissional',
|
|
])) {
|
|
items.addAll([
|
|
'Portátil e carregador',
|
|
'Roupa formal ou smart casual',
|
|
'Bloco de notas',
|
|
'Caneta',
|
|
'Cartões/documentos profissionais',
|
|
]);
|
|
}
|
|
|
|
if (_containsAny(lower, [
|
|
'casamento',
|
|
'cerimónia',
|
|
'formal',
|
|
'jantar elegante',
|
|
])) {
|
|
items.addAll([
|
|
'Roupa formal',
|
|
'Sapatos formais',
|
|
'Acessórios',
|
|
'Perfume',
|
|
'Kit pequeno de emergência para roupa',
|
|
]);
|
|
}
|
|
|
|
final itemLines = items.take(18).map((item) => '- $item').join('\n');
|
|
final tipLines = tips.isEmpty
|
|
? ''
|
|
: '\n\nDicas:\n${tips.map((tip) => '- $tip').join('\n')}';
|
|
|
|
return 'Para $input, eu levaria:\n\n$itemLines$tipLines\n\nSe me disseres duração, clima e tipo de viagem, consigo ajustar melhor a lista.';
|
|
}
|
|
|
|
bool _containsAny(String text, List<String> terms) {
|
|
return terms.any(text.contains);
|
|
}
|
|
}
|