<template>
  <div>
    <h3 class="title is-4">
      Ingredients
      <button type="button" class="button is-primary" @click="bulkEditIngredients">Bulk Edit</button>
    </h3>

    <app-modal wide :open="isBulkEditing" title="Edit Ingredients" @dismiss="cancelBulkEditing">
      <div class="columns">
        <div class="column is-half bulk-input">
          <textarea ref="bulkEditTextarea" class="textarea is-size-7-mobile" v-model="bulkEditText"></textarea>
        </div>
        <div class="column is-half">
          <table class="table is-bordered is-narrow is-size-7">
            <thead>
            <tr>
              <th>#</th>
              <th>Unit</th>
              <th>Name</th>
              <th>Prep</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="i in bulkIngredientPreview">
              <td>{{i.quantity}}</td>
              <td>{{i.units}}</td>
              <td>{{i.name}}</td>
              <td>{{i.preparation}}</td>
            </tr>
            </tbody>
          </table>
        </div>
      </div>
      <button class="button is-primary" type="button" @click="saveBulkEditing">Save</button>
      <button class="button is-secondary" type="button" @click="cancelBulkEditing">Cancel</button>
    </app-modal>

    <div>
      <recipe-edit-ingredient-item v-for="(i, idx) in visibleIngredients" :key="i.id" :ingredient="i" :show-labels="idx === 0 || isMobile" @deleteFood="deleteFood"></recipe-edit-ingredient-item>
    </div>

    <button type="button" class="button is-primary" @click="addIngredient">Add Ingredient</button>
  </div>
</template>

<script setup>

  import { computed, ref } from "vue";
  import { useMediaQueryStore } from "../stores/mediaQuery";
  import RecipeEditIngredientItem from "./RecipeEditIngredientItem";

  const mediaQueryStore = useMediaQueryStore();

  const props = defineProps({
    ingredients: {
      required: true,
      type: Array
    }
  });

  const isBulkEditing = ref(false);
  const bulkEditText = ref(null);
  const isMobile = computed(() => mediaQueryStore.mobile);
  const visibleIngredients = computed(() => props.ingredients.filter(i => i._destroy !== true));

  const bulkIngredientPreview = computed(() => {
    if (bulkEditText.value === null || bulkEditText.value === "") {
      return [];
    }

    const regex = /^\s*(?:([\d\/.]+(?:\s+[\d\/]+)?)\s+)?(?:([\w-]+)(?:\s+of)?\s+)?([^,|]+?|.+\|)(?:,\s*([^|]*?))?(?:\s*\[(\d+)\]\s*)?$/i;

    const magicFunc = function(str) {
      if (str === "-") {
        return "";
      } else {
        return str;
      }
    };

    const parsed = [];
    const lines = bulkEditText.value.replace("\r", "").split("\n");

    for (let line of lines) {
      if (line.length === 0) { continue; }

      const match = line.match(regex);

      if (match) {
        const matchedName = match[3].replace(/\|\s*$/, "");
        let item = {quantity: magicFunc(match[1]), units: magicFunc(match[2]), name: magicFunc(matchedName), preparation: magicFunc(match[4]), id: match[5] || null};
        parsed.push(item);
      } else {
        parsed.push(null);
      }
    }

    return parsed;
  });

  function createIngredient() {
    const sort_orders = props.ingredients.map(i => i.sort_order);
    sort_orders.push(0);
    const next_sort_order = Math.max(...sort_orders) + 5;

    return {
      id: null,
      quantity: null,
      units: null,
      name: null,
      preparation: null,
      ingredient_id: null,
      sort_order: next_sort_order
    };
  }

  function addIngredient() {
    props.ingredients.push(createIngredient());
  }

  function deleteFood(food) {
    if (food.id) {
      food._destroy = true;
    } else {
      const idx = props.ingredients.findIndex(i => i === food);
      props.ingredients.splice(idx, 1);
    }
  }

  function bulkEditIngredients() {
    isBulkEditing.value = true;

    let text = [];

    for (let item of visibleIngredients.value) {
      text.push(
          item.quantity + " " +
          (item.units || "-") + " " +
          (item.name.indexOf(",") >= 0 ? item.name + "|" : item.name) +
          (item.preparation ? (", " + item.preparation) : "") +
          (item.id ? (" [" + item.id + "]") : "")
      );
    }

    bulkEditText.value = text.join("\n");
  }

  function cancelBulkEditing() {
    isBulkEditing.value = false;
  }

  function saveBulkEditing() {
    const parsed = bulkIngredientPreview.value.filter(i => i !== null);
    const existing = [...props.ingredients];
    const newList = [];

    for (let parsedIngredient of parsed) {
      let newIngredient = null;

      if (parsedIngredient.id !== null) {
        let intId = parseInt(parsedIngredient.id);
        let exIdx = existing.findIndex(i => i.id === intId);
        if (exIdx >= 0) {
          let ex = existing[exIdx];
          if (ex.name === parsedIngredient.name) {
            newIngredient = ex;
            existing.splice(exIdx, 1);
          }
        }
      }

      if (newIngredient === null) {
        newIngredient = createIngredient();
      }

      newIngredient.quantity = parsedIngredient.quantity;
      newIngredient.units = parsedIngredient.units;
      newIngredient.name = parsedIngredient.name;
      newIngredient.preparation = parsedIngredient.preparation;
      newList.push(newIngredient);
    }

    for (let oldExisting of existing.filter(i => i.id !== null)) {
      newList.push({id: oldExisting.id, _destroy: true});
    }

    props.ingredients.splice(0);
    let sortIdx = 0;
    for (let n of newList) {
      n.sort_order = sortIdx++;
      props.ingredients.push(n);
    }

    isBulkEditing.value = false;
  }

</script>

<style lang="scss" scoped>

  .bulk-input {

    textarea {
      height: 100%;
      min-height: 15rem;
    }
  }

</style>