<template>
  <v-container>
    <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-col cols="12" sm="6" lg="4" xl="3">
              <v-text-field
                v-model="obj.name"
                :readonly="this.formState.readOnly"
                clearable
                @click:clear="onChange('name')"
                :counter="255"
                :label="lt('WidgetName')"
                :rules="[
                  form().max255(this, 'name'),
                  form().required(this, 'name')
                ]"
                :error-messages="form().serverErrors(this, 'name')"
                ref="name"
                @change="onChange('name')"
              ></v-text-field>
            </v-col>
            <v-col
              v-if="form().showMe(this, 'WidgetSerial')"
              cols="12"
              sm="6"
              lg="4"
              xl="3"
            >
              <v-text-field
                v-model="obj.serial"
                :readonly="this.formState.readOnly"
                clearable
                @click:clear="onChange('serial')"
                :counter="10"
                :label="lt('WidgetSerial')"
                :rules="[form().maxLength(this, 'serial', 10)]"
                :error-messages="form().serverErrors(this, 'serial')"
                ref="serial"
                @change="onChange('serial')"
              ></v-text-field>
            </v-col>
            <v-col
              v-if="form().showMe(this, 'WidgetCount')"
              cols="12"
              sm="6"
              lg="4"
              xl="3"
            >
              <v-text-field
                v-model="obj.count"
                :readonly="this.formState.readOnly"
                clearable
                @click:clear="onChange('count')"
                :counter="10"
                :label="lt('WidgetCount')"
                ref="count"
                :rules="[form().integerValid(this, 'count')]"
                :error-messages="form().serverErrors(this, 'count')"
                required
                @change="onChange('count')"
                type="number"
              ></v-text-field>
            </v-col>

            <v-col
              v-if="form().showMe(this, 'WidgetDollarAmount')"
              cols="12"
              sm="6"
              lg="4"
              xl="3"
            >
              <v-text-field
                v-model="obj.dollarAmount"
                :readonly="this.formState.readOnly"
                :prefix="ltFormat().currencySymbol"
                :label="lt('WidgetDollarAmount')"
                ref="dollarAmount"
                required
                :rules="[form().decimalValid(this, 'dollarAmount')]"
                :error-messages="form().serverErrors(this, 'dollarAmount')"
                @change="onChange('dollarAmount')"
                type="number"
              ></v-text-field>
            </v-col>

            <v-col cols="12" sm="6" lg="4" xl="3">
              <gz-date-time-picker
                :label="lt('WidgetStartDate')"
                v-model="obj.startDate"
                :readonly="this.formState.readOnly"
                ref="startDate"
                :error-messages="form().serverErrors(this, 'startDate')"
                @change="onChange('startDate')"
              ></gz-date-time-picker>
            </v-col>

            <v-col cols="12" sm="6" lg="4" xl="3">
              <gz-date-time-picker
                :label="lt('WidgetEndDate')"
                :rules="[form().datePrecedence(this, 'startDate', 'endDate')]"
                :error-messages="form().serverErrors(this, 'endDate')"
                v-model="obj.endDate"
                :readonly="this.formState.readOnly"
                ref="endDate"
                @change="onChange('endDate')"
              ></gz-date-time-picker>
            </v-col>
            <v-col
              v-if="form().showMe(this, 'Active')"
              cols="12"
              sm="6"
              lg="4"
              xl="3"
            >
              <v-checkbox
                v-model="obj.active"
                :readonly="this.formState.readOnly"
                :label="lt('Active')"
                ref="active"
                :error-messages="form().serverErrors(this, 'active')"
                required
                @change="onChange('active')"
              ></v-checkbox>
            </v-col>
            <v-col
              v-if="form().showMe(this, 'WidgetRoles')"
              cols="12"
              sm="6"
              lg="4"
              xl="3"
            >
              <v-select
                v-model="obj.roles"
                :items="pickLists.roles"
                item-text="name"
                item-value="id"
                :readonly="this.formState.readOnly"
                :label="lt('WidgetRoles')"
                ref="roles"
                :rules="[form().integerValid(this, 'roles')]"
                :error-messages="form().serverErrors(this, 'roles')"
                required
                @change="onChange('roles')"
              ></v-select>
            </v-col>

            <v-col v-if="form().showMe(this, 'WidgetNotes')" cols="12">
              <v-textarea
                v-model="obj.notes"
                :readonly="this.formState.readOnly"
                :label="lt('WidgetNotes')"
                :error-messages="form().serverErrors(this, 'notes')"
                ref="notes"
                @change="onChange('notes')"
                auto-grow
                clearable
              ></v-textarea>
            </v-col>

            <v-col v-if="form().showMe(this, 'Tags')" cols="12">
              <gz-tag-picker
                v-model="obj.tags"
                :readonly="this.formState.readOnly"
                ref="tags"
                :error-messages="form().serverErrors(this, 'tags')"
                @change="onChange('tags')"
              ></gz-tag-picker>
            </v-col>

            <v-col cols="12">
              <gz-custom-fields
                :formKey="formCustomTemplateKey"
                v-bind:value.sync="obj.customFields"
                :readOnly="this.formState.readOnly"
                :parentVM="this"
                ref="customFields"
                :error-messages="form().serverErrors(this, 'customFields')"
                @change="onChange('customFields')"
              ></gz-custom-fields>
              <!-- v-model="obj.customFields" -->
            </v-col>
          </v-row>
          <!-- <v-layout align-left justify-center row wrap mt-12>
          <v-col xs6 sm4> FORMtags: {{ obj.tags }} </v-col>
        </v-row> -->
          <!-- <v-layout align-left justify-center row wrap mt-12>
          <v-col xs6 sm4>
            READY: {{ formState.ready }}
            <br />
            LOADING: {{ formState.loading }}
            <br />
            DIRTY: {{ formState.dirty }}
            <br />
            VALID: {{ formState.valid }}
            <br />
            READONLY: {{ formState.readOnly }}
            <br />
          </v-col>
        </v-row>-->
        </v-form>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*  Xeslint-disable    */
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Illegal1 = O0
const FORM_KEY = "inventory-widget-edit";
const API_BASE_URL = "Widget/";
const FORM_CUSTOM_TEMPLATE_KEY = "widget";

