import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
const String urlGist = 'https://gist.githubusercontent.com/JACursino/f4c830dd0ee6c3e2a3d9fc4c4812c9dc/raw/7eb73f73d32259737a40b200d362b27f50b53a34/recipes.json';
Future<List<Map<String, dynamic>>> buscarReceitas() async {
final resposta = await get(Uri.parse(urlGist));
if (resposta.statusCode == 200) {
final List dadosJson = jsonDecode(resposta.body);
return dadosJson.cast<Map<String, dynamic>>();
} else {
throw Exception('Falha ao carregar os dados. Status: ${resposta.statusCode}'); //Erro! Lançar uma exceção
}
}
List<String> filtrarReceitas(
List<String> ingredientesDisponiveis,
List<Map<String, dynamic>> todasReceitas,
) {
final List<String> receitasEncontradas = [];
for (final Map<String, dynamic> receita in todasReceitas) {
final List<String> ingredientesReceita = List<String>.from(receita['ingredients']);
bool todosIngredientesEncontrados = ingredientesDisponiveis.any((ingredienteUsuario) { /* função any retorna ao menos um item verdadeiro */
bool encontreiEsteIngrediente = false;
for (String ingredienteReceita in ingredientesReceita) {
if (ingredienteReceita.toLowerCase().contains(ingredienteUsuario)) {
encontreiEsteIngrediente = true;
break;
}
}
return encontreiEsteIngrediente;
});
if (todosIngredientesEncontrados) {
receitasEncontradas.add(receita['name'] as String);
}
}
return receitasEncontradas;
}
void exibirReceitas(List<String> nomesReceitas) {
print('--- Receitas que você pode fazer ---');
if (nomesReceitas.isEmpty) {
print('Hmm, não encontramos nenhuma receita com esses ingredientes.');
} else {
for (String nome in nomesReceitas) {
print('-> $nome');
}
}
print('----------------------------------');
}
void exibirDetalhesReceita(Map<String, dynamic> receita) {
print('\n====================================');
print('Receita: ${receita['name']}');
print('Tempo de Preparo: ${receita['preparation_time']}');
print('====================================');
print('\n--- Ingredientes ---');
for (var ingrediente in receita['ingredients']) {
print(' - $ingrediente');
}
print('\n--- Modo de Preparo ---');
final instrucoes = receita['instructions'].toString().split('. ');
for (var linha in instrucoes) {
if (linha.trim().isNotEmpty) {
print('${linha.trim()}.');
}
}
print('\n====================================');
print('Bom apetite!');
print('====================================\n');
}
void main() async {
print('--- Buscador de Receitas ---');
print('Vamos encontrar receitas com o que você tem em casa!\n');
print('Digite os ingredientes que você tem, separados por vírgula (ex: proteinas, temperos, legumes, frutas, vegetais...):');
String? entradaUsuario = stdin.readLineSync();
if (entradaUsuario == null || entradaUsuario.trim().isEmpty) {
print('Você não digitou nenhum ingrediente. Encerrando o programa.');
return;
}
List<String> ingredientesDisponiveis = entradaUsuario
.split(',')
.map((ingrediente) => ingrediente.trim().toLowerCase())
.toList();
print('\nBuscando receitas com os ingredientes: $ingredientesDisponiveis...\n');
try {
final List<Map<String, dynamic>> todasReceitas = await buscarReceitas();
final List<String> receitasPossiveis = filtrarReceitas(
ingredientesDisponiveis,
todasReceitas,
);
exibirReceitas(receitasPossiveis);
if (receitasPossiveis.isNotEmpty) {
print('\nGostaria de ver o passo a passo de alguma receita?');
print('Digite o nome dela exatamente como está na lista (ou "sair" para encerrar):');
String? escolhaUsuario = stdin.readLineSync();
if (escolhaUsuario != null && escolhaUsuario.toLowerCase() != 'sair') {
// foi utilizado o .firstWhere para encontrar o primeiro item que corresponde à condição.
try {
final Map<String, dynamic> receitaEscolhida = todasReceitas.firstWhere(
(receita) =>
receita['name'].toString().toLowerCase() == escolhaUsuario.toLowerCase(),
);
exibirDetalhesReceita(receitaEscolhida);
} on StateError {
print('\nReceita não encontrada. Verifique se digitou o nome corretamente.');
}
}
}
} catch (e) {
print('Ocorreu um erro ao buscar as receitas: $e');
}
}