<template>
  <v-card v-if="this.formState.ready">
    <v-card-title
      ><v-icon class="mr-3">{{ getIconForPage() }}</v-icon
      >{{ name }}</v-card-title
    >
    <v-row>
      <gz-error :error-box-message="formState.errorBoxMessage"></gz-error>

      <v-col rows="12">
        <template v-if="$route.params.userlog">
          <!-- **** USER LOG ****** -->
          <v-timeline :dense="$vuetify.breakpoint.smAndDown" data-cy="timeLine">
            <v-timeline-item
              v-for="i in obj"
              :key="i.index"
              fill-dot
              :color="getIconColorForEvent(i.event)"
              :icon="getIconForEvent(i.event)"
            >
              <v-card :outlined="$store.state.darkMode">
                <v-card-title>{{ i.name }}</v-card-title>
                <v-card-subtitle
                  >{{ i.date }} - {{ getEventName(i.event) }}</v-card-subtitle
                >
                <v-card-text
                  ><v-icon large class="mr-2">{{
                    getIconForAType(i.aType)
                  }}</v-icon
                  >{{ getNameForType(i.aType) }}
                  <div class="mt-4" v-if="i.textra">{{ i.textra }}</div>
                </v-card-text>
                <v-card-actions>
                  <v-btn text @click="openHistoryOfItem(i)">{{
                    $ay.t("History")
                  }}</v-btn>
                  <v-btn v-if="canOpen(i.aType)" text @click="openItem(i)">{{
                    $ay.t("Open")
                  }}</v-btn>
                </v-card-actions>
              </v-card>
            </v-timeline-item>
          </v-timeline>
        </template>
        <template v-else>
          <!-- **** OBJECT LOG ****** -->
          <v-timeline :dense="$vuetify.breakpoint.smAndDown" data-cy="timeLine">
            <v-timeline-item
              v-for="i in obj"
              :key="i.index"
              fill-dot
              :color="getIconColorForEvent(i.event)"
              :icon="getIconForEvent(i.event)"
            >
              <v-card :outlined="$store.state.darkMode">
                <v-card-title>{{ i.name }}</v-card-title>
                <v-card-subtitle
                  >{{ i.date }} - {{ getEventName(i.event) }}</v-card-subtitle
                >
                <v-card-text
                  ><v-icon large class="mr-2">{{
                    getIconForAType(i.aType)
                  }}</v-icon
                  >{{ getNameForType(i.aType) }}
                  <div class="mt-4" v-if="i.textra">{{ i.textra }}</div>
                </v-card-text>

                <v-card-actions>
                  <v-btn text @click="openHistoryOfItem(i)">{{
                    $ay.t("History")
                  }}</v-btn>
                  <v-btn
                    v-if="canViewUserHistory(i)"
                    text
                    @click="openHistoryOfUser(i)"
                    >{{ $ay.t("Activity") }}</v-btn
                  >
                  <v-btn v-if="canOpenUser" text @click="openItem(i)">{{
                    $ay.t("Open")
                  }}</v-btn>
                </v-card-actions>
              </v-card>
            </v-timeline-item>
          </v-timeline>
        </template>
      </v-col>
      <v-col cols="12">
        <v-btn
          block
          color="primary"
          large
          v-if="moreAvailable"
          text
          @click="getDataFromApi()"
          >{{ $ay.t("More") }}</v-btn
        ></v-col
      >
    </v-row>
  </v-card>
</template>

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

