<template>
  <v-row v-if="formState.ready">
    <v-col>
      <v-form ref="form">
        <v-row justify="start">
          <gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
          <v-col cols="12" sm="4" lg="4" xl="3">
            <v-text-field
              v-model="searchPhrase"
              clearable
              :label="$ay.t('Search')"
              ref="searchPhrase"
              @change="getDataFromApi()"
              hint="text, *xt, te*"
              data-cy="phrase"
            ></v-text-field>
          </v-col>
          <v-col cols="12" sm="4" lg="4" xl="3">
            <v-select
              v-model="searchObjectType"
              :items="selectLists.objectTypes"
              item-text="name"
              item-value="id"
              :label="$ay.t('Object')"
            ></v-select>
          </v-col>
          <v-col cols="12" sm="4" lg="4" xl="3">
            <v-btn color="primary" @click="getDataFromApi()" value="SEARCH">
              <v-icon data-cy="btnsearch">$ayiSearch</v-icon>
            </v-btn>
          </v-col>

          <v-col cols="12">
            <p v-if="!items.length">{{ $ay.t("NoResults") }}</p>
            <v-card v-if="items.length" max-width="900">
              <v-list>
                <v-subheader v-if="maxResultsReturned">
                  <span>({{ $ay.t("TooManyResults") }})</span>
                </v-subheader>

                <template v-for="item in items">
                  <!-- KEY MUST BE UNIQUE INSIDE v-for OR LIST ITEM GOES SNAKEY -->
                  <v-subheader :key="'s' + item.index" v-if="item.subheader"
                    ><v-icon large class="mr-2">{{ item.icon }}</v-icon
                    ><span class="title">{{
                      item.subheader
                    }}</span></v-subheader
                  >

                  <v-list-item link :key="item.index">
                    <v-list-item-content
                      @click="openItem(item)"
                      :data-cy="'btnopenitem' + item.index"
                    >
                      <v-list-item-title v-text="item.name"></v-list-item-title>
                      <v-list-item-subtitle
                        v-html="item.info"
                      ></v-list-item-subtitle>
                    </v-list-item-content>
                    <v-list-item-action>
                      <v-btn icon @click="getExcerpt(item)">
                        <v-icon
                          color="grey lighten-1"
                          large
                          :data-cy="'btnexcerpt' + item.index"
                          >$ayiInfoCircle</v-icon
                        >
                      </v-btn>
                    </v-list-item-action>
                  </v-list-item>
                </template>
              </v-list>
            </v-card>
          </v-col>
        </v-row>
      </v-form>
    </v-col>
  </v-row>
</template>

<script>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*  Xeslint-disable    */
////////////////////////////////////////////////////////////////////////////////////////////////////////////

const FORM_KEY = "home-search";
const API_BASE_URL = "search/";
const FORM_CUSTOM_TEMPLATE_KEY = "home-search";
const MAX_RESULTS = 200;

