<!--
  Component for editing task lists.

  Part of the basebox sample Todo app.
  https://basebox.io
-->
<template>
  <main>

    <h1>
      Lists
    </h1>

    <div class="toolbar">
      <button type="button" @click="addList()" class="btn btn-primary btn-large">New List</button>
      <div class="ms-auto">
        <small>{{ gStore.lists.length }} lists found.</small>
      </div>
    </div>

    <div id="list-container">
      <transition-group name="list" tag="div">
        <div class="list-item" v-for="list in gStore.lists" :key="list.id" :id="`list-${list.id}`">
          <div class="item-v-container">
            <input class="item-title" type="text" @blur="saveList(list)" v-model="list.title">
          </div>
          <div class="item-meta">
            <div class="dropdown">
              <button class="btn btn-sm btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                <i class="bi bi-trash"></i>
              </button>
              <ul class="dropdown-menu">
                <li><a class="dropdown-item" href="#"
                       @click="deleteList(list)">Delete this list</a></li>
              </ul>
            </div>
            <span class="item-counter">
              {{ listItemCount(list) }}
              <i class="bi bi-card-checklist"></i>
            </span>
          </div>
        </div>

        <div class="alert alert-info" v-if="gStore.lists.length === 0">
          <p>There are no lists, yet.</p>
          <button type="button" @click="addList()" class="btn btn-primary btn-large">Create your first list</button>
        </div>
      </transition-group>
    </div>

  </main>

</template>

<script>
import {gqlQuery} from "../util/net";
import {showError, store} from "../store";
import {showModal} from "../util/misc";

const NEW_LIST_ID = "new-list-id";

export default {
  name: "Lists",

  methods: {

    /**
     * Save a list to the database.
     * @param list - the list object to save.
     */
    saveList(list)
    {
      /* Prepare request; it is different if the list is new */
      let gql = "";
      if (list.id === NEW_LIST_ID) {
        /* create new list */
        gql = `mutation {
          createList(
            title: "${list.title}"
            user: {
              username: "${store.session.username}"
            }
          ) {
            id
          }
        }`;
      } else {
        /* save existing list */
        gql = `mutation {
          updateList(
            id: "${list.id}",
            title: "${list.title}"
          ) {
            id
          }
        }`;
      }
      /* send query */
      gqlQuery(
        gql
      ).then(data => {
        /* Save the list's id in case it was just created */
        if (!list.id) {
          list.id = data.createList.id;
        }
      }).catch(e => {
        const errMsg = `Failed to save list: ${e}`;
        console.error(errMsg);
        showError(errMsg);
      });
    },

    /**
     * Delete a list.
     * @param list - the list object to delete
     */
    deleteList(list) {
      if (list.id !== NEW_LIST_ID) {
        /* Make sure the list is not in use */
        if (store.tasks.findIndex(task => task.list.id === list.id) !== -1) {
          showModal("Delete List", "The list cannot be deleted as it is in use.");
          return;
        }
        /* List must be also deleted from the server */
        gqlQuery(`mutation {
          deleteList(id: "${list.id}") {
            id
          }
        }`);
      }

      /* delete list from the store. */
      const idx = store.lists.findIndex(item => item.id === list.id);
      if (idx !== -1) {
        store.lists.splice(idx, 1);
      }

    },

    /**
     * Add a new list.
     */
    addList()
    {
      /* push it to the array of lists in the store; it will be saved
       * when the user leaves the title field.
       */
      store.lists.push({
        title: "Enter list title",
        id: NEW_LIST_ID
      });

      /* wait a moment, then scroll list to the bottom */
      setTimeout(function() {
        document.getElementById("list-container").scrollTo({
          top: 100000,
          behavior: "smooth"
        });
        /* select text in new item's title field */
        const titleInput = document.querySelector(`#list-${NEW_LIST_ID} .item-title`);
        titleInput.setSelectionRange(0, 1000);
        titleInput.focus();
      }, 100);

    },

    /**
     * Return number of todo items in a list.
     */
    listItemCount(list) {
      return store.tasks.filter((item) => item.list.id === list.id).length;
    },

  },

  computed: {
    /**
     * Add global store to the context, so we can refer to it in the template.
     */
    gStore() {
      return store;
    },

  }
}
</script>

<style lang="scss" scoped>

#list-container {
  margin-top: 20px;
}

.item-counter {
  font-size: .8em;
  border: 1px solid var(--bs-border-color);
  padding: 3px 5px;
  text-align: right;
  border-radius: 3px;
  margin-top: 5px;
  display: block;
}

</style>
