<template>
  <v-container>
    <!-- <div>
      READY: {{ formState.ready }}
      <br />
      LOADING: {{ formState.loading }}
      <br />
      DIRTY: {{ formState.dirty }}
      <br />
      VALID: {{ formState.valid }}
      <br />
      READONLY: {{ formState.readOnly }}
      <br />
    </div> -->
    <div>
      ListViewId: {{ listViewId }}
      <v-divider></v-divider>
      <br />
      DataListKey: {{ dataListKey }}
      <v-divider></v-divider>
      <br />
      FormKey: {{ formKey }}
      <v-divider></v-divider>
      <br />
      <!-- fieldDefinitions: {{ fieldDefinitions }}
      <v-divider></v-divider>
      <br /> -->
      effectiveListView: {{ effectiveListView }}
      <v-divider></v-divider>
      <br />
      obj: {{ obj }}
      <v-divider></v-divider>
    </div>

    <v-row v-if="this.formState.ready">
      <v-col>
        <v-form ref="form">
          <v-row>
            <v-col cols="12" mt-1 mb-2>
              <v-alert
                ref="errorbox"
                v-show="formState.errorBoxMessage"
                color="error"
                icon="fa-exclamation-circle "
                transition="scale-transition"
                class="multi-line"
                outlined
                >{{ formState.errorBoxMessage }}</v-alert
              >
            </v-col>
          </v-row>
          <v-row>
            <v-col cols="12" sm="6" lg="4" xl="3">
              <!-- <v-select
                v-model="listViewId"
                :items="pickLists.availableDataListViews"
                item-text="name"
                item-value="id"
                :label="lt('GridFilterName')"
                @change="filterChanged()"
              ></v-select> -->
            </v-col>
          </v-row>
        </v-form>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*  Xeslint-disable    */
////////////////////////////////////////////////////////////////////////////////////////////////////////////

const FORM_KEY = "ay-data-list-view";
const API_BASE_URL = "DataListView/";
export default {
  beforeRouteEnter(to, from, next) {
    var ltKeysRequired = ["DataListView", "GridFilterName"];

    window.$gz.locale.fetch(ltKeysRequired).then(next);
  },
  beforeRouteLeave(to, from, next) {
    //var vm = this;
    if (this.formState.dirty) {
      window.$gz.dialog.confirmLeaveUnsaved().then(dialogResult => {
        if (dialogResult == true) {
          next();
        } else {
          next(false);
        }
      });
    } else {
      next();
    }
  },
  beforeDestroy() {
    window.$gz.eventBus.$off("menu-click", clickHandler);
  },
  created() {
    var vm = this;

    //set route values in data object so init form can handle
    vm.dataListKey = this.$route.params.dataListKey;
    vm.listViewId = this.$route.params.listViewId;
    vm.formKey = this.$route.params.formKey;
    //console.log("Created TOP calling initform...");
    initForm(vm)
      .then(() => {
        //console.log("CREATED: back from initform");
        //  path: "/ay-data-list-view/:listViewId/:dataListKey",
        vm.formState.ready = true;

        window.$gz.eventBus.$on("menu-click", clickHandler);
        //NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
        //modify the menu as necessary
        generateMenu(vm, false); //default is never read only and passing in this vm
        //init disable save button so it can be enabled only on edit to show dirty form
        window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":save");
      })
      .catch(err => {
        //console.log("CREATED: ERROR back from initform with error");
        vm.formState.ready = true;
        window.$gz.errorHandler.handleFormError(err);
      });
  },
  data() {
    return {
      obj: [], //working copy driving UI
      listViewId: undefined,
      dataListKey: undefined,
      formKey: undefined,
      fieldDefinitions: [],
      effectiveListView: undefined,
      concurrencyToken: undefined,
      pickLists: {},
      formState: {
        ready: false,
        dirty: false,
        valid: true,
        readOnly: false,
        loading: true,
        errorBoxMessage: undefined,
        appError: undefined,
        serverError: {}
      },
      rights: window.$gz.role.getRights(window.$gz.type.DataListView)     
    };
  },

  methods: {
    lt: function(ltkey) {
      return window.$gz.locale.get(ltkey);
    },
    visibleChanged: function(item) {
      //Note: stock items can't be changed so no need to take that into account
      if (item.required && item.visible == false) {
        item.required = false;
      }
      this.formState.dirty = true;
      enableSaveButton();
    },
    submit() {
      var vm = this;
      var url = API_BASE_URL + this.formCustomTemplateKey;

      //clear any errors vm might be around from previous submit
      window.$gz.form.deleteAllErrorBoxErrors(this);

      //Create template data object here....
      //Note that server expects to see a string array of json template, not actual json
      var newObj = {
        formKey: this.formCustomTemplateKey,
        concurrencyToken: this.concurrencyToken,
        template: "[]"
      };
      //temporary array to hold template for later stringification
      var temp = [];
      //Rules:
      for (var i = 0; i < this.obj.length; i++) {
        var fldItem = this.obj[i];
        if (fldItem.custom == false) {
          //Process regular stock field
          //If it's *not* set to stockRequired (i.e. built in field with biz rules that can't be hidden or changed)
          // and it's also set to hidden or required then it's template-worthy
          if (
            !fldItem.stockRequired &&
            (fldItem.visible == false || fldItem.required == true)
          ) {
            temp.push({
              fld: fldItem.key,
              required: fldItem.required,
              hide: !fldItem.visible
            });
          }
        } else {
          //Process custom field
          //If it's not visible then don't add it at all
          if (fldItem.visible == true) {
            temp.push({
              fld: fldItem.key,
              required: fldItem.required,
              type: fldItem.type
            });
          }
        }
      }

      //now set the template as a json string
      newObj.template = JSON.stringify(temp);

      window.$gz.api
        .upsert(url, newObj)
        .then(res => {
          vm.formState.loading = false;
          if (res.error != undefined) {
            vm.formState.serverError = res.error;
            window.$gz.form.setErrorBoxErrors(vm);
          } else {
            //Handle "put" of an existing record (UPDATE) (there is no POST of a new record for this particular object)

            //Set store values for template and token
            window.$gz.formCustomTemplate.set(
              vm.formCustomTemplateKey,
              res.data.concurrencyToken,
              newObj.template
            );
            //set our local concurrency token value
            vm.concurrencyToken = res.data.concurrencyToken;

            //form is now clean
            window.$gz.form.setFormState({
              vm: vm,
              dirty: false
            });
          }
        })
        .catch(function handleSubmitError(error) {
          vm.formState.loading = false;
          window.$gz.errorHandler.handleFormError(error, vm);
        });
    }
  }
};

