import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; import 'package:eatvio_app/features/recipes/models/ingredient.dart'; import 'package:eatvio_app/features/recipes/models/recipe_model.dart'; import 'package:eatvio_app/features/recipes/presentation/bloc/recipe_create_state.dart'; import 'package:eatvio_app/features/recipes/reporitories/recipe_repository.dart'; import 'package:eatvio_app/features/recipes/models/product.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:image_picker/image_picker.dart'; class RecipeCreateCubit extends Cubit { final RecipeRepository recipeRepository; RecipeCreateCubit({required this.recipeRepository}) : super(const RecipeCreateState.loading()); loadRecipeById(String recipeID) async { emit(const RecipeCreateStateLoading()); try { final RecipeModel recipe = await recipeRepository.getRecipe(recipeID); final List types = [ SelectionPopupModel(title: 'Первые блюда', value: 'first_meals'), SelectionPopupModel(title: 'Вторые блюда', value: 'second_meals'), SelectionPopupModel(title: 'Cалаты', value: 'salads'), SelectionPopupModel(title: 'Перекусы/закуски', value: 'snacks'), SelectionPopupModel(title: 'Сладости', value: 'sweets'), SelectionPopupModel(title: 'Напитки', value: 'drinks'), SelectionPopupModel(title: 'Прочее', value: 'other'), ]; final List cookingTimes = [ SelectionPopupModel(title: '10 минут', value: 10), SelectionPopupModel(title: '20 минут', value: 20), SelectionPopupModel(title: '30 минут', value: 30), SelectionPopupModel(title: '1 час', value: 60), SelectionPopupModel(title: '2 часа', value: 120), SelectionPopupModel(title: '10 дней', value: 14400), ]; final List statuses = [ SelectionPopupModel(title: 'Активна', value: 'active'), SelectionPopupModel(title: 'Неактивна', value: 'inactive'), ]; final selectedType = types.firstWhere( (type) => type.value == recipe.type, orElse: () => types[0], ); final selectedCookingTime = cookingTimes.firstWhere( (time) => time.value == recipe.cooking_time, orElse: () => cookingTimes[0], ); final selectedStatus = statuses.firstWhere( (status) => status.value == recipe.state, orElse: () => statuses[0], ); final stepControllers = recipe.steps?.map((step) { return TextEditingController(text: step?.description); }).toList(); final stepImages = recipe.steps?.map((step) { return step?.image != null ? XFile(step!.image!) : null; }).toList(); final ingredients = recipe.ingredients?.map((ingredient) { return Ingredient( name: ingredient!.name, portion: ingredient.portion, unit: ingredient.unit, ); }).toList(); emit(RecipeCreateState.loaded( picker: ImagePicker(), recipeImage: XFile(recipe.image!), titleController: TextEditingController(text: recipe.title), productNameController: TextEditingController(), ingredientController: TextEditingController(), stepDescriptionController: TextEditingController(text: recipe.description), youtubeLinkController: TextEditingController(text: recipe.video_url), stepControllers: stepControllers ?? [], stepImages: stepImages ?? [], autocompleteList: [], ingredients: ingredients ?? [], numberOfSteps: 1, ingredientAsItems: false, types: types, cookingTimes: cookingTimes, statuses: statuses, selectedType: selectedType, selectedCookingTime: selectedCookingTime, selectedStatus: selectedStatus,),); } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } loadRecipeCreate() { emit(const RecipeCreateStateLoading()); try { final List types = [ SelectionPopupModel(title: 'Первые блюда', value: 'first_meals'), SelectionPopupModel(title: 'Вторые блюда', value: 'second_meals'), SelectionPopupModel(title: 'Cалаты', value: 'salads'), SelectionPopupModel(title: 'Перекусы/закуски', value: 'snacks'), SelectionPopupModel(title: 'Сладости', value: 'sweets'), SelectionPopupModel(title: 'Напитки', value: 'drinks'), SelectionPopupModel(title: 'Прочее', value: 'other'), ]; final List cookingTimes = [ SelectionPopupModel(title: '10 минут', value: 10), SelectionPopupModel(title: '20 минут', value: 20), SelectionPopupModel(title: '30 минут', value: 30), SelectionPopupModel(title: '1 час', value: 60), SelectionPopupModel(title: '2 часа', value: 120), SelectionPopupModel(title: '10 дней', value: 14400), ]; final List statuses = [ SelectionPopupModel(title: 'Активна', value: 'active'), SelectionPopupModel(title: 'Неактивна', value: 'inactive'), ]; emit(RecipeCreateState.loaded( picker: ImagePicker(), titleController: TextEditingController(), productNameController: TextEditingController(), ingredientController: TextEditingController(), stepDescriptionController: TextEditingController(), youtubeLinkController: TextEditingController(), stepControllers: [TextEditingController()], stepImages: [null], autocompleteList: [], ingredients: [], numberOfSteps: 1, ingredientAsItems: false, types: types, cookingTimes: cookingTimes, statuses: statuses, selectedType: types[0], selectedCookingTime: cookingTimes[0], selectedStatus: statuses[0],),); } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } publishRecipe(RecipeModel recipe) async { await recipeRepository.publishRecipe(recipe); } editRecipe(RecipeModel recipe, String id) async { await recipeRepository.editRecipe(recipe, id); } uploadRecipeImage(XFile? pickedFile) { try { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; var updatedState = currentState.copyWith( recipeImage: pickedFile, ); emit(updatedState); } } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } uploadStepImage(XFile? pickedFile, int stepNumber) { try { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; var updatedStepImages = List.from(currentState.stepImages); if (stepNumber >= 0 && stepNumber < updatedStepImages.length) { updatedStepImages[stepNumber] = pickedFile; } var updatedState = currentState.copyWith( stepImages: updatedStepImages, ); emit(updatedState); } } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } switchUnits(bool value) { try { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; var updatedState = currentState.copyWith(ingredientAsItems: value); emit(updatedState); } } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } addIngredient(Ingredient ingredient) { try { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; bool ingredientExists = currentState.ingredients.any((existingIngredient) => existingIngredient.name == ingredient.name); if (ingredientExists) { emit(RecipeCreateState.error(errorMessage: 'Ингредиент уже существует.')); return; } List newIngredients = List.from(currentState.ingredients); newIngredients.add(ingredient); var updatedState = currentState.copyWith(ingredients: newIngredients); emit(updatedState); } } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } addStep() { try { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; List newStepImages = List.from(currentState.stepImages); newStepImages.add(null); List newStepControllers = List.from(currentState.stepControllers); newStepControllers.add(TextEditingController()); var updatedState = currentState.copyWith(stepImages: newStepImages, stepControllers: newStepControllers, numberOfSteps: currentState.numberOfSteps + 1); emit(updatedState); } } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } removeStep() { try { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; List newStepImages = List.from(currentState.stepImages); newStepImages.removeLast(); List newStepControllers = List.from(currentState.stepControllers); newStepControllers.removeLast(); var updatedState = currentState.copyWith(stepImages: newStepImages, stepControllers: newStepControllers, numberOfSteps: currentState.numberOfSteps - 1); emit(updatedState); } } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } } inputProduct(String input) async { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; final Map> productNutritionalValues = await recipeRepository.inputProduct(input); var updatedState = currentState.copyWith( productNameController: TextEditingController(text: input), autocompleteList: productNutritionalValues['product_nutritional_value'] ?? [], ); emit(updatedState); } } changeType(SelectionPopupModel type) { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; RecipeCreateStateLoaded updatedState = currentState.copyWith( selectedType: type, ); emit(updatedState); } } changeStatus(SelectionPopupModel status) { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; RecipeCreateStateLoaded updatedState = currentState.copyWith( selectedStatus: status, ); emit(updatedState); } } changeCookingTime(SelectionPopupModel cookingTime) { if (state is RecipeCreateStateLoaded) { var currentState = state as RecipeCreateStateLoaded; RecipeCreateStateLoaded updatedState = currentState.copyWith( selectedCookingTime: cookingTime, ); emit(updatedState); } } }