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

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

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

<script>

  import RecipeEditIngredientItem from "./RecipeEditIngredientItem";

  import { mapState } from "vuex";

  export default {
    props: {
      ingredients: {
        required: true,
        type: Array
      }
    },

    data() {
      return {
        isBulkEditing: false,
        bulkEditText: null
      };
    },

    computed: {
      ...mapState({
        isMobile: state => state.mediaQueries.mobile
      }),
      bulkIngredientPreview() {
        if (this.bulkEditText === null) {
          return [];
        }

        const regex = /^(?:([\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 = this.bulkEditText.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;
      },

      visibleIngredients() {
        return this.ingredients.filter(i => i._destroy !== true);
      }
    },

    methods: {
      createIngredient() {
        return {
          id: null,
          quantity: null,
          units: null,
          name: null,
          preparation: null,
          ingredient_id: null,
          sort_order: Math.max([0].concat(this.ingredients.map(i => i.sort_order))) + 5
        };
      },

      addIngredient() {
        this.ingredients.push(this.createIngredient());
      },

      deleteIngredient(ingredient) {
        if (ingredient.id) {
          ingredient._destroy = true;
        } else {
          const idx = this.ingredients.findIndex(i => i === ingredient);
          this.ingredients.splice(idx, 1);
        }
      },

      bulkEditIngredients() {
        this.isBulkEditing = true;

        let text = [];

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

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

      cancelBulkEditing() {
        this.isBulkEditing = false;
      },

      saveBulkEditing() {
        const parsed = this.bulkIngredientPreview.filter(i => i !== null);
        const existing = [...this.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 = this.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});
        }

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

        this.isBulkEditing = false;
      }
    },

    components: {
      RecipeEditIngredientItem
    }
  }

</script>

<style lang="scss" scoped>



</style>