<template>
  <div>
    <h1 class="title">Recipes</h1>

    <router-link v-if="appConfig.isLoggedIn" :to="{name: 'new_recipe'}" class="button is-primary">Create Recipe</router-link>

    <app-pager :current-page="currentPage" :total-pages="totalPages" paged-item-name="recipe" @changePage="changePage"></app-pager>

    <app-loading v-if="localLoading"></app-loading>




    <table class="table is-fullwidth" :class="{ small: isTouch }">
      <thead>
      <tr>
        <th v-for="h in tableHeader" :key="h.name">
          <a v-if="h.sort" href="#" @click.prevent="setSort(h.name)">
            {{h.label}}
            <app-icon v-if="search.column === h.name" size="sm" :icon="search.direction === 'asc' ? 'caret-bottom' : 'caret-top'"></app-icon>
          </a>
          <span v-else>{{h.label}}</span>
        </th>
        <th></th>
      </tr>
      <tr>
        <td>
          <app-search-text placeholder="search names" :model-value="search.name" @update:modelValue="setSearchName($event)"></app-search-text>
        </td>
        <td>
          <app-search-text placeholder="search tags" :model-value="search.tags" @update:modelValue="setSearchTags($event)"></app-search-text>
        </td>
        <td colspan="5"></td>
      </tr>
      </thead>
      <transition-group name="fade" tag="tbody">
      <tr v-for="r in recipes" :key="r.id">
        <td><router-link :to="{name: 'recipe', params: { id: r.id } }">{{r.name}}</router-link></td>
        <td>
          <div class="tags">
            <span class="tag" v-for="tag in r.tags" :key="tag">{{tag}}</span>
          </div>
        </td>
        <td>
          <app-rating v-if="r.rating !== null" :model-value="r.rating" readonly></app-rating>
          <span v-else>--</span>
        </td>
        <td>{{ r.yields }}</td>
        <td class="recipe-time">{{ formatRecipeTime(r.total_time, r.active_time) }}</td>
        <td><app-date-time :date-time="r.created_at" :show-time="false"></app-date-time></td>
        <td>
          <app-dropdown hover v-if="appConfig.isLoggedIn" class="is-right">
            <template #button>
              <button class="button is-small">
                <app-icon icon="menu"></app-icon>
              </button>
            </template>

            <div class="dropdown-item">
              <router-link :to="{name: 'new_log', params: { recipeId: r.id } }" class="button is-primary is-fullwidth">
                <app-icon icon="star" size="md"></app-icon> <span>Add Log Entry</span>
              </router-link>
            </div>

            <div class="dropdown-item">
              <router-link :to="{name: 'edit_recipe', params: { id: r.id } }" class="button is-primary is-fullwidth">
                <app-icon icon="pencil" size="md"></app-icon> <span>Edit Recipe</span>
              </router-link>
            </div>

            <div class="dropdown-item">
              <button type="button" class="button is-danger is-fullwidth" @click="deleteRecipe(r)">
                <app-icon icon="x" size="md"></app-icon> <span>Delete Recipe</span>
              </button>
            </div>

          </app-dropdown>
        </td>
      </tr>
      </transition-group>
    </table>

    <div v-if="!localLoading && recipes.length === 0">
      No Recipes
    </div>

    <app-pager :current-page="currentPage" :total-pages="totalPages" paged-item-name="recipe" @changePage="changePage"></app-pager>
    <app-confirm :open="showConfirmRecipeDelete" title="Delete Recipe?" :message="confirmRecipeDeleteMessage" @cancel="recipeDeleteCancel" @confirm="recipeDeleteConfirm"></app-confirm>

  </div>
</template>