export default {
  beforeRouteEnter(to, from, next) {
    var ltKeysRequired = [
      "Widget",
      "WidgetName",
      "WidgetSerial",
      "WidgetDollarAmount",
      "WidgetCount",
      "WidgetRoles",
      "WidgetStartDate",
      "WidgetEndDate",
      "WidgetNotes",
      "WidgetCustom1",
      "WidgetCustom2",
      "WidgetCustom3",
      "WidgetCustom4",
      "WidgetCustom5",
      "WidgetCustom6",
      "WidgetCustom7",
      "WidgetCustom8",
      "WidgetCustom9",
      "WidgetCustom10",
      "WidgetCustom11",
      "WidgetCustom12",
      "WidgetCustom13",
      "WidgetCustom14",
      "WidgetCustom15",
      "WidgetCustom16"
    ];

    window.$gz.locale.fetch(ltKeysRequired).then(
      //ensure cached any form customizations for this particular form
      window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY).then(next)
    );
  },
  beforeCreate() {
    var vm = this;
    initForm(this)
      .then(() => {
        vm.formState.ready = true;
      })
      .catch(err => {
        vm.formState.ready = true;
        window.$gz.errorHandler.handleFormError(err);
      });
  },
  created() {
    this.rights = window.$gz.role.getRights(window.$gz.type.Widget);

    window.$gz.eventBus.$on("menu-click", clickHandler);
    //id 0 means create a new record don't load one
    if (this.$route.params.id != 0) {
      this.getDataFromApi(this.$route.params.id);
    } else {
      //setup for new record
      var readOnly = !this.rights.change;
      //Update the form status
      window.$gz.form.setFormState({
        vm: this,
        dirty: false,
        valid: true,
        loading: false,
        readOnly: readOnly
      });

      //it's a new record so it can't be deleted so...
      this.rights.delete = false;

      //NOTE: If this object requires defaults from the server for a new object then here is where it woudld fetch them

      //modify the menu as necessary
      generateMenu(this);
    }
  },
  beforeRouteUpdate(to, from, next) {
    //fetch the data for the record as if it's a new record
    if (to.params.id != 0) {
      this.getDataFromApi(to.params.id);
    }
    next();
    // react to route changes...
    // don't forget to call next()
  },
  beforeRouteLeave(to, from, next) {
    //var vm = this;
    if (this.formState.dirty && !JUST_DELETED) {
      window.$gz.dialog.confirmLeaveUnsaved().then(dialogResult => {
        if (dialogResult == true) {
          next();
        } else {
          next(false);
        }
      });
    } else {
      next();
    }
  },
  beforeDestroy() {
    window.$gz.eventBus.$off("menu-click", clickHandler);
  },
  components: {},
  data() {
    return {
      formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
      pickLists: {
        roles: []
      },
      obj: {
        //IMPORTANT NOTE: Fields that are NON NULLABLE in the schema for the table but *are* hideable **MUST** have a default value set here or else there will be no way to save the record
        //I.E. Serial, Roles fields
        id: 0,
        concurrencyToken: 0,
        name: null,
        serial: 0,
        dollarAmount: null,
        active: null,
        roles: 0,
        startDate: null,
        endDate: null,
        notes: null,
        count: null,
        customFields: "{}",
        tags: []
      },
      formState: {
        ready: false,
        dirty: false,
        valid: true,
        readOnly: false,
        loading: true,
        errorBoxMessage: null,
        appError: null,
        serverError: {}
      },
      rights: window.$gz.role.defaultRightsObject()
    };
  },
  //WATCHERS
  watch: {
    formState: {
      handler: function(val) {
        //,oldval is available here too if necessary
        if (this.formState.loading) {
          return;
        }

        //enable / disable save button
        var canSave = val.dirty && val.valid && !val.readOnly;
        if (canSave) {
          window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":save");
        } else {
          window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":save");
        }

        //enable / disable duplicate button
        var canDuplicate = !val.dirty && val.valid && !val.readOnly;
        if (canDuplicate) {
          window.$gz.eventBus.$emit(
            "menu-enable-item",
            FORM_KEY + ":duplicate"
          );
        } else {
          window.$gz.eventBus.$emit(
            "menu-disable-item",
            FORM_KEY + ":duplicate"
          );
        }
      },
      deep: true
    }
  },
  computed: {
    canSave: function() {
      return this.formState.valid && this.formState.dirty;
    },
    canDuplicate: function() {
      return this.formState.valid && !this.formState.dirty;
    }
  },
  methods: {
    lt(ltKey) {
      return window.$gz.locale.get(ltKey);
    },
    ltFormat() {
      return window.$gz.locale.format();
    },
    form() {
      return window.$gz.form;
    },
    onChange(ref) {
      if (!this.formState.loading && !this.formState.readOnly) {
        window.$gz.form.onChange(this, ref);
      }
    },
    getDataFromApi(recordId) {
      this.formState.loading = true;
      if (!recordId) {
        throw FORM_KEY + "::getDataFromApi -> Missing recordID!";
      }
      var url = API_BASE_URL + recordId;
      var vm = this;
      window.$gz.form.deleteAllErrorBoxErrors(this);

      window.$gz.api
        .get(url)
        .then(res => {
          if (res.error != undefined) {
            //Not found?
            if (res.error.code == "2010") {
              //notify not found error then navigate backwards
              window.$gz.dialog
                .displayLTErrorMessage("ErrorAPI2010")
                .then(() => {
                  // navigate backwards
                  vm.$router.go(-1);
                });
            }
            vm.formState.serverError = res.error;
            window.$gz.form.setErrorBoxErrors(vm);
          } else {
            vm.obj = res.data;
            //Update the form status
            window.$gz.form.setFormState({
              vm: vm,
              dirty: false,
              valid: true,
              loading: false,
              readOnly: res.readOnly ? true : false
            });
            //modify the menu as necessary
            generateMenu(vm, res.readOnly);
          }
        })
        .catch(function handleGetDataFromAPIError(error) {
          //Update the form status
          window.$gz.form.setFormState({
            vm: vm,
            loading: false
          });
          window.$gz.errorHandler.handleFormError(error, vm);
        });
    },
    submit() {
      if (this.canSave) {
        this.formState.loading = true;
        var vm = this;
        var url = API_BASE_URL + this.$route.params.id;

        //clear any errors vm might be around from previous submit
        window.$gz.form.deleteAllErrorBoxErrors(this);
        window.$gz.api
          .upsert(url, this.obj)
          .then(res => {
            vm.formState.loading = false;
            if (res.error != undefined) {
              vm.formState.serverError = res.error;
              window.$gz.form.setErrorBoxErrors(vm);
            } else {
              //Logic for detecting if a post or put: if id then it was a post, if no id then it was a put
              if (res.data.id) {
                //Handle "post" of new record (CREATE)
                vm.obj = res.data;
                window.$gz.form.setFormState({
                  vm: vm,
                  dirty: false,
                  readOnly: res.readOnly ? true : false
                });

                //change url to new record but don't actually navigate, replace current url with same url but with the actual id at the end instead of zero:
                vm.$router.replace(
                  vm.$route.fullPath.slice(0, -1) + res.data.id
                );
              } else {
                //Handle "put" of an existing record (UPDATE)
                vm.obj.concurrencyToken = res.data.concurrencyToken;
                window.$gz.form.setFormState({
                  vm: vm,
                  dirty: false
                });
              }
            }
          })
          .catch(function handleSubmitError(error) {
            vm.formState.loading = false;
            window.$gz.errorHandler.handleFormError(error, vm);
          });
      }
    },
    remove() {
      var vm = this;
      window.$gz.dialog.confirmDelete().then(dialogResult => {
        if (dialogResult == true) {
          //do the delete
          vm.formState.loading = true;
          //No need to delete a new record, just abandon it...
          if (this.$route.params.id == 0) {
            //this should not get offered for delete but to be safe and clear just in case:
            JUST_DELETED = true;
            // navigate backwards
            vm.$router.go(-1);
          } else {
            var url = API_BASE_URL + vm.$route.params.id;

            window.$gz.form.deleteAllErrorBoxErrors(vm);
            window.$gz.api
              .remove(url)
              .then(res => {
                if (res.error != undefined) {
                  vm.formState.serverError = res.error;
                  window.$gz.form.setErrorBoxErrors(vm);
                } else {
                  //workaround to prevent warning about leaving dirty record
                  //For some reason I couldn't just reset isdirty in formstate
                  JUST_DELETED = true;
                  // navigate backwards
                  vm.$router.go(-1);
                }
              })
              .catch(function handleGetDataFromAPIError(error) {
                //Update the form status
                window.$gz.form.setFormState({
                  vm: vm,
                  loading: false
                });
                window.$gz.errorHandler.handleFormError(error, vm);
              });
          }
        }
      });
    },
    duplicate() {
      if (this.canDuplicate && this.$route.params.id != 0) {
        this.formState.loading = true;
        var vm = this;
        var url = API_BASE_URL + "duplicate/" + this.$route.params.id;

        //clear any errors vm might be around from previous submit
        window.$gz.form.deleteAllErrorBoxErrors(this);
        window.$gz.api
          .duplicate(url)
          .then(res => {
            // debugger;
            vm.formState.loading = false;
            if (res.error != undefined) {
              vm.formState.serverError = res.error;
              window.$gz.form.setErrorBoxErrors(vm);
            } else {
              //Navigate to new record
              vm.$router.push(
                window.$gz.api.replaceAfterLastSlash(
                  vm.$route.fullPath,
                  res.data.id
                )
              );
            }
          })
          .catch(function handleDuplicateError(error) {
            vm.formState.loading = false;
            window.$gz.errorHandler.handleFormError(error, vm);
          });
      }
    }
  }
};

