<template>
  <v-layout v-if="this.formState.ready">
    <v-flex>
      <v-form ref="form">
        <v-layout align-center justify-left row wrap>
          <v-flex xs12 mt-1 mb-2>
            <v-alert
              ref="errorbox"
              v-show="formState.errorBoxMessage"
              color="error"
              icon="fa-exclamation-circle "
              value="true"
              transition="scale-transition"
              class="multi-line"
              outline
              >{{ formState.errorBoxMessage }}</v-alert
            >
          </v-flex>
          <v-flex xs12 sm6 lg4 xl3 px-2>
            <v-text-field
              v-model="obj.name"
              :readonly="this.formState.readOnly"
              clearable
              @click:clear="onChange('name')"
              :counter="255"
              :label="this.$gzlocale.get('WidgetName')"
              :rules="[
                this.$gzform.max255(this, 'name'),
                this.$gzform.required(this, 'name')
              ]"
              :error-messages="this.$gzform.serverErrors(this, 'name')"
              ref="name"
              @change="onChange('name')"
            ></v-text-field>
          </v-flex>
          <v-flex xs12 sm6 lg4 xl3 px-2>
            <v-text-field
              v-model="obj.serial"
              :readonly="this.formState.readOnly"
              clearable
              @click:clear="onChange('serial')"
              :counter="10"
              :label="this.$gzlocale.get('WidgetSerial')"
              :rules="[this.$gzform.maxLength(this, 'serial', 10)]"
              :error-messages="this.$gzform.serverErrors(this, 'serial')"
              ref="serial"
              @change="onChange('serial')"
            ></v-text-field>
          </v-flex>
          <v-flex xs12 sm6 lg4 xl3 px-2>
            <v-text-field
              v-model="obj.count"
              :readonly="this.formState.readOnly"
              clearable
              @click:clear="onChange('count')"
              :counter="10"
              :label="this.$gzlocale.get('WidgetCount')"
              ref="count"
              :rules="[
                this.$gzform.integerValid(this, 'count'),
                this.$gzform.required(this, 'count')
              ]"
              :error-messages="this.$gzform.serverErrors(this, 'count')"
              required
              @change="onChange('count')"
              type="number"
            ></v-text-field>
          </v-flex>

          <v-flex xs12 sm6 lg4 xl3 px-2>
            <v-text-field
              v-model="obj.dollarAmount"
              :readonly="this.formState.readOnly"
              :prefix="this.$gzlocale.format().currencySymbol"
              :label="this.$gzlocale.get('WidgetDollarAmount')"
              ref="dollarAmount"
              required
              :rules="[
                this.$gzform.decimalValid(this, 'dollarAmount'),
                this.$gzform.required(this, 'dollarAmount')
              ]"
              :error-messages="this.$gzform.serverErrors(this, 'dollarAmount')"
              @change="onChange('dollarAmount')"
              type="number"
            ></v-text-field>
          </v-flex>

          <v-flex xs12 sm6 lg4 xl3 px-2>
            <gz-date-time-picker
              :label="this.$gzlocale.get('WidgetStartDate')"
              v-model="obj.startDate"
              :readonly="this.formState.readOnly"
              ref="startDate"
              :error-messages="this.$gzform.serverErrors(this, 'startDate')"
              @change="onChange('startDate')"
            ></gz-date-time-picker>
          </v-flex>

          <v-flex xs12 sm6 lg4 xl3 px-2>
            <gz-date-time-picker
              :label="this.$gzlocale.get('WidgetEndDate')"
              :rules="[
                this.$gzform.datePrecedence(this, 'startDate', 'endDate')
              ]"
              :error-messages="this.$gzform.serverErrors(this, 'endDate')"
              v-model="obj.endDate"
              :readonly="this.formState.readOnly"
              ref="endDate"
              @change="onChange('endDate')"
            ></gz-date-time-picker>
          </v-flex>
          <v-flex xs12 sm6 lg4 xl3 px-2>
            <v-checkbox
              v-model="obj.active"
              :readonly="this.formState.readOnly"
              :label="this.$gzlocale.get('Active')"
              ref="active"
              :error-messages="this.$gzform.serverErrors(this, 'active')"
              required
              @change="onChange('active')"
            ></v-checkbox>
          </v-flex>
          <v-flex xs12 sm6 lg4 xl3 px-2>
            <v-select
              v-model="obj.roles"
              :items="pickLists.roles"
              item-text="name"
              item-value="id"
              :readonly="this.formState.readOnly"
              :label="this.$gzlocale.get('WidgetRoles')"
              ref="roles"
              :rules="[
                this.$gzform.integerValid(this, 'roles'),
                this.$gzform.required(this, 'roles')
              ]"
              :error-messages="this.$gzform.serverErrors(this, 'roles')"
              required
              @change="onChange('roles')"
            ></v-select>
          </v-flex>

          <v-flex xs12 px-2>
            <v-textarea
              v-model="obj.notes"
              :readonly="this.formState.readOnly"
              :label="this.$gzlocale.get('WidgetNotes')"
              :error-messages="this.$gzform.serverErrors(this, 'notes')"
              ref="notes"
              @change="onChange('notes')"
              auto-grow
            ></v-textarea>
          </v-flex>

          <v-flex xs12 px-2>
            <gz-tag-picker
              :label="this.$gzlocale.get('Tags')"
              v-model="obj.tags"
              :readonly="this.formState.readOnly"
              ref="tags"
              :error-messages="this.$gzform.serverErrors(this, 'tags')"
              @change="onChange('tags')"
            ></gz-tag-picker>
          </v-flex>

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

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