export default {
  beforeRouteLeave(to, from, next) {
    let vm = this;
    //save last search in session cache
    window.$gz.form.setFormSettings(FORM_KEY, {
      temp: {
        ayaType: vm.searchObjectType,
        phrase: vm.searchPhrase,
        items: vm.items,
        maxResultsReturned: vm.maxResultsReturned
      }
    });

    next();
  },
  async created() {
    let vm = this;
    try {
      await initForm(vm);

      vm.formState.ready = true;
      window.$gz.eventBus.$on("menu-click", clickHandler);
      generateMenu(vm);

      if (vm.$route.params.ayatype) {
        vm.searchObjectType = vm.$route.params.ayatype;
      }

      //get form settings from session cache, if same type as in route then re-use teh last search stuff
      //however if different than need to clear it (or not rehydrate it)
      let savedSettings = window.$gz.form.getFormSettings(FORM_KEY);

      if (savedSettings && savedSettings.temp) {
        savedSettings = savedSettings.temp;
        if (
          vm.searchObjectType == null ||
          vm.searchObjectType == savedSettings.ayaType
        ) {
          //same type or no type so go ahead and rehydrate
          vm.searchPhrase = savedSettings.phrase;
          vm.searchObjectType = savedSettings.ayaType;
          vm.items = savedSettings.items;
        }
      }
    } catch (err) {
      vm.formState.ready = true;
      window.$gz.errorHandler.handleFormError(err, vm);
    }
  },
  beforeDestroy() {
    window.$gz.eventBus.$off("menu-click", clickHandler);
  },
  components: {},
  data() {
    return {
      formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
      selectLists: {
        objectTypes: []
      },
      searchPhrase: null,
      searchObjectType: 0,
      items: [],
      maxResultsReturned: false,
      formState: {
        ready: false,
        dirty: false,
        valid: true,
        readOnly: false,
        loading: false,
        errorBoxMessage: null,
        appError: null,
        serverError: {}
      },
      rights: window.$gz.role.defaultRightsObject()
    };
  },

  methods: {
    openItem(item) {
      window.$gz.eventBus.$emit("openobject", {
        type: item.type,
        id: item.id
      });
    },
    async getExcerpt(item) {
      let vm = this;
      //Search/Info/2/1?phrase=we
      if (item.info || item.id == 0) {
        return;
      }

      let max = 40;
      switch (vm.$vuetify.breakpoint.name) {
        case "xs":
          max = 30;
          break;
        case "sm":
          max = 67;
          break;
        case "md":
          max = 78;
          break;
        case "lg":
          max = 120;
          break;
        case "xl":
          max = 120;
          break;
        default:
          max = 40;
      }
      try {
        let res = await window.$gz.api.get(
          API_BASE_URL +
            "Info/" +
            item.type +
            "/" +
            item.id +
            "?phrase=" +
            vm.searchPhrase +
            "&max=" +
            max
        );

        if (res.error) {
          vm.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(vm);
        } else {
          let showInfo = res.data;
          let searchTerms = vm.searchPhrase.replace(/[*]/gi, "").split(" ");
          for (let i = 0; i < searchTerms.length; i++) {
            let regEx = new RegExp(searchTerms[i], "ig");
            let replaceMask =
              "<span class='v-list-item__mask'>" + searchTerms[i] + "</span>";
            showInfo = showInfo.replace(regEx, replaceMask);
          }

          item.info = showInfo;
        }
      } catch (error) {
        window.$gz.errorHandler.handleFormError(error, vm);
      }
    },
    async getDataFromApi() {
      let vm = this;
      if (!vm.searchPhrase || vm.formState.loading) {
        return;
      }
      vm.formState.loading = true;
      window.$gz.form.deleteAllErrorBoxErrors(vm);
      /**
 * {
  "phrase": "e*",
  "nameOnly": false,
  "typeOnly": 0,
  "maxResults": 100
}
 * 
 */
      try {
        let res = await window.$gz.api.upsert(API_BASE_URL, {
          phrase: vm.searchPhrase,
          nameOnly: false,
          typeOnly: !!vm.searchObjectType ? vm.searchObjectType : 0,
          maxResults: MAX_RESULTS
        });
        if (res.error) {
          vm.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(vm);
        } else {
          vm.maxResultsReturned = res.data.searchResults.length == MAX_RESULTS;
          let newResults = [];
          let nDex = 0;
          let lastType = -1;
          for (let i = 0; i < res.data.searchResults.length; i++) {
            let item = res.data.searchResults[i];
            if (item.type != lastType) {
              //change of type, set subheader props
              //de-lodash
              // let tsub = window.$gz. _.find(vm.selectLists.objectTypes, [
              //   "id",
              //   item.type
              // ]);

              let tsub = vm.selectLists.objectTypes.find(
                z => z.id == item.type
              );

              if (tsub != null) {
                item.subheader = tsub.name;
              } else {
                item.subheader = "TYPE " + item.type;
              }
              item.icon = window.$gz.util.iconForType(item.type);
              lastType = item.type;
            }
            item.info = null;
            item.index = ++nDex;
            newResults.push(item);
          }
          vm.items = newResults;
        }
      } catch (error) {
        window.$gz.errorHandler.handleFormError(error, vm);
      } finally {
        //Update the form status
        window.$gz.form.setFormState({
          vm: vm,
          loading: false
        });
      }
    }
  }
};

/////////////////////////////
//
//
function clickHandler(menuItem) {
  if (!menuItem) {
    return;
  }
  let m = window.$gz.menu.parseMenuItem(menuItem);
  if (m.owner == FORM_KEY && !m.disabled) {
    switch (m.key) {
      default:
        window.$gz.eventBus.$emit(
          "notify-warning",
          FORM_KEY + "::context click: [" + m.key + "]"
        );
    }
  }
}

//////////////////////
//
//
function generateMenu(vm) {
  let menuOptions = {
    isMain: true,
    icon: "$ayiSearch",
    title: "Search",
    helpUrl: "home-search",
    hideSearch: true,
    formData: {
      ayaType: window.$gz.type.UserOptions
    },
    menuItems: []
  };

  window.$gz.eventBus.$emit("menu-change", menuOptions);
}

/////////////////////////////////
//
//
async function initForm(vm) {
  await fetchTranslatedText(vm);
  await populateSelectionLists(vm);
}

//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
  await window.$gz.translation.cacheTranslations([
    "TooManyResults",
    "NoResults",
    "Object",
    "ServiceBank"
  ]);
}

//////////////////////
//
//
async function populateSelectionLists(vm) {
  let res = await window.$gz.api.get("enum-list/list/coreview");
  if (res.error) {
    vm.formState.serverError = res.error;
    window.$gz.form.setErrorBoxErrors(vm);
  } else {
    vm.selectLists.objectTypes = res.data;
    //ServiceBank will appear in search results but is not a Core biz object so won't be added to list by server
    //and needs to be added manually here
    vm.selectLists.objectTypes.push({ name: vm.$ay.t("ServiceBank"), id: 55 });
    //servicebank?
    window.$gz.form.addNoSelectionItem(vm.selectLists.objectTypes);
  }
}
</script>