<script setup>

  import { computed, reactive, ref, watch } from "vue";
  import { useRouter } from 'vue-router'
  import api from "../lib/Api";
  import AppLoading from "./AppLoading";
  import { useAppConfigStore } from "../stores/appConfig";
  import { useMediaQueryStore } from "../stores/mediaQuery";
  import { useLoadResource } from "../lib/useLoadResource";

  const appConfig = useAppConfigStore();
  const mediaQueries = useMediaQueryStore();
  const { loadResource, localLoading } = useLoadResource();
  const router = useRouter();

  const props = defineProps({
    searchQuery: {
      type: Object,
      required: false,
      default: {}
    }
  });

  const tableHeader = [
    {name: 'name', label: 'Name', sort: true},
    {name: 'tags', label: 'Tags', sort: false},
    {name: 'rating', label: 'Rating', sort: true},
    {name: 'yields', label: 'Yields', sort: false},
    {name: 'total_time', label: 'Time', sort: true},
    {name: 'created_at', label: 'Created', sort: true}
  ];

  const recipeData = ref(null);
  const recipeForDeletion = ref(null);
  const isTouch = computed(() => mediaQueries.touch);

  const search = computed(() => ({
    name: props.searchQuery.name || null,
    tags: props.searchQuery.tags || null,
    column: props.searchQuery.column || "created_at",
    direction: props.searchQuery.direction || "desc",
    page: props.searchQuery.page || 1,
    per: props.searchQuery.per || 25
  }));

  const recipes = computed(() => {
    if (recipeData.value) {
      return recipeData.value.recipes;
    } else {
      return [];
    }
  });

  const totalPages = computed(() => {
    if (recipeData.value) {
      return recipeData.value.total_pages;
    }
    return 0;
  });

  const currentPage = computed(() => {
    if (recipeData.value) {
      return recipeData.value.current_page;
    }
    return 0;
  });

  const showConfirmRecipeDelete = computed(() => recipeForDeletion.value !== null);

  const confirmRecipeDeleteMessage = computed(() => {
    if (showConfirmRecipeDelete.value) {
      return `Are you sure you want to delete ${recipeForDeletion.value.name}?`;
    } else {
      return "??";
    }
  });

  watch(search, () => {
    getList().then(() => appConfig.initialLoad = true);
  }, {
    deep: true,
    immediate: true
  });

  function getList() {
    return loadResource(
        api.getRecipeList(search.value.page, search.value.per, search.value.column, search.value.direction, search.value.name, search.value.tags, data => recipeData.value = data)
    );
  }


  function buildQueryParams() {
    return {
      name: props.searchQuery.name,
      tags: props.searchQuery.tags,
      column: props.searchQuery.column,
      direction: props.searchQuery.direction,
      page: props.searchQuery.page,
      per: props.searchQuery.per
    }
  }

  function redirectToParams(params) {
    const rParams = {};

    if (params.name) {
      rParams.name = params.name;
    }

    if (params.tags) {
      rParams.tags = params.tags;
    }

    if (params.column) {
      rParams.column = params.column;
    }

    if (params.direction) {
      rParams.direction = params.direction;
    }

    if (params.page) {
      rParams.page = params.page;
    }

    if (params.per) {
      rParams.per = params.per;
    }

    router.push({name: 'recipeList', query: rParams});
  }

  function changePage(idx) {
    const p = buildQueryParams();
    p.page = idx;
    redirectToParams(p);
  }

  function setSort(col) {
    const p = buildQueryParams();

    if (p.column === col) {
      p.direction = p.direction === "desc" ? "asc" : "desc";
    } else {
      p.column = col;
      p.direction = "asc";
    }
    redirectToParams(p);
  }

  function setSearchName(name) {
    const p = buildQueryParams();
    if (name !== p.name) {
      p.name = name;
      p.page = null;
      redirectToParams(p);
    }
  }

  function setSearchTags(tags) {
    const p = buildQueryParams();
    if (tags !== p.tags) {
      p.tags = tags;
      p.page = null;
      redirectToParams(p);
    }
  }

  function deleteRecipe(recipe) {
    recipeForDeletion.value = recipe;
  }

  function recipeDeleteConfirm() {
    if (recipeForDeletion.value !== null) {
      loadResource(
          api.deleteRecipe(recipeForDeletion.value.id).then(() => {
            recipeForDeletion.value = null;
            return getList();
          })
      );
    }
  }

  function recipeDeleteCancel() {
    recipeForDeletion.value = null;
  }

  function formatRecipeTime(total, active) {
    let str = "";

    if (total && total > 0) {
      str += total;
    }

    if (active && active > 0) {
      if (str.length) {
        str += " (" + active + ")";
      } else {
        str += active;
      }
    }

    return str;
  }


</script>

<style lang="scss" scoped>
  .recipe-time {
    white-space: nowrap;
  }

  .table th {
    white-space: nowrap;
  }

  .table.small {
    td, th {
      &:nth-of-type(3), &:nth-of-type(4), &:nth-of-type(5), &:nth-of-type(6) {
        display: none;
      }
    }
  }

</style>