import 'package:diameter/main.dart';
import 'package:diameter/models/meal.dart';
import 'package:diameter/models/recipe.dart';
import 'package:diameter/utils/utils.dart';
import 'package:objectbox/objectbox.dart';
import 'package:diameter/objectbox.g.dart' show Ingredient_, Recipe_;

@Entity(uid: 6950311793136068892)
@Sync()
class Ingredient {
  static final Box<Ingredient> box = objectBox.store.box<Ingredient>();

  // properties
  int id;
  bool deleted;
  double amount;

  // relations
  final recipe = ToOne<Recipe>();
  final ingredient = ToOne<Meal>();

  // constructor
  Ingredient({
    this.id = 0,
    this.deleted = false,
    required this.amount,
  });

  // methods
  static Ingredient? get(int id) => box.get(id);
  static void put(Ingredient ingredient) => box.put(ingredient);
  static void putMany(List<Ingredient> ingredients) => box.putMany(ingredients);

  static List<Ingredient> getAllForRecipe(int id) {
    QueryBuilder<Ingredient> builder =
        box.query(Ingredient_.deleted.equals(false));
    builder.link(Ingredient_.recipe, Recipe_.id.equals(id));
    return builder.build().find();
  }

  static double? getCarbsRatioForRecipe(int id) {
    double carbsSum = 0.0;
    double totalWeight = 0.0;

    List<Ingredient> ingredients = getAllForRecipe(id);

    for (Ingredient ingredient in ingredients) {
      if ((ingredient.ingredient.target?.carbsRatio ?? 0) <= 0) {
        return null;
      }
      totalWeight += ingredient.amount;
      carbsSum +=
          Utils.calculateCarbs(ingredient.ingredient.target!.carbsRatio!, ingredient.amount);
    }
    return totalWeight > 0
        ? Utils.calculateCarbsRatio(carbsSum, totalWeight)
        : null;
  }

  static double? getTotalWeightForRecipe(int id) {
    double totalWeight = 0.0;

    List<Ingredient> ingredients = getAllForRecipe(id);

    for (Ingredient ingredient in ingredients) {
      if (ingredient.ingredient.target?.carbsRatio == null) {
        return null;
      }
      totalWeight += ingredient.amount;
    }

    return totalWeight;
  }

  @override
  String toString() {
    return ingredient.target?.value ?? '';
  }
}