const FORM_KEY = "ay-history";
const API_BASE_URL = "event-log/";
const DEFAULT_EVENTS_PAGE_SIZE = 200;
export default {
  async created() {
    let vm = this;
    try {
      await initForm(vm);

      vm.readOnly = true;
      window.$gz.eventBus.$on("menu-click", clickHandler);
      generateMenu(vm, false);
      await vm.getDataFromApi();
    } catch (err) {
      window.$gz.errorHandler.handleFormError(err, vm);
    } finally {
      vm.formState.ready = true;
    }
  },
  beforeDestroy() {
    window.$gz.eventBus.$off("menu-click", clickHandler);
  },
  data() {
    return {
      obj: [],
      name: null,
      eventTypes: {},
      ayaTypes: {},
      page: -1, //Note this must be -1 at start to work properly
      moreAvailable: false,
      canOpenUser: window.$gz.role.canOpen(window.$gz.type.User),
      formState: {
        ready: false,
        loading: false,
        errorBoxMessage: null,
        appError: null,
        serverError: {}
      }
    };
  },
  methods: {
    openItem(item) {
      if (item.userId) {
        window.$gz.eventBus.$emit("openobject", {
          type: window.$gz.type.User,
          id: item.userId
        });
      } else {
        window.$gz.eventBus.$emit("openobject", {
          type: item.aType,
          id: item.objectId
        });
      }
    },
    openHistoryOfItem(item) {
      if (item.userId) {
        //object log, so open is for user
        //note: this exception is required because in object log there is no item.objecttype
        this.$router.push({
          name: "ay-history",
          params: { ayatype: window.$gz.type.User, recordid: item.userId }
        });
      } else {
        this.$router.push({
          name: "ay-history",
          params: { ayatype: item.aType, recordid: item.objectId }
        });
      }
    },
    canViewUserHistory(objectlogitem) {
      //For object log to decide if view history of user in item is allowed
      //if user has full read role to User or it's themselves then they can
      return (
        this.canOpenUser || this.$store.state.userId == objectlogitem.userId
      );
    },
    openHistoryOfUser(item) {
      this.$router.push({
        name: "ay-history",
        params: {
          ayatype: window.$gz.type.User,
          recordid: item.userId,
          userlog: true
        }
      });
    },
    canOpen(otype) {
      // console.log("Canopen type: ", otype);
      // console.log("Openable:", this.ayaTypes[otype].openableObject);
      // console.log("roleCanOpen", window.$gz.role.canOpen(otype));
      // console.log("Role rights to type:", window.$gz.role.getRights(otype));
      return (
        this.ayaTypes[otype].openableObject && window.$gz.role.canOpen(otype)
      );
    },
    getIconForPage() {
      let vm = this;
      if (vm.$route.params.userlog) {
        return vm.ayaTypes[window.$gz.type.User].icon;
      } else {
        return vm.ayaTypes[vm.$route.params.ayatype].icon;
      }
    },
    getEventName(event) {
      return this.eventTypes[event].name;
    },
    getIconForEvent(event) {
      return this.eventTypes[event].icon;
    },
    getIconForAType(otype) {
      if (otype) {
        //return this.ayaTypes[otype].icon;
        return window.$gz.util.iconForType(otype);
      } else {
        return null;
      }
    },
    getNameForType(otype) {
      if (otype) {
        return this.ayaTypes[otype].name;
      } else {
        return null;
      }
    },
    getIconColorForEvent(event) {
      switch (event) {
        case 0:
          return "red";
        case 1:
        case 10:
          return "green";
        //attachments all purple to distinguish when looking at object's history
        case 4:
        case 5:
        case 6:
        case 11:
          return "indigo";
        case 12: //erase all data
        case 13: //reset serial number
          return "deep-purple";
        default:
          return "primary";
      }
    },
    async getDataFromApi() {
      let vm = this;
      if (vm.formState.loading) {
        return;
      }
      vm.formState.loading = true;
      window.$gz.form.deleteAllErrorBoxErrors(vm);
      let url = null;
      vm.page += 1;
      //path: "/history/:ayatype/:recordid/:userlog?"
      ///event-log/UserLog?UserId=2&Offset=2&Limit=2
      ///event-log/ObjectLog?AyaType=2&AyId=2&Offset=2&Limit=2

      if (vm.$route.params.userlog) {
        url = API_BASE_URL + "userlog?UserId=" + vm.$route.params.recordid;
      } else {
        url =
          API_BASE_URL +
          "objectlog?AyaType=" +
          vm.$route.params.ayatype +
          "&AyId=" +
          vm.$route.params.recordid;
      }
      //paging
      url += "&Offset=" + vm.page * DEFAULT_EVENTS_PAGE_SIZE;
      url += "&limit=" + DEFAULT_EVENTS_PAGE_SIZE;
      try {
        let res = await window.$gz.api.get(url);

        if (res.error) {
          //Not found?
          if (res.error.code == "2010") {
            window.$gz.form.handleObjectNotFound(vm);
          }
          vm.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(vm);
        } else {
          vm.moreAvailable = res.data.events.length == DEFAULT_EVENTS_PAGE_SIZE;
          vm.name = res.data.name;
          let temp = res.data.events;
          let currentEventCount = vm.obj.length;
          let timeZoneName = window.$gz.locale.getResolvedTimeZoneName();
          let languageName = window.$gz.locale.getResolvedLanguage();
          let hour12 = window.$gz.store.state.userOptions.hour12;
          for (let i = 0; i < temp.length; i++) {
            temp[i].date = window.$gz.locale.utcDateToShortDateAndTimeLocalized(
              temp[i].date,
              timeZoneName,
              languageName,
              hour12
            );
            temp[
              i
            ].name = await window.$gz.translation.translateStringWithMultipleKeysAsync(
              temp[i].name
            );

            temp[i].index = currentEventCount + i;
          }

          vm.obj = [...vm.obj, ...temp];

          //Update the form status
          window.$gz.form.setFormState({
            vm: vm,
            dirty: false,
            valid: true,
            loading: false
          });
          //modify the menu as necessary
          //  generateMenu(vm);
        }
      } catch (error) {
        //Update the form status
        window.$gz.form.setFormState({
          vm: vm,
          loading: false
        });
        window.$gz.errorHandler.handleFormError(error, vm);
      }
    }
  }
};

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