const FORM_KEY = "inventory-widget-edit";
const FORM_BASE_URL = "Widget/";
const FORM_CUSTOM_TEMPLATE_KEY = "widget";

export default {
  beforeCreate() {
    //console.log("BEFORECREATE: TOP");
    var vm = this;
    initForm(this)
      .then(() => {
        vm.formState.ready = true;
      })
      .catch(err => {
        vm.formState.ready = true;
        vm.$gzHandleFormError(err);
      });
  },
  created() {
    this.rights = this.$gzrole.getRights(this, this.$gztype.Widget);

    this.$gzevent.$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
      this.$gzform.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;

      //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) {
      vm.$gzdialog.confirmLeaveUnsaved(vm).then(dialogResult => {
        if (dialogResult == true) {
          next();
        } else {
          next(false);
        }
      });
    } else {
      next();
    }
  },
  beforeDestroy() {
    this.$gzevent.$off("menu-click", clickHandler);
  },
  components: {},
  data() {
    return {
      formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
      pickLists: {
        roles: []
      },
      obj: {
        id: 0,
        concurrencyToken: 0,
        name: null,
        serial: null,
        dollarAmount: null,
        active: null,
        roles: null,
        startDate: null,
        endDate: null,
        notes: null,
        count: null,
        customFields: null,
        tags: []
      },
      formState: {
        ready: false,
        dirty: false,
        valid: true,
        readOnly: false,
        loading: true,
        errorBoxMessage: null,
        appError: null,
        serverError: {}
      },
      rights: this.$gzrole.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) {
          this.$gzevent.$emit("menu-enable-item", FORM_KEY + ":save");
        } else {
          this.$gzevent.$emit("menu-disable-item", FORM_KEY + ":save");
        }

        //enable / disable duplicate button
        var canDuplicate = !val.dirty && val.valid && !val.readOnly;
        if (canDuplicate) {
          this.$gzevent.$emit("menu-enable-item", FORM_KEY + ":duplicate");
        } else {
          this.$gzevent.$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: {
    onChange(ref) {
      if (!this.formState.loading && !this.formState.readOnly) {
        this.$gzform.onChange(this, ref);
      }
    },
    getDataFromApi(recordId) {
      this.formState.loading = true;
      if (!recordId) {
        throw FORM_KEY + "::getDataFromApi -> Missing recordID!";
      }
      var url = FORM_BASE_URL + recordId;
      var vm = this;
      this.$gzform.deleteAllErrorBoxErrors(this);

      this.$gzapi
        .get(url)
        .then(res => {
          if (res.error != undefined) {
            //Not found?
            if (res.error.code == "2010") {
              //notify not found error then navigate backwards
              vm.$gzdialog
                .displayLTErrorMessage(vm, "ErrorAPI2010")
                .then(() => {
                  // navigate backwards
                  vm.$router.go(-1);
                });
            }
            vm.formState.serverError = res.error;
            vm.$gzform.setErrorBoxErrors(vm);
          } else {
            vm.obj = res.data;
            //Update the form status
            vm.$gzform.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
          vm.$gzform.setFormState({
            vm: vm,
            loading: false
          });
          vm.$gzHandleFormError(error, vm);
        });
    },
    submit() {
      if (this.canSave) {
        this.formState.loading = true;
        var vm = this;
        var url = FORM_BASE_URL + this.$route.params.id;

        //clear any errors vm might be around from previous submit
        this.$gzform.deleteAllErrorBoxErrors(this);
        this.$gzapi
          .upsert(url, this.obj)
          .then(res => {
            vm.formState.loading = false;
            if (res.error != undefined) {
              vm.formState.serverError = res.error;
              vm.$gzform.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;
                vm.$gzform.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;
                vm.$gzform.setFormState({
                  vm: vm,
                  dirty: false
                });
              }
            }
          })
          .catch(function handleSubmitError(error) {
            vm.formState.loading = false;
            vm.$gzHandleFormError(error, vm);
          });
      }
    },
    remove() {
      var vm = this;
      vm.$gzdialog.confirmDelete(vm).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 delet but to be safe and clear just in case:
            JUST_DELETED = true;
            // navigate backwards
            vm.$router.go(-1);
          } else {
            var url = FORM_BASE_URL + vm.$route.params.id;

            vm.$gzform.deleteAllErrorBoxErrors(vm);
            vm.$gzapi
              .remove(url)
              .then(res => {
                if (res.error != undefined) {
                  vm.formState.serverError = res.error;
                  vm.$gzform.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
                vm.$gzform.setFormState({
                  vm: vm,
                  loading: false
                });
                vm.$gzHandleFormError(error, vm);
              });
          }
        }
      });
    },
    duplicate() {
      if (this.canDuplicate && this.$route.params.id != 0) {
        this.formState.loading = true;
        var vm = this;
        var url = FORM_BASE_URL + "duplicate/" + this.$route.params.id;

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

/////////////////////////////
//
//
function clickHandler(menuItem) {
  if (!menuItem) {
    return;
  }
  var m = this.$gzmenu.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":
        var reportList = m.vm.$gzreport.availableReports("WIDGET");
        var selectedItem = reportList[0].value;
        m.vm.$gzdialog
          .getReportChoice(m.vm, reportList, selectedItem)
          .then(res => {
            if (res) {
              m.vm.$gzevent.$emit(
                "notify-success",
                FORM_KEY + "::report click, selected is: [" + res + "]"
              );
            }
          });

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

//////////////////////
//
//
function generateMenu(vm) {
  var menuOptions = {
    isMain: false,
    icon: "fa-splotch",
    title: vm.$gzlocale.get("Widget"),
    helpUrl: "intro/#searching",
    formData: { formKey: FORM_KEY, ayaType: vm.$gztype.Widget },
    menuItems: []
  };

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

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

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

  //STUB REPORTS

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

  vm.$gzevent.$emit("menu-change", menuOptions);
}

var JUST_DELETED = false;

//////////////////////
//
//
function initForm(vm) {
  return fetchLocaleText(vm).then(
    populatePickLists(vm).then(
      vm.$gzformcustomtemplate.get(FORM_CUSTOM_TEMPLATE_KEY)
    )
  );
}

//////////////////////
//
//
function populatePickLists(vm) {
  return vm.$gzapi.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 vm.$gzlocale.fetch(ltKeysRequired);
}
</script>

<style></style>
