<template>
  <div>
    <gz-report-selector ref="reportSelector"></gz-report-selector>
    <div v-if="formState.ready">
      <gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
      <v-form ref="form">
        <v-row dense>
          <v-col cols="12" sm="6" lg="4" xl="3">
            <gz-pick-list
              ref="customerId"
              v-model="obj.customerId"
              :aya-type="sockTypes().Customer"
              show-edit-icon
              :readonly="formState.readOnly"
              :label="$sock.t('Customer')"
              :error-messages="form().serverErrors(this, 'customerId')"
              :rules="[form().required(this, 'customerId')]"
              @input="fieldValueChanged('customerId')"
              @update:name="customerChanged"
            ></gz-pick-list>
          </v-col>

          <v-col cols="12" sm="6" lg="4" xl="3">
            <v-select
              ref="pGroup"
              v-model="obj.pGroup"
              dense
              :items="selectLists.pGroups"
              item-text="name"
              item-value="id"
              :readonly="formState.readOnly"
              :label="$sock.t('ProductGroup')"
              data-cy="pGroup"
              :rules="[form().integerValid(this, 'pGroup')]"
              :error-messages="form().serverErrors(this, 'pGroup')"
              @input="fieldValueChanged('pGroup')"
            ></v-select>
          </v-col>

          <v-col cols="12" sm="6" lg="4" xl="3">
            <v-text-field
              ref="subsite"
              v-model="obj.subsite"
              dense
              :readonly="formState.readOnly"
              :label="$sock.t('SubSite')"
              :error-messages="form().serverErrors(this, 'subsite')"
              data-cy="subsite"
              @input="fieldValueChanged('subsite')"
            ></v-text-field>
          </v-col>
          <v-col cols="12" sm="6" lg="4" xl="3">
            <v-text-field
              ref="regTo"
              v-model="obj.regTo"
              dense
              :readonly="formState.readOnly"
              :label="$sock.t('LicenseRegTo')"
              :rules="[form().required(this, 'regTo')]"
              :error-messages="form().serverErrors(this, 'regTo')"
              data-cy="regTo"
              @input="fieldValueChanged('regTo')"
            ></v-text-field>
          </v-col>

          <v-col cols="12" sm="6" lg="4" xl="3">
            <gz-email
              ref="fetchEmail"
              v-model="obj.fetchEmail"
              :readonly="formState.readOnly"
              :label="$sock.t('LicenseFetchEmail')"
              data-cy="fetchEmail"
              :error-messages="form().serverErrors(this, 'fetchEmail')"
              @input="fieldValueChanged('fetchEmail')"
            ></gz-email>
          </v-col>
          <v-col cols="12" sm="6" lg="4" xl="3">
            <v-text-field
              ref="dbId"
              v-model="obj.dbId"
              dense
              :readonly="formState.readOnly"
              :label="$sock.t('DatabaseID')"
              :rules="[form().required(this, 'dbId')]"
              :error-messages="form().serverErrors(this, 'dbId')"
              data-cy="dbId"
              @input="fieldValueChanged('dbId')"
            ></v-text-field>
          </v-col>
          <!-- ################################ SUBSCRIPTION ITEMS LIST ############################### -->

          <v-col cols="12" class="mb-6">
            <v-data-table
              :headers="headerList"
              :items="itemList"
              item-key="index"
              class="elevation-1"
              disable-pagination
              disable-filtering
              disable-sort
              hide-default-footer
              data-cy="itemsTable"
              dense
              :item-class="itemsRowClasses"
              :no-data-text="$sock.t('NoData')"
            >
              <!-- <template v-slot:[`item.productViz`]="{ item }">
                <div class="subtitle-1" @click="openItem(item)">
                  <a href="javascript:"> {{ item.productViz }}</a>
                </div>
              </template> -->
              <template v-slot:top>
                <v-col cols="12">
                  <v-menu v-if="rights.change" offset-y>
                    <template v-slot:activator="{ on, attrs }">
                      <span class="text-subtitle-2">
                        {{ $sock.t("SubscriptionItemList") }}</span
                      ><v-btn large icon v-bind="attrs" v-on="on">
                        <v-icon small color="primary">$sockiEllipsisV</v-icon>
                      </v-btn>
                    </template>
                    <v-list>
                      <v-list-item @click="newItem">
                        <v-list-item-icon>
                          <v-icon>$sockiPlus</v-icon>
                        </v-list-item-icon>
                        <v-list-item-title>{{
                          $sock.t("New")
                        }}</v-list-item-title>
                      </v-list-item>
                    </v-list>
                  </v-menu>
                  <span v-else class="text-h6">
                    {{ $sock.t("SubscriptionItemList") }}</span
                  >
                </v-col>
              </template>

              <template v-slot:[`item.renewal`]="{ item }">
                <v-simple-checkbox
                  v-model="item.renewal"
                  disabled
                ></v-simple-checkbox>
              </template>

              <template v-slot:[`item.active`]="{ item }">
                <v-simple-checkbox
                  v-model="item.active"
                  disabled
                ></v-simple-checkbox>
              </template>

              <template v-slot:[`item.actions`]="{ item }">
                <v-btn icon @click="editItem(item)">
                  <v-icon :class="itemsRowClasses(item)">
                    $sockiEdit
                  </v-icon>
                </v-btn>
              </template>
            </v-data-table>
          </v-col>

          <!-- --------------------------------- -->

          <v-col v-if="form().showMe(this, 'Notes')" cols="12">
            <v-textarea
              ref="notes"
              v-model="obj.notes"
              dense
              :readonly="formState.readOnly"
              :label="$sock.t('ContractNotes')"
              :error-messages="form().serverErrors(this, 'notes')"
              data-cy="notes"
              auto-grow
              @input="fieldValueChanged('notes')"
            ></v-textarea>
          </v-col>

          <v-col cols="12" sm="6" lg="4" xl="3">
            <v-checkbox
              ref="active"
              v-model="obj.active"
              dense
              :readonly="formState.readOnly"
              :label="$sock.t('Active')"
              data-cy="active"
              :error-messages="form().serverErrors(this, 'active')"
              @change="fieldValueChanged('active')"
            ></v-checkbox>
          </v-col>
          <!-- --------------------------------- -->

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

          <v-col v-if="form().showMe(this, 'Attachments') && obj.id" cols="12">
            <gz-attachments
              :readonly="formState.readOnly"
              :aya-type="sockType"
              :aya-id="obj.id"
            ></gz-attachments
          ></v-col>
        </v-row>
      </v-form>
    </div>
    <v-overlay :value="!formState.ready || formState.loading">
      <v-progress-circular indeterminate :size="64" />
    </v-overlay>

    <!-- #########################################################################################-->
    <!-- ########################## SUBSCRIPTION ITEM EDIT FORM  ###############################-->
    <!-- #########################################################################################-->
    <template v-if="obj.items.length">
      <v-row dense justify="center">
        <v-dialog v-model="editItemDialog">
          <v-card>
            <v-card-title> </v-card-title>
            <v-card-text>
              <v-row dense>
                <v-col cols="12" sm="6" lg="4" xl="3">
                  <gz-pick-list
                    ref="Items.ProductId"
                    v-model="obj.items[editItemIndex].productId"
                    :aya-type="sockTypes().Product"
                    :allow-no-selection="false"
                    show-edit-icon
                    :readonly="formState.readOnly"
                    :label="$sock.t('Product')"
                    data-cy="Items.ProductId"
                    :rules="[form().required(this, 'Items.ProductId')]"
                    :error-messages="
                      form().serverErrors(
                        this,
                        `Items[${editItemIndex}].productId`
                      )
                    "
                    @input="
                      fieldValueChanged(`Items[${editItemIndex}].productId`)
                    "
                  ></gz-pick-list>
                </v-col>

                <v-col cols="12" sm="6" lg="4" xl="3">
                  <gz-decimal
                    ref="Items.Quantity"
                    v-model="obj.items[editItemIndex].quantity"
                    :readonly="formState.readOnly"
                    :label="$sock.t('PurchaseQuantity')"
                    data-cy="Items.quantity"
                    :error-messages="
                      form().serverErrors(
                        this,
                        `Items[${editItemIndex}].quantity`
                      )
                    "
                    :rules="[
                      form().decimalValid(this, 'Items.quantity'),
                      form().required(this, 'Items.quantity')
                    ]"
                    @input="
                      fieldValueChanged(`Items[${editItemIndex}].quantity`)
                    "
                  ></gz-decimal>
                </v-col>

                <v-col cols="12" sm="6" lg="4" xl="3">
                  <v-row no-gutters>
                    <v-col cols="1">
                      <v-menu offset-y>
                        <template v-slot:activator="{ on, attrs }">
                          <v-btn icon v-bind="attrs" v-on="on">
                            <v-icon small>$sockiPlus</v-icon>
                          </v-btn>
                        </template>
                        <v-list>
                          <!-- <v-list-item @click="subExpireAddOneWeek">
                            <v-list-item-icon>
                              <v-icon>$sockiPlus</v-icon>
                            </v-list-item-icon>
                            <v-list-item-title>One week</v-list-item-title>
                          </v-list-item> -->
                          <v-list-item @click="subExpireAddOneMonth">
                            <v-list-item-icon>
                              <v-icon>$sockiPlus</v-icon>
                            </v-list-item-icon>
                            <v-list-item-title
                              >One month + 7d</v-list-item-title
                            >
                          </v-list-item>
                          <v-list-item @click="subExpireAddOneYear">
                            <v-list-item-icon>
                              <v-icon>$sockiPlus</v-icon>
                            </v-list-item-icon>
                            <v-list-item-title>One year + 7d</v-list-item-title>
                          </v-list-item>
                        </v-list>
                      </v-menu>
                    </v-col>
                    <v-col>
                      <gz-date-time-picker
                        ref="Items.expireDate"
                        v-model="obj.items[editItemIndex].expireDate"
                        :label="$sock.t('PurchaseExpireDate')"
                        :readonly="formState.readOnly"
                        :error-messages="
                          form().serverErrors(
                            this,
                            `Items[${editItemIndex}].expireDate`
                          )
                        "
                        :rules="[form().required(this, 'Items.expireDate')]"
                        @input="
                          fieldValueChanged(
                            `Items[${editItemIndex}].expireDate`
                          )
                        "
                      ></gz-date-time-picker>
                    </v-col>
                  </v-row>
                </v-col>
                <v-col cols="12" sm="6" lg="4" xl="3">
                  <v-checkbox
                    ref="renewal"
                    v-model="obj.items[editItemIndex].renewal"
                    dense
                    :readonly="formState.readOnly"
                    :label="$sock.t('Renewal')"
                    :error-messages="
                      form().serverErrors(
                        this,
                        `Items[${editItemIndex}].renewal`
                      )
                    "
                    @change="
                      fieldValueChanged(`Items[${editItemIndex}].renewal`)
                    "
                  ></v-checkbox>
                </v-col>
                <v-col cols="12" sm="6" lg="4" xl="3">
                  <gz-date-time-picker
                    ref="Items.originalOrderDate"
                    v-model="obj.items[editItemIndex].originalOrderDate"
                    :label="$sock.t('OriginalOrderDate')"
                    :readonly="formState.readOnly"
                    :error-messages="
                      form().serverErrors(
                        this,
                        `Items[${editItemIndex}].originalOrderDate`
                      )
                    "
                    :rules="[form().required(this, 'Items.originalOrderDate')]"
                    @input="
                      fieldValueChanged(
                        `Items[${editItemIndex}].originalOrderDate`
                      )
                    "
                  ></gz-date-time-picker>
                </v-col>

                <v-col cols="12" sm="6" lg="4" xl="3">
                  <v-text-field
                    ref="Items.originalOrderNumber"
                    v-model="obj.items[editItemIndex].originalOrderNumber"
                    dense
                    :label="$sock.t('OriginalOrderNumber')"
                    :readonly="formState.readOnly"
                    :error-messages="
                      form().serverErrors(
                        this,
                        `Items[${editItemIndex}].originalOrderNumber`
                      )
                    "
                    :rules="[
                      form().required(this, 'Items.originalOrderNumber')
                    ]"
                    @input="
                      fieldValueChanged(
                        `Items[${editItemIndex}].originalOrderNumber`
                      )
                    "
                  ></v-text-field>
                </v-col>
                <v-col cols="12" sm="6" lg="4" xl="3">
                  <v-checkbox
                    ref="active"
                    v-model="obj.items[editItemIndex].active"
                    dense
                    :readonly="formState.readOnly"
                    :label="$sock.t('Active')"
                    :error-messages="
                      form().serverErrors(
                        this,
                        `Items[${editItemIndex}].active`
                      )
                    "
                    @change="
                      fieldValueChanged(`Items[${editItemIndex}].active`)
                    "
                  ></v-checkbox>
                </v-col>
              </v-row>
            </v-card-text>
            <v-card-actions>
              <template v-if="!$vuetify.breakpoint.xs">
                <v-btn
                  color="red darken-1"
                  text
                  @click="deleteItem(obj.items[editItemIndex])"
                  >{{ $sock.t("Delete") }}</v-btn
                >
                <v-spacer></v-spacer>
                <v-btn
                  color="blue darken-1"
                  text
                  @click="editItemDialog = false"
                  >{{ $sock.t("Close") }}</v-btn
                >

                <v-btn
                  color="blue darken-1"
                  text
                  class="ml-4"
                  @click="duplicateItem(obj.items[editItemIndex])"
                  >{{ $sock.t("Duplicate") }}</v-btn
                >
                <v-btn
                  color="blue darken-1"
                  text
                  class="ml-4"
                  @click="newItem()"
                  >{{ $sock.t("New") }}</v-btn
                >

                <v-btn
                  color="blue darken-1"
                  text
                  class="ml-4"
                  @click="submit()"
                  >{{ $sock.t("Save") }}</v-btn
                >
              </template>
              <template v-else>
                <!-- MOBILE FORMAT -->
                <v-row dense>
                  <v-btn
                    class="mt-4"
                    block
                    text
                    color="blue darken-1"
                    @click="submit()"
                    >{{ $sock.t("Save") }}</v-btn
                  >
                  <v-btn
                    class="mt-4"
                    block
                    text
                    color="blue darken-1"
                    @click="duplicateItem(obj.items[editItemIndex])"
                    >{{ $sock.t("Duplicate") }}</v-btn
                  >
                  <v-btn
                    class="mt-4"
                    block
                    text
                    color="blue darken-1"
                    @click="newItem()"
                    >{{ $sock.t("New") }}</v-btn
                  >
                  <v-btn
                    class="mt-4"
                    block
                    text
                    color="blue darken-1"
                    @click="editItemDialog = false"
                    >{{ $sock.t("Close") }}</v-btn
                  >

                  <v-btn
                    class="mt-8 mb-6"
                    block
                    text
                    color="red darken-1"
                    @click="deleteItem(obj.items[editItemIndex])"
                    >{{ $sock.t("Delete") }}</v-btn
                  >
                </v-row>
              </template>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-row>
    </template>
  </div>
