import '../../../core/api/api_client.dart'; import '../../../core/api/api_exception.dart'; import '../../../core/api/api_paths.dart'; import '../domain/parsed_recipe.dart'; import '../domain/recipe.dart'; import '../domain/inventory_preview.dart'; import '../domain/recipe_analysis.dart'; class RecipeRepository { final ApiClient _api; RecipeRepository(this._api); Future> fetchRecipes({String? token}) async { try { final dynamic data = await _api.getJson(RecipeApiPaths.list, token: token); if (data is! List) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return data .map((e) => Recipe.fromJson(e as Map)) .toList(); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte hämta recept.'); } } Future fetchRecipeDetail(int id, {String? token}) async { try { final data = await _api.getJson(RecipeApiPaths.detail(id), token: token); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return Recipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte hämta recept.'); } } Future createRecipe(Map body, {String? token}) async { try { final data = await _api.postJson(RecipeApiPaths.list, body: body, token: token); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return Recipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte spara recept.'); } } Future updateRecipe(int id, Map body, {String? token}) async { try { final data = await _api.patchJson( RecipeApiPaths.update(id), body: body, token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return Recipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte uppdatera recept.'); } } Future deleteRecipe(int id, {String? token}) async { try { await _api.deleteJson(RecipeApiPaths.remove(id), token: token); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte ta bort recept.'); } } Future setRecipeVisibility(int id, {required bool isPublic, String? token}) async { try { final data = await _api.patchJson( RecipeApiPaths.setVisibility(id), body: {'isPublic': isPublic}, token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return Recipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte uppdatera synlighet.'); } } Future shareRecipeWithUsername(int id, {required String username, String? token}) async { try { final data = await _api.postJson( RecipeApiPaths.share(id), body: {'username': username}, token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return Recipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte dela receptet.'); } } Future unshareRecipeWithUsername(int id, {required String username, String? token}) async { try { final data = await _api.deleteJson( RecipeApiPaths.unshare(id, username), token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return Recipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte ta bort delning.'); } } Future fetchInventoryPreview(int id, {String? token}) async { try { final data = await _api.getJson( RecipeApiPaths.inventoryPreview(id), token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return InventoryPreview.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte hämta inventariestatus.'); } } Future fetchRecipeAnalysis(int id, {String? token}) async { try { final data = await _api.getJson( RecipeApiPaths.analysis(id), token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return RecipeAnalysis.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte hämta receptanalys.'); } } Future rematchRecipeIngredients(int id, {String? token}) async { try { final data = await _api.postJson( RecipeApiPaths.rematch(id), body: const {}, token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return RecipeAnalysis.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte köra om matchning.'); } } Future parseMarkdown(String markdown, {String? token}) async { try { final data = await _api.postJson( RecipeApiPaths.parseMarkdown, body: {'markdown': markdown}, token: token, ); if (data is! Map) { throw const ApiException( type: ApiErrorType.unknown, message: 'Ogiltigt svar från servern.'); } return ParsedRecipe.fromJson(data); } on ApiException { rethrow; } catch (_) { throw const ApiException( type: ApiErrorType.network, message: 'Kunde inte tolka receptet.'); } } }