function enableSaveButton() {
  window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":save");
}

/////////////////////////////
//
//
function clickHandler(menuItem) {
  if (!menuItem) {
    return;
  }
  var m = window.$gz.menu.parseMenuItem(menuItem);
  if (m.owner == FORM_KEY && !m.disabled) {
    switch (m.key) {
      case "save":
        m.vm.submit();
        break;

      default:
        window.$gz.eventBus.$emit(
          "notify-warning",
          FORM_KEY + "::context click: [" + m.key + "]"
        );
    }
  }
}

//////////////////////
//
//
function generateMenu(vm) {
  var menuOptions = {
    isMain: false,
    icon: "filter",
    title: window.$gz.locale.get("DataListView"),
    helpUrl: "form-ay-data-list-view",
    formData: {
      formKey: FORM_KEY,
      ayaType: window.$gz.type.FormCustom,
      formCustomTemplateKey: undefined
    },
    menuItems: []
  };

  if (vm.rights.change) {
    menuOptions.menuItems.push({
      title: window.$gz.locale.get("Save"),
      icon: "save",
      surface: true,
      key: FORM_KEY + ":save",
      vm: vm
    });
  }

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

/////////////////////////////////
//
//
function initForm(vm) {
  //return test();
  return new Promise(function(resolve, reject) {
    (async function() {
      try {
        await populateFieldDefinitions(vm);
        await fetchLocalizedFieldNames(vm);
        await setEffectiveListView(vm);
        await initDataObject(vm);
      } catch (err) {
        reject(err);
      }
      resolve();
      //////////
    })();
  });
}

////////////////////
//
function populateFieldDefinitions(vm) {
  //console.log("called populatefieldDefinitions");
  //http://localhost:7575/api/v8/DataList/ListFields?DataListKey=TestWidgetDataList
  return window.$gz.api
    .get("DataList/ListFields?DataListKey=" + vm.dataListKey)
    .then(res => {
      if (res.error != undefined) {
        throw res.error;
      } else {
        vm.fieldDefinitions = res.data;
        //console.log("DONE populatefieldDefinitions");
      }
    });
}

//////////////////////////////////////////////////////////
//
// Ensures column names are present in locale table
//
function fetchLocalizedFieldNames(vm) {
  //console.log("called fetchLTFN");
  var columnKeys = [];
  for (var i = 1; i < vm.fieldDefinitions.length; i++) {
    var cm = vm.fieldDefinitions[i];
    columnKeys.push(cm.ltKey);
  }
  //Now fetch all the keys and await the response before returning
  return window.$gz.locale.fetch(columnKeys).then(() => {
    //console.log("DONE fetchLTFN");

    return;
  });
}

/////////////////////////////////
//
//
function setEffectiveListView(vm) {
  //console.log("called setEffectiveListView");

  /*
  effectiveListView
  - Second get the ListView that is currently in use so can setup the page view
			- If listviewid is zero then that's starting with the default list view so need to fetch it and then init the form
			- If listviewid is -1 then that's starting with an unsaved listview so get that from the saved form store
			- If listviewid is greater than 0 then it's a saved listview and there sb a cached version of it but ideally maybe fetch it from 

  */

  if (vm.listViewId == null) {
    throw "ay-data-list::setEffectiveListView - listViewId is not set";
  }

  var formSettings = window.$gz.form.getFormSettings(vm.formKey);

  if (vm.listViewId == -1) {
    if (formSettings.saved.dataTable.editedListView != null) {
      vm.effectiveListView = formSettings.saved.dataTable.editedListView;
      //console.log("DONE setEffectiveListView (resolved with saved, lvid=-1)");
      return Promise.resolve();
    }
  } else if (vm.listViewId == 0) {
    //get default list view
    //http://localhost:7575/api/v8/DataListView/default/TestWidgetDataList
    return window.$gz.api
      .get("DataListView/default/" + vm.dataListKey)
      .then(res => {
        if (res.error != undefined) {
          throw res.error;
        } else {
          vm.effectiveListView = JSON.parse(res.data);
          //console.log("DONE setEffectiveListView (fetched default, lvid=0)");
        }
      });
  } else {
    //listview has an id value
    //check if cached, if not then fetch, cache and set
    if (
      formSettings.temp.dataTable &&
      formSettings.temp.dataTable.cachedListView != null
    ) {
      vm.effectiveListView = formSettings.temp.dataTable.cachedListView;
      //console.log("DONE setEffectiveListView (resolved with cached,lvid>0)");
      return Promise.resolve();
    } else {
      //fetch it and cache it
      return window.$gz.api.get("DataListView/" + vm.listViewId).then(res => {
        if (res.error != undefined) {
          throw res.error;
        } else {
          vm.effectiveListView = JSON.parse(res.data.listView);
          //console.log("DONE setEffectiveListView (fetched listView, lvid>0)");
        }
      });
    }
  }
}

////////////////////
//
function initDataObject(vm) {
  //console.log("called initDataObject");

  if (vm.effectiveListView == null) {
    throw "ay-data-list::initDataObject - effectiveListView is not set";
  }
  if (vm.fieldDefinitions == null) {
    throw "ay-data-list::initDataObject - fieldDefinitions are not set";
  }

  var ret = [];

  //Pass 1, iterate the listview first
  for (var i = 0; i < vm.effectiveListView.length; i++) {
    var lvItem = vm.effectiveListView[i];

    var fld = window.$gz._.find(vm.fieldDefinitions, ["fieldKey", lvItem.fld]);
    var o = {
      key: fld.fieldKey,
      title: vm.lt(fld.ltKey),
      visible: true,
      isFilterable: fld.isFilterable,
      isSortable: fld.isSortable,
      enumType: fld.enumType,
      ayaObjectType: fld.ayaObjectType,
      uiFieldDataType: fld.uiFieldDataType,
      isCustomField: fld.isCustomField,
      sort: lvItem.sort || null,
      filter: lvItem.filter || null
    };
    ret.push(o);
  }

  //Pass 2, remaining fields not already dealt with
  //debugger;
  for (var i = 0; i < vm.fieldDefinitions.length; i++) {
    var fld = vm.fieldDefinitions[i];
    //skip over the default column
    if (fld.fieldKey == "df") {
      continue;
    }
    //is this field already in ret array?
    if (null == window.$gz._.find(ret, ["key", fld.fieldKey])) {
      //nope, so add it
      var o = {
        key: fld.fieldKey,
        title: vm.lt(fld.ltKey),
        visible: false,
        isFilterable: fld.isFilterable,
        isSortable: fld.isSortable,
        enumType: fld.enumType,
        ayaObjectType: fld.ayaObjectType,
        uiFieldDataType: fld.uiFieldDataType,
        isCustomField: fld.isCustomField,
        sort: null,
        filter: null
      };
      ret.push(o);
    }
  }
  vm.obj = ret;
  //console.log("DONE InitDataObject");

  if (window.$gz.errorHandler.devMode) {
    if (vm.obj.length != vm.fieldDefinitions.length - 1) {
      throw "ay-data-list-view::initDataObject - working array length not equal to total field definition length";
    }
  }
  return Promise.resolve();

  //eoc
}
</script>