/////////////////////////////
//
//
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;
      case "delete":
        m.vm.remove();
        break;
      case "duplicate":
        m.vm.duplicate();
        break;
      case "report":
        //TODO: FOLLOWING TWO LINES STILL VALID BUT NEED TO MAKE A REPORT CHOOSER COMPONENT
        // var reportList = window.$gz.report.availableReports("WIDGET");
        // var selectedItem = reportList[0].value;
        alert("STUB: REPORT LIST DIALOG");

        // window.$gz.dialog
        //   .getReportChoice(m.vm, reportList, selectedItem)
        //   .then(res => {
        //     if (res) {
        //       window.$gz.eventBus.$emit(
        //         "notify-success",
        //         FORM_KEY + "::report click, selected is: [" + res + "]"
        //       );
        //     }
        //   });

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

//////////////////////
//
//
function generateMenu(vm) {
  var menuOptions = {
    isMain: false,
    icon: "fa-splotch",
    title: window.$gz.locale.get("Widget"),
    helpUrl: "form-widget",
    formData: {
      formKey: FORM_KEY,
      ayaType: window.$gz.type.Widget,
      formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY
    },
    menuItems: []
  };

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

  if (vm.rights.delete) {
    menuOptions.menuItems.push({
      title: window.$gz.locale.get("Delete"),
      icon: "trash-alt",
      surface: true,
      key: FORM_KEY + ":delete",
      vm: vm
    });
  }

  if (vm.rights.change) {
    menuOptions.menuItems.push({
      title: window.$gz.locale.get("Duplicate"),
      icon: "clone",
      key: FORM_KEY + ":duplicate",
      vm: vm
    });
  }

  //STUB REPORTS

  menuOptions.menuItems.push({
    title: window.$gz.locale.get("Print"),
    icon: "print",
    key: FORM_KEY + ":report",
    vm: vm
  });

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

var JUST_DELETED = false;

//////////////////////
//
//
//
function initForm(vm) {
  return populatePickLists(vm);
}

//////////////////////
//
//
function populatePickLists(vm) {
  return window.$gz.api
    .get("AyaEnumPickList/list/authorizationroles")
    .then(res => {
      if (res.error) {
        throw res.error;
      }
      vm.pickLists.roles = res.data;
    });
}

//////////////////////
//
//
// function fetchLocaleText(vm) {
//   //Cache all required lt keys
//   var ltKeysRequired = [
//     "Widget",
//     "WidgetName",
//     "WidgetSerial",
//     "WidgetDollarAmount",
//     "WidgetCount",
//     "WidgetRoles",
//     "WidgetStartDate",
//     "WidgetEndDate",
//     "WidgetNotes",
//     "WidgetCustom1",
//     "WidgetCustom2",
//     "WidgetCustom3",
//     "WidgetCustom4",
//     "WidgetCustom5",
//     "WidgetCustom6",
//     "WidgetCustom7",
//     "WidgetCustom8",
//     "WidgetCustom9",
//     "WidgetCustom10",
//     "WidgetCustom11",
//     "WidgetCustom12",
//     "WidgetCustom13",
//     "WidgetCustom14",
//     "WidgetCustom15",
//     "WidgetCustom16"
//   ];

//   return window.$gz.locale.fetch(ltKeysRequired);
// }
</script>

<style></style>
