package mealplaner.gui.dialogs.recepies;

import static mealplaner.commons.BundleStore.BUNDLES;
import static mealplaner.commons.NonnegativeInteger.FOUR;
import static mealplaner.commons.NonnegativeInteger.ONE;
import static mealplaner.commons.gui.GridPanel.gridPanel;
import static mealplaner.commons.gui.buttonpanel.ButtonPanelBuilder.builder;
import static mealplaner.commons.gui.dialogs.DialogWindow.window;
import static mealplaner.model.recipes.Recipe.createRecipe;

import java.awt.event.ActionListener;
import java.util.List;
import java.util.Optional;

import javax.swing.JDialog;
import javax.swing.JFrame;

import mealplaner.commons.NonnegativeInteger;
import mealplaner.commons.gui.GridPanel;
import mealplaner.commons.gui.buttonpanel.ButtonPanel;
import mealplaner.commons.gui.dialogs.DialogWindow;
import mealplaner.commons.gui.inputfields.InputField;
import mealplaner.commons.gui.inputfields.NonnegativeIntegerInputField;
import mealplaner.commons.gui.tables.Table;
import mealplaner.gui.dialogs.DialogEditing;
import mealplaner.gui.dialogs.ingredients.IngredientsInput;
import mealplaner.model.DataStore;
import mealplaner.model.recipes.Ingredient;
import mealplaner.model.recipes.Recipe;

public class RecipeInput implements DialogEditing<Optional<Recipe>> {
  private final DialogWindow dialogWindow;
  private RecipeTable recipeTable;
  private InputField<NonnegativeInteger> nonnegativeIntegerInputField;
  private Optional<Recipe> enteredRecipe;
  private Table table;

  public RecipeInput(JFrame parentFrame, String label) {
    dialogWindow = window(parentFrame, label);
  }

  public RecipeInput(JDialog parentDialog, String label) {
    dialogWindow = window(parentDialog, label);
  }

  @Override
  public Optional<Recipe> showDialog(Optional<Recipe> recipe, DataStore store) {
    enteredRecipe = recipe;
    display(recipe, store);
    dialogWindow.dispose();
    return enteredRecipe;
  }

  private void display(Optional<Recipe> recipe, DataStore store) {
    nonnegativeIntegerInputField = setupInputField(recipe);
    GridPanel inputFieldPanel = gridPanel(1, 2);
    nonnegativeIntegerInputField.addToPanel(inputFieldPanel);

    recipeTable = new RecipeTable(recipe.orElse(createRecipe()), store.getIngredients());
    table = recipeTable.setupTable();

    ButtonPanel buttonPanel = displayButtons(store);

    dialogWindow.addNorth(inputFieldPanel);
    dialogWindow.addCentral(table);
    dialogWindow.addSouth(buttonPanel);
    dialogWindow.arrangeWithSize(400, 300);
    dialogWindow.setVisible();
  }

  private NonnegativeIntegerInputField setupInputField(Optional<Recipe> recipe) {
    return new NonnegativeIntegerInputField(
        BUNDLES.message("recipeNumberOfPortionsField"),
        "RecipePortions",
        recipe.isPresent()
            ? recipe.get().getNumberOfPortions()
            : FOUR);
  }

  private ButtonPanel displayButtons(DataStore store) {
    return builder("RecipeInput")
        .addButton(BUNDLES.message("ingredientInput"),
            BUNDLES.message("ingredientInputMnemonic"),
            action -> saveNewIngredients(store))
        .addCancelDialogButton(dialogWindow)
        .addOkButton(getSaveListener())
        .build();
  }

  private void saveNewIngredients(DataStore store) {
    List<Ingredient> newIngredients = new IngredientsInput(dialogWindow).showDialog(store);
    Table oldTable = table;
    enteredRecipe = recipeTable.getRecipe(ONE);
    newIngredients.addAll(store.getIngredients());
    recipeTable = new RecipeTable(enteredRecipe.orElse(createRecipe()), newIngredients);
    table = recipeTable.setupTable();
    dialogWindow.swapCentral(oldTable, table);
  }

  private ActionListener getSaveListener() {
    return action -> {
      enteredRecipe = recipeTable.getRecipe(nonnegativeIntegerInputField.getUserInput());
      dialogWindow.dispose();
    };
  }
}

@@ -500,24 +500,52 @@
 onListener;%0A
+import java.util.ArrayList;%0A
 import java.
@@ -3458,19 +3458,76 @@
 E);%0A    
-new
+List%3CIngredient%3E allIngredients = new ArrayList%3C%3E();%0A    all
 Ingredie
@@ -3558,24 +3558,67 @@
 edients());%0A
+    allIngredients.addAll(newIngredients);%0A
     recipeTa
@@ -3677,19 +3677,19 @@
 ipe()), 
-new
+all
 Ingredie

Make new ingredients last in AutoCompleteBox