//////////////////////
//
//
function generateMenu(vm) {
  let menuOptions = {
    isMain: false,
    icon: "$ayiHistory",
    title: "History",
    helpUrl: "ay-history",
    menuItems: []
  };
  window.$gz.eventBus.$emit("menu-change", menuOptions);
}
/////////////////////////////////
//
//
async function initForm(vm) {
  await fetchTranslatedText(vm);
  await populateAyaTypeList(vm);
  await populateEventTypeList(vm);
}
//////////////////////
//
//
async function populateAyaTypeList(vm) {
  await window.$gz.enums.fetchEnumList("ayatype");
  let ayt = window.$gz.enums.getSelectionList("ayatype");
  let temp = {};
  for (let i = 0; i < ayt.length; i++) {
    let item = ayt[i];
    let openableObject = false;
    //CoreBizObject add here
    //todo: centralize this if reuqired one more time anywhere
    switch (item.id) {
      //default to can open and only have exceptions because most stuff can be opened
      case window.$gz.type.NoType:
      case window.$gz.type.DashboardView:
        openableObject = false;
        break;
      default:
        openableObject = true;
    }
    temp[item.id] = {
      name: item.name,
      openableObject: openableObject
    };
  }
  vm.ayaTypes = temp;
}

/////////////////////////////////
//
//
function populateEventTypeList(vm) {
  vm.eventTypes = {
    0: { name: vm.$ay.t("EventDeleted"), icon: "$ayiTrashAlt" },
    1: { name: vm.$ay.t("EventCreated"), icon: "$ayiPlus" },
    2: {
      name: vm.$ay.t("EventRetrieved"),
      icon: "$ayiEnvelopeOpenText"
    },
    3: { name: vm.$ay.t("EventModified"), icon: "$ayiSave" },
    4: {
      name: vm.$ay.t("EventAttachmentCreate"),
      icon: "$ayiPlus"
    },
    5: {
      name: vm.$ay.t("EventAttachmentDelete"),
      icon: "$ayiTrashAlt"
    },
    6: {
      name: vm.$ay.t("EventAttachmentDownload"),
      icon: "$ayiFileDownload"
    },
    7: {
      name: vm.$ay.t("EventLicenseFetch"),
      icon: "$ayiTicket"
    },
    8: {
      name: vm.$ay.t("EventLicenseTrialRequest"),
      icon: "$ayiRocket"
    },
    9: {
      name: vm.$ay.t("EventServerStateChange"),
      icon: "$ayiPlus"
    },
    10: { name: vm.$ay.t("EventSeedDatabase"), icon: "$ayiPlus" },
    11: { name: vm.$ay.t("EventAttachmentModified"), icon: "$ayiSave" },
    12: { name: "ERASE ALL DATA", icon: "$ayiSeedling" },
    13: { name: vm.$ay.t("EventResetSerial"), icon: "$ayiEgg" },
    13: {
      name: vm.$ay.t("EventUtilityFileDownload"),
      icon: "$ayiFileDownload"
    }
  };
}

//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
  await window.$gz.translation.cacheTranslations([
    "EventDeleted",
    "EventCreated",
    "EventRetrieved",
    "EventModified",
    "EventAttachmentCreate",
    "EventAttachmentDelete",
    "EventAttachmentDownload",
    "EventAttachmentModified",
    "EventLicenseFetch",
    "EventLicenseTrialRequest",
    "EventServerStateChange",
    "EventSeedDatabase",
    "EventResetSerial",
    "EventUtilityFileDownload",
    "Activity"
  ]);
}
</script>