</template>
<script>
const FORM_KEY = "subscription-edit";
const API_BASE_URL = "subscription/";
const FORM_CUSTOM_TEMPLATE_KEY = "Subscription";
export default {
  data() {
    return {
      formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
      editItemDialog: false,
      editItemIndex: 0,
      obj: {
        id: 0,
        concurrency: 0,
        customerId: null,
        pGroup: null,
        active: true,
        subsite: "main",
        regTo: null,
        fetchEmail: null,
        dbId: null,
        items: [],
        notes: null,
        tags: []
      },
      formState: {
        ready: false,
        dirty: false,
        valid: true,
        readOnly: false,
        loading: true,
        errorBoxMessage: null,
        appError: null,
        serverError: {}
      },
      rights: window.$gz.role.defaultRightsObject(),
      sockType: window.$gz.type.Subscription,
      selectLists: {
        pGroups: []
      }
    };
  },
  computed: {
    headerList: function() {
      const headers = [];
      headers.push({
        text: this.$sock.t("ProductName"),
        align: "left",
        value: "productViz"
      });

      headers.push({
        text: this.$sock.t("PurchaseQuantity"),
        align: "right",
        value: "quantity"
      });
      headers.push({
        text: this.$sock.t("Renewal"),
        align: "center",
        value: "renewal"
      });

      headers.push({
        text: this.$sock.t("PurchaseExpireDate"),
        align: "right",
        value: "expireDate"
      });

      headers.push({
        text: this.$sock.t("Active"),
        align: "center",
        value: "active"
      });

      if (!this.formState.readOnly) {
        headers.push({ text: "", value: "actions" });
      }
      return headers;
    },
    itemList: function() {
      return this.obj.items.map((x, i) => {
        return {
          index: i,
          id: x.id,
          quantity: window.$gz.locale.decimalLocalized(
            x.quantity,
            this.languageName
          ),
          expireDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
            x.expireDate,
            this.timeZoneName,
            this.languageName,
            this.hour12
          ),
          active: x.active,
          renewal: x.renewal,
          productViz: x.productViz
        };
      });
    }
  },
  watch: {
    formState: {
      handler: function(val) {
        if (this.formState.loading) {
          return;
        }

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

        if (!val.dirty && val.valid && !val.readOnly) {
          window.$gz.eventBus.$emit(
            "menu-enable-item",
            FORM_KEY + ":duplicate"
          );
          window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":license");
          window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":new");
        } else {
          window.$gz.eventBus.$emit(
            "menu-disable-item",
            FORM_KEY + ":duplicate"
          );
          window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":license");
          window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":new");
        }
      },
      deep: true
    }
  },
  async created() {
    const vm = this;
    try {
      await initForm(vm);
      vm.rights = window.$gz.role.getRights(window.$gz.type.Subscription);
      vm.formState.readOnly = !vm.rights.change;
      window.$gz.eventBus.$on("menu-click", clickHandler);
      //---------------------------------
      let setDirty = false;
      //id 0 means create or duplicate to new
      if (vm.$route.params.recordid != 0) {
        //is there already an obj from a prior operation?
        if (this.$route.params.obj) {
          //yes, no need to fetch it
          this.obj = this.$route.params.obj;
        } else {
          await vm.getDataFromApi(vm.$route.params.recordid);
        }
      } else {
        //Might be a duplicate and contain another record
        if (this.$route.params.obj) {
          this.obj = this.$route.params.obj;
          this.obj.concurrency = undefined;
          this.obj.id = 0;
          this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
            "Copy"
          )}`;
          setDirty = true;
        }
      }
      window.$gz.form.setFormState({
        vm: vm,
        loading: false,
        dirty: setDirty,
        valid: true
      });
      //----------------------------
      generateMenu(vm);
    } catch (error) {
      window.$gz.errorHandler.handleFormError(error, vm);
    } finally {
      vm.formState.ready = true;
    }
  },
  async beforeRouteLeave(to, from, next) {
    if (!this.formState.dirty || JUST_DELETED) {
      next();
      return;
    }
    if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
      next();
    } else {
      next(false);
    }
  },
  beforeDestroy() {
    window.$gz.eventBus.$off("menu-click", clickHandler);
  },
  methods: {
    editItem: function(item) {
      this.editItemIndex = item.index;
      this.editItemDialog = true;
    },
    newItem: function() {
      this.obj.items.push({
        id: 0,
        subscriptionId: 0,
        productId: null,
        quantity: 1,
        expireDate: null, //deliberate to ensure a date gets set properly as some items are monthly and some yearly can't just assume a date here
        originalOrderDate: window.$gz.locale.nowUTC8601String(),
        originalOrderNumber: null,
        active: true,
        renewal: false
      });
      this.editItemIndex = this.obj.items.length - 1;
      this.editItemDialog = true;
      this.formState.dirty = true;
    },
    duplicateItem: function(src) {
      this.obj.items.push({
        id: 0,
        subscriptionId: 0,
        productId: null,
        quantity: 1,
        expireDate: src.expireDate,
        originalOrderDate: src.originalOrderDate,
        originalOrderNumber: src.originalOrderNumber,
        active: true,
        renewal: false
      });
      this.editItemIndex = this.obj.items.length - 1;
      this.editItemDialog = true;
      this.formState.dirty = true;
    },
    deleteItem: function() {
      this.editItemDialog = false;
      this.obj.items.splice(this.editItemIndex, 1);
      this.editItemIndex = 0;
      this.formState.dirty = true;
    },
    itemsRowClasses: function(item) {
      const path = `Items[${item.index}].`;
      if (this.form().childRowHasError(this, path)) {
        return "font-weight-black font-italic error--text";
      }
    },
    subExpireAddOneWeek: function() {
      this.obj.items[this.editItemIndex].expireDate = addToDate(
        this.obj.items[this.editItemIndex].expireDate,
        {
          days: 7
        }
      );
    },
    subExpireAddOneMonth: function() {
      this.obj.items[this.editItemIndex].expireDate = addToDate(
        this.obj.items[this.editItemIndex].expireDate,
        {
          months: 1,
          days: 7
        }
      );
    },
    subExpireAddOneYear: function() {
      this.obj.items[this.editItemIndex].expireDate = addToDate(
        this.obj.items[this.editItemIndex].expireDate,
        {
          years: 1,
          days: 7
        }
      );
      //   const now = window.$gz.locale.nowUTC8601String(this.timeZoneName);
      //   this.obj.items[
      //     this.editItemIndex
      //   ].expireDate = window.$gz.locale.addDurationToUTC8601String(now, {
      //     years: 1
      //   });
    },
    async customerChanged() {
      const id = this.obj.customerId;
      if (!id || id == 0) {
        return;
      }
      const res = await window.$gz.api.get(`customer/${id}`);
      if (res.error) {
        window.$gz.eventBus.$emit(
          "notify-warning",
          window.$gz.errorHandler.errorToString(res, this)
        );
      } else {
        //Use customer record to update stuff here
        this.obj.fetchEmail = res.data.emailAddress;
        this.obj.regTo = res.data.name;
        this.obj.dbId = res.data.dbId;
      }
    },
    canSave: function() {
      return this.formState.valid && this.formState.dirty;
    },
    canDuplicate: function() {
      return this.formState.valid && !this.formState.dirty;
    },
    sockTypes: function() {
      return window.$gz.type;
    },
    form() {
      return window.$gz.form;
    },
    fieldValueChanged(ref) {
      if (
        this.formState.ready &&
        !this.formState.loading &&
        !this.formState.readOnly
      ) {
        window.$gz.form.fieldValueChanged(this, ref);
      }
    },
    async getDataFromApi(recordId) {
      const vm = this;
      window.$gz.form.setFormState({
        vm: vm,
        loading: true
      });
      if (!recordId) {
        throw new Error(FORM_KEY + "::getDataFromApi -> Missing recordID!");
      }
      try {
        window.$gz.form.deleteAllErrorBoxErrors(vm);
        const res = await window.$gz.api.get(API_BASE_URL + recordId);
        if (res.error) {
          if (res.error.code == "2010") {
            window.$gz.form.handleObjectNotFound(vm);
          }
          vm.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(vm);
        } else {
          vm.obj = res.data;
          generateMenu(vm);
          window.$gz.form.setFormState({
            vm: vm,
            dirty: false,
            valid: true,
            loading: false
          });
        }
      } catch (error) {
        window.$gz.errorHandler.handleFormError(error, vm);
      } finally {
        window.$gz.form.setFormState({
          vm: vm,
          loading: false
        });
      }
    },
    async submit() {
      const vm = this;
      if (vm.canSave == false) {
        return;
      }
      try {
        window.$gz.form.setFormState({
          vm: vm,
          loading: true
        });
        window.$gz.form.deleteAllErrorBoxErrors(vm);
        const res = await window.$gz.api.upsert(API_BASE_URL, vm.obj);
        if (res.error) {
          vm.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(vm);
        } else {
          //POST or PUT which is a little different than other objects
          //so if it's new then need to navigate to it to update url with id
          if (vm.$route.params.recordid != 0) {
            //update of existing record
            vm.obj = res.data;
          } else {
            this.$router.replace({
              name: "subscription-edit",
              params: {
                recordid: res.data.id,
                obj: res.data
              }
            });
          }
          window.$gz.form.setFormState({
            vm: vm,
            dirty: false,
            valid: true
          });
        }
        //{
        //   if (res.data.id) {
        //     //POST
        //     vm.obj = res.data;
        //     this.$router.replace({
        //       name: "subscription-edit",
        //       params: {
        //         recordid: res.data.id,
        //         obj: res.data
        //       }
        //     });
        //   } else {
        //     //PUT
        //     vm.obj.concurrency = res.data.concurrency;
        //   }
        //   window.$gz.form.setFormState({
        //     vm: vm,
        //     dirty: false,
        //     valid: true
        //   });
        // }
      } catch (ex) {
        window.$gz.errorHandler.handleFormError(ex, vm);
      } finally {
        window.$gz.form.setFormState({
          vm: vm,
          loading: false
        });
      }
    },
    async remove() {
      try {
        const dialogResult = await window.$gz.dialog.confirmDelete();
        if (dialogResult != true) {
          return;
        }
        window.$gz.form.setFormState({
          vm: this,
          loading: true
        });

        if (this.$route.params.recordid == 0) {
          JUST_DELETED = true;

          this.$router.go(-1);
        } else {
          window.$gz.form.deleteAllErrorBoxErrors(this);
          const res = await window.$gz.api.remove(
            API_BASE_URL + this.$route.params.recordid
          );
          if (res.error) {
            this.formState.serverError = res.error;
            window.$gz.form.setErrorBoxErrors(this);
          } else {
            JUST_DELETED = true;
            this.$router.go(-1);
          }
        }
      } catch (error) {
        window.$gz.errorHandler.handleFormError(error, this);
      } finally {
        window.$gz.form.setFormState({
          vm: this,
          loading: false
        });
      }
    },
    duplicate() {
      this.$router.push({
        name: "subscription-edit",
        params: {
          recordid: 0,
          obj: this.obj
        }
      });
    }
  }
};

/////////////////////////////
//
//
async function clickHandler(menuItem) {
  if (!menuItem) {
    return;
  }
  const 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 "new":
        m.vm.$router.push({
          name: "subscription-edit",
          params: { recordid: 0 }
        });
        break;
      case "duplicate":
        m.vm.duplicate();
        break;
      case "report":
        {
          const res = await m.vm.$refs.reportSelector.open(
            {
              AType: window.$gz.type.Subscription,
              selectedRowIds: [m.vm.obj.id]
            },
            m.id
          );
          if (res == null) {
            return;
          }
          window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
        }
        break;
      case "LicenseList":
        {
          let cName = "Customer";
          const selected = m.vm.$refs.customerId.getFullSelectionValue();
          if (selected != null) {
            cName = selected.name;
          }
          m.vm.$router.push({
            name: "biz-license-list",
            params: {
              aType: window.$gz.type.Customer,
              objectId: m.vm.obj.customerId,
              name: cName
            }
          });
        }
        break;
      case "license":
        {
          if (!m.vm.canDuplicate()) {
            alert("Save this record first");
            return;
          }

          if (m.vm.obj.fetchEmail == null) {
            throw new Error("Email address Required");
          }

          if (m.vm.obj.regTo == null) {
            throw new Error("Registered to Required");
          }

          if (m.vm.obj.pGroup == 0 || m.vm.obj.pGroup == 4) {
            throw new Error("Invalid product group");
          }

          if (m.vm.obj.items.length == 0) {
            throw new Error("No subscription items to license");
          }

          if (
            (m.vm.obj.pGroup == 2 || m.vm.obj.pGroup == 3) &&
            m.vm.obj.dbId == null
          ) {
            throw new Error("DB ID Required");
          }

          const RAVEN_PERPETUAL_PRODUCT_SOCKEYE_ID = 4;
          const RAVEN_SUBSCRIPTION_MONTHLY_PRODUCT_SOCKEYE_ID = 22;
          const RAVEN_SUBSCRIPTION_YEARLY_PRODUCT_SOCKEYE_ID = 24;
          // const PRODUCT_INTERNAL_ID = [
          //   { id: 19, name: "AyaNova Lite ", active: true },
          //   {
          //     id: 4,
          //     name:
          //       "AyaNova perpetual single user  license includes one year maintenance plan ",
          //     active: true
          //   },
          //   { id: 22, name: "AyaNova subscription one user  monthly ", active: true },
          //   { id: 24, name: "AyaNova subscription one user  yearly ", active: true },
          //   { id: 23, name: "Custom 539230073 ", active: true },
          //   { id: 21, name: "Custom 733918243 ", active: true },
          //   { id: 10, name: "Export to  XLS ", active: true },
          //   { id: 11, name: "Importexport.csv duplicate ", active: true },
          //   { id: 14, name: "Key Administration ", active: true },
          //   { id: 13, name: "MBI ", active: true },
          //   { id: 16, name: "OLI ", active: true },
          //   { id: 18, name: "Outlook Schedule Export ", active: true },
          //   { id: 15, name: "PTI  ", active: true },
          //   { id: 8, name: "QBI ", active: true },
          //   { id: 6, name: "QBOI ", active: true },
          //   { id: 5, name: "Quick Notification ", active: true },
          //   { id: 3, name: "RI ", active: true },
          //   { id: 7, name: "Single ", active: true },
          //   { id: 9, name: "Up to 10 ", active: true },
          //   { id: 17, name: "Up to 15 ", active: true },
          // id 25 = up to 25
          //   { id: 12, name: "Up to 20 ", active: true },
          //   { id: 2, name: "Up to 5 ", active: true },
          //   { id: 20, name: "Up to 999 ", active: true },
          //   { id: 1, name: "WBI ", active: true }
          // ];

          //generate license from subscription values here
          //copied from biz-license default record values
          let l = {
            id: 0,
            concurrency: 0,
            created: window.$gz.locale.nowUTC8601String(),
            active: false, //here, active means it's ready for pickup
            customerId: m.vm.obj.customerId,
            pGroup: m.vm.obj.pGroup,
            regTo: m.vm.obj.regTo,
            key: null,
            fetchCode: null,
            fetchEmail: m.vm.obj.fetchEmail,
            fetchedOn: null, //here, non null fetchedOn is read only
            dbId: null,
            licenseExpire: null, //what it is in v8, "lockdate" in v7
            maintenanceExpire: null,
            notificationSent: false,
            wiki: null,
            tags: [],
            trialMode: false,
            renewal: true,
            //dto only props
            customerUsers: 250,
            maxDataGB: 20,
            users: 1,
            wbi: false,
            wbiExpires: null,
            mbi: false,
            mbiExpires: null,
            ri: false,
            riExpires: null,
            qbi: false,
            qbiExpires: null,
            qboi: false,
            qboiExpires: null,
            pti: false,
            ptiExpires: null,
            quickNotification: false,
            quickNotificationExpires: null,
            exportToXLS: false,
            exportToXLSExpires: null,
            outlookSchedule: false,
            outlookScheduleExpires: null,
            oli: false,
            oliExpires: null,
            importExportCSVDuplicate: false,
            importExportCSVDuplicateExpires: null
          };

          /*
    public enum ProductGroup
    {
        Misc = 0,
        AyaNova7 = 1,
        RavenPerpetual = 2,
        RavenSubscription = 3,
        NotSet = 4
    }

*/
          switch (m.vm.obj.pGroup) {
            case 1: //v7
              {
                l.dbId = null;
                l.customerUsers = null;
                l.maxDataGB = null;
                //iterate items
                m.vm.obj.items.forEach(z => {
                  if (z.active) {
                    //----------------
                    switch (z.productId) {
                      case 1: //WBI
                        l.wbi = true;
                        l.wbiExpires = z.expireDate;
                        break;
                      case 2: //Up to 5
                        l.users = 5;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 3: //RI
                        l.ri = true;
                        l.riExpires = z.expireDate;
                        break;
                      case 5: //QuickNotification
                        l.quickNotification = true;
                        l.quickNotificationExpires = z.expireDate;
                        break;
                      case 6: //QBOI
                        l.qboi = true;
                        l.qboiExpires = z.expireDate;
                        break;
                      case 7: //SINGLE
                        l.users = 1;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 8: //QBI
                        l.qbi = true;
                        l.qbiExpires = z.expireDate;
                        break;
                      case 9: //Up to 10
                        l.users = 10;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 10: //EXPORT TO XLS
                        l.exportToXLS = true;
                        l.exportToXLSExpires = z.expireDate;
                        break;
                      case 11: //Import Export CSV Duplicate
                        l.importExportCSVDuplicate = true;
                        l.importExportCSVDuplicateExpires = z.expireDate;
                        break;
                      case 12: //Up to 20
                        l.users = 20;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 13: //MBI
                        l.mbi = true;
                        l.mbiExpires = z.expireDate;
                        break;
                      case 15: //PTI
                        l.pti = true;
                        l.ptiExpires = z.expireDate;
                        break;
                      case 16: //OLI
                        l.oli = true;
                        l.oliExpires = z.expireDate;
                        break;
                      case 17: //Up to 15
                        l.users = 15;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 18: //Outlook schedule export
                        l.outlookSchedule = true;
                        l.outlookScheduleExpires = z.expireDate;
                        break;
                      case 19: //AyaNova Lite (but we coerce it to a single instead as it's deprecated / only one customer)
                        l.users = 1;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 25: //Up to 25 //case 4576
                        l.users = 25;
                        l.maintenanceExpire = z.expireDate;
                        break;
                      case 20: //Up to 999
                        l.users = 999;
                        l.maintenanceExpire = z.expireDate;
                        break;
                    }

                    //----------------
                  }
                });
              }
              break;
            case 2: //Raven perpetual
              {
                l.dbId = m.vm.obj.dbId;
                l.customerUsers = null;
                l.maxDataGB = null;
                //iterate items, count up users and find the furthest future expiry date
                let newestDate = window.$gz.locale.nowUTC8601String();
                let totalUserCount = 0;
                m.vm.obj.items.forEach(z => {
                  if (
                    z.active &&
                    z.productId == RAVEN_PERPETUAL_PRODUCT_SOCKEYE_ID
                  ) {
                    totalUserCount += z.quantity;
                    if (
                      window.$gz.locale.d1IsBeforeD2FromUTC8601String(
                        newestDate,
                        z.expireDate
                      )
                    ) {
                      newestDate = z.expireDate;
                    }
                  }
                });
                l.users = totalUserCount;
                l.maintenanceExpire = newestDate;
              }
              break;
            case 3: //RavenSubscription
              {
                l.dbId = m.vm.obj.dbId;
                l.customerUsers = 250;
                l.maxDataGB = 20;
                //iterate items, count up users and find the furthest future expiry date
                let newestDate = window.$gz.locale.nowUTC8601String();
                let totalUserCount = 0;
                m.vm.obj.items.forEach(z => {
                  if (
                    z.active &&
                    (z.productId ==
                      RAVEN_SUBSCRIPTION_MONTHLY_PRODUCT_SOCKEYE_ID ||
                      z.productId ==
                        RAVEN_SUBSCRIPTION_YEARLY_PRODUCT_SOCKEYE_ID)
                  ) {
                    totalUserCount += z.quantity;
                    if (
                      window.$gz.locale.d1IsBeforeD2FromUTC8601String(
                        newestDate,
                        z.expireDate
                      )
                    ) {
                      newestDate = z.expireDate;
                    }
                  }
                });
                l.users = totalUserCount;
                l.maintenanceExpire = newestDate;
                l.licenseExpire = newestDate;
              }

              break;
          }
          console.log(l);
          m.vm.$router.push({
            name: "license-edit",
            params: {
              recordid: 0,
              obj: l
            }
          });
        }
        break;

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

//////////////////////
//
//
function generateMenu(vm) {
  const menuOptions = {
    isMain: false,
    readOnly: vm.formState.readOnly,
    icon: "$sockiFileContract",
    title: "Subscription",
    formData: {
      sockType: window.$gz.type.Subscription,
      recordId: vm.$route.params.recordid,
      formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
      recordName: vm.obj.subsite
    },
    menuItems: []
  };

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

  menuOptions.menuItems.push({
    title: "Report",
    icon: "$sockiFileAlt",
    key: FORM_KEY + ":report",
    vm: vm
  });

  const lastReport = window.$gz.form.getLastReport(FORM_KEY);
  if (lastReport != null) {
    menuOptions.menuItems.push({
      title: lastReport.name,
      notrans: true,
      icon: "$sockiFileAlt",
      key: FORM_KEY + ":report:" + lastReport.id,
      vm: vm
    });
  }

  if (vm.rights.change) {
    menuOptions.menuItems.push({
      title: "New",
      icon: "$sockiPlus",
      key: FORM_KEY + ":new",
      vm: vm
    });
  }

  if (vm.rights.change && vm.$route.params.recordid != 0) {
    menuOptions.menuItems.push({
      title: "Duplicate",
      icon: "$sockiClone",
      key: FORM_KEY + ":duplicate",
      vm: vm
    });
  }
  if (vm.rights.delete && vm.$route.params.recordid != 0) {
    menuOptions.menuItems.push({
      title: "Delete",
      icon: "$sockiTrashAlt",
      surface: false,
      key: FORM_KEY + ":delete",
      vm: vm
    });
  }
  menuOptions.menuItems.push({ divider: true, inset: false });

  if (vm.rights.change && vm.$route.params.recordid != 0 && vm.canDuplicate()) {
    menuOptions.menuItems.push({
      title: "Generate license",
      notrans: true,
      icon: "$sockiHandHoldingWater",
      key: FORM_KEY + ":license",
      vm: vm
    });
  }

  menuOptions.menuItems.push({
    title: "LicenseList",
    icon: "$sockiGem",
    key: FORM_KEY + ":LicenseList",
    vm: vm
  });

  menuOptions.menuItems.push({ divider: true, inset: false });
  window.$gz.eventBus.$emit("menu-change", menuOptions);
}

let JUST_DELETED = false;

/////////////////////////////////
//
//
async function initForm(vm) {
  await fetchTranslatedText();
  await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY, vm);
  await populateSelectionLists(vm);
}

//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText() {
  await window.$gz.translation.cacheTranslations([
    "Subscription",
    "Customer",
    "ProductGroup",
    "Product",
    "SubSite",
    "ContractNotes",
    "ProductName",
    "PurchaseQuantity",
    "PurchaseExpireDate",
    "SubscriptionItemList",
    "OriginalOrderNumber",
    "OriginalOrderDate",
    "LicenseRegTo",
    "LicenseFetchEmail",
    "DatabaseID",
    "Renewal"
  ]);
}

//////////////////////
//
//
async function populateSelectionLists(vm) {
  //ensure the pick lists required are pre-fetched
  await window.$gz.enums.fetchEnumList("productgroup");
  vm.selectLists.pGroups = window.$gz.enums.getSelectionList("productgroup");
}

//////////////////////
//
//
function addToDate(dateValue, span) {
  let newDate = dateValue;
  if (newDate == null) {
    newDate = window.$gz.locale.addDurationToUTC8601String(
      window.$gz.locale.nowUTC8601String(),
      span
    );
  } else {
    newDate = window.$gz.locale.addDurationToUTC8601String(newDate, span);
  }
  return newDate;
}
</script>
