<template>
  <div id="resourceEdit" class="container">
    <b-row>
      <div class="col-sm-2"></div>
      <div class="col-sm-8">
        <coscine-headline :headline="$t('title')" />
        <controls
          :projectId="projectId"
          :resourceId="resourceId"
          :projectsSelectOptions="projectsSelectOptions"
          :resourcesSelectOptions="resourcesSelectOptions"
          :progressbarOccupied="progressbarOccupied"
          :resource="resource"
          :isLoading="isLoading"
          @changeProject="changeProject"
          @changeResource="changeResource"
        />
        <tab-view
          :resource="resource"
          :resourceId="resourceId"
          :applicationProfile="applicationProfile"
          :isLoading="isLoading"
          :isOwner="isOwner"
          :displayNameIsLocked="displayNameIsLocked"
          :licenses="licenses"
          :disciplines="disciplines"
          :visibilities="visibilities"
          :keywordoptions="keywordoptions"
          :disciplineLabel="disciplineLabel"
          :resourceTypeOptionsLength="resourceTypeOptionsLength"
          @translateResourceNameToDisplayName="
            translateResourceNameToDisplayName
          "
          @addTag="addTag"
          @lockDisplayName="lockDisplayName"
          :isWaitingForResponse="isWaitingForResponse"
          @deleteResource="deleteResource"
        />
        <buttons
          :projectId="projectId"
          :resourceId="resourceId"
          :resource="resource"
          :isWaitingForResponse="isWaitingForResponse"
          :isOwner="isOwner"
          :isLoading="isLoading"
          @updateResource="updateResource"
        />
      </div>
      <div class="col-sm-2"></div>
    </b-row>
    <coscine-loading-spinner :isWaitingForResponse="isWaitingForResponse" />
  </div>
</template>

<script lang="ts">
import Vue from "vue";
import {
  BlobApi,
  ProjectApi,
  ProjectRoleApi,
  ResourceTypeApi,
  MetadataApi,
  ResourceApi,
  VisibilityApi,
  LicenseApi,
  DisciplineApi,
} from "@coscine/api-connection";
import { GuidUtil, LanguageUtil, LinkUtil, FileUtil } from "@coscine/app-util";
import {
  CoscineLoadingSpinner,
  CoscineHeadline,
} from "@coscine/component-library";
import "@coscine/component-library/dist/index.css";

import Buttons from "./components/Buttons.vue";
import Controls from "./components/Controls.vue";
import TabView from "./components/TabView.vue";

function parseKeywords(form: any, delimiter = ";") {
  // combine array values to a string (using the 'keyword' form input)
  if (typeof form.Keywords !== "string") {
    let keywordString = "";
    for (const keyword of form.Keywords) {
      keywordString += keyword + delimiter;
    }
    if (keywordString.charAt(keywordString.length - 1) === delimiter) {
      keywordString = keywordString.substring(0, keywordString.length - 1);
    }
    form.Keywords = keywordString;
  }
}

interface Resource {
  id: string;
  name: string;
  used: any;
  allocated: any;
  maxAvailable: any;
}

export default Vue.extend({
  name: "resourceedit",
  components: {
    CoscineLoadingSpinner,
    CoscineHeadline,
    Buttons,
    Controls,
    TabView,
  },
  data() {
    return {
      resource: {
        ResourceName: "",
        DisplayName: "",
        Description: "",
        PID: "",
        Disciplines: [] as Array<unknown>,
        Keywords: [] as Array<unknown>,
        Visibility: {
          id: "",
          displayName: "",
        },
        License: null,
        UsageRights: "",
        type: {
          id: "",
          displayName: "",
          enabled: true,
        },
        applicationProfile: "",
        fixedValues: {},
        resourceTypeOption: {},
        isArchived: false,
      },
      projectId: "",
      resourceId: "" as any,
      isOwner: false,
      isWaitingForResponse: false,
      isLoading: true,
      applicationProfileList: [] as Array<unknown>,
      applicationProfile: [] as any[],
      selectedResourceTypeInformation: {} as any,
      displayNameIsLocked: false,
      licenses: [] as Array<unknown>,
      disciplines: [] as Array<unknown>,
      visibilities: [] as Array<unknown>,
      keywordoptions: [] as Array<unknown>,
      disciplineLabel: "displayNameEn",
      progressbarOccupied: 0,

      projectInformationHashmap: {} as any,
      resourceHashmap: {} as any,
      resourceInformationHashmap: {} as any,

      projectsSelectOptions: [] as Array<unknown>,
      resourcesSelectOptions: [] as Array<unknown>,

      resources: [] as Resource[],
      resourceTypeOptionsLength: 1,
    };
  },
  methods: {
    setWaitingForResponse(newIsWaitingForResponse: boolean) {
      this.isWaitingForResponse = newIsWaitingForResponse;
    },
    fillForm(data: any) {
      this.resource.isArchived = data.archived;
      this.resource.ResourceName = data.resourceName;
      this.resource.DisplayName = data.displayName;
      this.resource.Description = data.description;
      this.resource.UsageRights = data.usageRights;
      this.resource.Keywords = [] as Array<unknown>;
      const keywords = data.keywords ? data.keywords.split(";") : [];
      this.resource.Keywords = keywords;
      this.resource.Disciplines = [] as Array<unknown>;
      for (const discipline of Object.keys(data.disciplines)) {
        this.resource.Disciplines.push(data.disciplines[discipline]);
      }
      this.resource.Visibility = data.visibility;
      this.resource.PID = data.pid;
      this.resource.License = data.license;
      this.resource.type = data.type;
      this.resource.resourceTypeOption = data.resourceTypeOption;
      this.resource.applicationProfile =
        data.applicationProfile !== null ? data.applicationProfile : "";
      this.resource.fixedValues =
        data.fixedValues !== null ? data.fixedValues : {};
      if ((this.resource.resourceTypeOption as any).Size != null) {
        BlobApi.getQuota(this.resourceId, (responseQuota: any) => {
          this.progressbarOccupied = responseQuota.data.data.usedSizeByte;
        });
      }
      this.$forceUpdate();
      return;
    },
    getResourceTypeOptionsLength(): number {
      if (
        this.resource === undefined ||
        this.resource.resourceTypeOption === undefined
      ) {
        return 0;
      }
      return Object.keys(this.resource.resourceTypeOption).length;
    },
    checkOwnership(projectRoles: any) {
      for (const projectRole in projectRoles) {
        if (projectRoles[projectRole].role.displayName === "Owner") {
          this.isOwner = true;
        }
      }
      if (!this.isOwner && GuidUtil.isValidGuid(this.resourceId)) {
        ResourceApi.isUserResourceCreator(this.resourceId, (response: any) => {
          this.isOwner = response.data.isResourceCreator;
        });
      }
    },
    updateResource() {
      if (!this.isWaitingForResponse) {
        this.isWaitingForResponse = true;
        parseKeywords(this.resource, ";");
        ResourceApi.updateResource(
          this.resourceId,
          this.resource,
          (response: any) => {
            this.isWaitingForResponse = false;
            this.makeToast(
              this.$t("savingResourceSuccessTitle").toString(),
              this.$t("savingResourceSuccessBody").toString()
            );
          },
          (error: any) => {
            this.isWaitingForResponse = false;
            this.makeToast(
              this.$t("savingResourceFailureTitle").toString(),
              this.$t("savingResourceFailureBody").toString(),
              true
            );
          }
        );
      }
    },
    deleteResource() {
      this.isWaitingForResponse = true;
      ResourceApi.deleteResource(
        this.resourceId,
        (response: any) => {
          this.isWaitingForResponse = false;
          this.changeResourceParameter();
          this.changeProject(this.projectId);
          this.resourceId = "";
          this.isLoading = true;
          this.makeToast(
            this.$t("deletingResourceSuccessTitle").toString(),
            this.$t("deletingResourceSuccessBody").toString()
          );
        },
        (error: any) => {
          this.isWaitingForResponse = false;
          this.makeToast(
            this.$t("deletingResourceFailureTitle").toString(),
            this.$t("deletingResourceFailureBody").toString(),
            true
          );
        }
      );
    },
    changeResourceParameter(id = "") {
      if (window.history.pushState) {
        let searchParams = new URLSearchParams(window.location.search);
        searchParams.set("resource_id", id);
        let newurl =
          window.location.protocol +
          "//" +
          window.location.host +
          window.location.pathname;
        if (id !== "") {
          newurl += "?" + searchParams.toString();
        }
        window.history.pushState({ path: newurl }, "", newurl);
      }
    },
    addTag(newTag: any) {
      this.resource.Keywords.push(newTag);
      this.keywordoptions.push(newTag);
    },
    translateResourceNameToDisplayName() {
      if (this.displayNameIsLocked) {
        return;
      }
      if (this.resource.ResourceName.length >= 25) {
        this.resource.DisplayName = this.resource.ResourceName.substring(0, 25);
      } else {
        this.resource.DisplayName = this.resource.ResourceName;
      }
    },
    lockDisplayName() {
      this.displayNameIsLocked = true;
    },
    showConnectionErrorToast() {
      this.makeToast(
        this.$t("connectionErrorTitle").toString(),
        this.$t("connectionErrorBody").toString(),
        true
      );
    },
    changeProject(id: string) {
      if (GuidUtil.isValidGuid(id)) {
        this.projectId = id;
        this.changeResourceParameter();
        ProjectRoleApi.getUserRoles(this.projectId, (response: any) => {
          this.checkOwnership(response.data);
        });
        ProjectApi.getResourcesWithoutAnalyticsLog(
          this.projectId,
          (allResourcesForProject: any) => {
            this.resourcesSelectOptions = [];
            this.resourceInformationHashmap = {};
            allResourcesForProject.data.forEach((element: any) => {
              this.resourcesSelectOptions.push({
                id: element.id,
                name: element.displayName,
              });
              this.resourceInformationHashmap[element.id] = element;
            });
          }
        );
      }
    },
    changeResource(id: string) {
      if (GuidUtil.isValidGuid(id)) {
        this.isLoading = true;
        this.resourceId = id;
        this.changeResourceParameter(id);
        ResourceApi.getResourceInformation(this.resourceId, (response: any) => {
          this.fillForm(response.data);
          this.resourceTypeOptionsLength = this.getResourceTypeOptionsLength();
          MetadataApi.getProfile(
            this.resource.applicationProfile,
            (response: any) => {
              this.applicationProfile = response.data;
              this.isLoading = false;
            }
          );
        });
      } else {
        this.isLoading = false;
      }
    },
    makeToast(givenTitle = "Title", text: any = "Message", error = false) {
      if (error) {
        this.$bvToast.toast(text, {
          title: givenTitle,
          noAutoHide: true,
          variant: "warning",
          toaster: "b-toaster-bottom-right",
        });
      } else {
        this.$bvToast.toast(text, {
          title: givenTitle,
          toaster: "b-toaster-bottom-right",
          noCloseButton: true,
        });
      }
    },
  },
  created() {
    this.projectId = GuidUtil.getProjectId();
    this.resourceId = GuidUtil.getResourceId();

    if (LanguageUtil.getLanguage() === "en") {
      this.disciplineLabel = "displayNameEn";
    } else {
      this.disciplineLabel = "displayNameDe";
    }

    this.isLoading = true;

    ProjectApi.getProjects(
      (response: any) => {
        response.data.forEach((element: any) => {
          this.projectsSelectOptions.push({
            id: element.id,
            name: element.displayName,
          });
          this.projectInformationHashmap[element.id] = element;
        });
        this.changeProject(this.projectId);
        this.changeResource(this.resourceId);
      },
      (error: any) => {
        this.showConnectionErrorToast();
      }
    );

    VisibilityApi.getVisibilities((response: any) => {
      for (const datum of response.data) {
        if (
          this.resource.Visibility.displayName === "" &&
          datum.displayName === "Project Members"
        ) {
          this.resource.Visibility = datum;
        }
        this.visibilities.push({ value: datum, text: datum.displayName });
      }
    });

    DisciplineApi.getDisciplines((response: any) => {
      this.disciplines = [];
      for (const datum of response.data) {
        this.disciplines.push(datum);
      }
    });

    LicenseApi.getLicenses((response: any) => {
      this.licenses = [];
      for (const license of response.data) {
        this.licenses.push({ value: license, text: license.displayName });
      }
      this.licenses.sort((a: any, b: any) =>
        a.text < b.text ? -1 : a.text > b.text ? 1 : 0
      );
    });
  },
});
</script>