<template>
  <v-card :id="spaceMenuParentId" class="spaceCardItem d-block d-sm-flex" flat>
    <v-img
      :src="spaceBannerUrl"
      transition="none"
      height="80px"
      min-height="80px"
      max-height="80px"
      min-width="100%"
      class="white--text align-start d-block spaceBannerImg"
      eager>
    </v-img>

    <div class="spaceToolbarIcons px-2">
      <v-btn
        :title="$t('spaceList.label.openSpaceInfo')"
        icon
        small
        class="spaceInfoIcon d-flex"
        @click="$emit('flip')">
        <v-icon size="12">fa-info</v-icon>
      </v-btn>
      <v-spacer />
      <template v-if="canUseActionsMenu">
        <v-btn
          v-if="space.canEdit"
          :title="$t('spaceList.label.openSpaceActionMenu')"
          icon
          text
          class="spaceActionIcon spaceEditIcon d-none"
          @click="editSpace">
          <i class="uiIcon uiIconEdit" />
        </v-btn>
        <v-btn
          :title="$t('spaceList.label.openSpaceMenu')"
          icon
          text
          class="spaceMenuIcon d-block"
          @click="displayActionMenu = true">
          <v-icon size="21">mdi-dots-vertical</v-icon>
        </v-btn>
        <v-menu
          ref="actionMenu"
          v-model="displayActionMenu"
          :attach="`#${spaceMenuParentId}`"
          transition="slide-x-reverse-transition"
          content-class="spaceActionMenu"
          offset-y>
          <v-list class="pa-0" dense>
            <template v-if="space.canEdit">
              <v-list-item @click="editSpace">
                <v-list-item-title class="subtitle-2">
                  <i class="uiIcon uiIconEdit" />
                  {{ $t('spacesList.button.edit') }}
                </v-list-item-title>
              </v-list-item>
              <v-list-item @click="removeSpaceConfirm">
                <v-list-item-title class="subtitle-2">
                  <i class="uiIcon uiIconTrash" />
                  {{ $t('spacesList.button.remove') }}
                </v-list-item-title>
              </v-list-item>
            </template>
            <v-list-item
              v-for="(extension, i) in enabledProfileActionExtensions"
              :key="i"
              @click="extension.click(space)">
              <v-list-item-title>
                <i :class="extension.icon ? extension.icon : 'hidden'" class="uiIcon " />
                {{ extension.title }}
              </v-list-item-title>
            </v-list-item>
          </v-list>
        </v-menu>
      </template>
    </div>

    <div class="spaceAvatar">
      <a :href="url">
        <v-img
          :src="spaceAvatarUrl"
          transition="none"
          class="mx-auto"
          height="75px"
          width="75px"
          max-height="75px"
          max-width="75px"
          eager>
        </v-img>
      </a>
    </div>

    <v-card-text class="spaceCardBody align-center pt-2 pb-1">
      <a
        :href="url"
        :title="space.displayName"
        class="spaceDisplayName text-truncate d-block">
        {{ space.displayName }}
      </a>
      <v-card-subtitle
        class="spaceMembersLabel py-0">
        {{ $t('spacesList.label.members', {0: space.membersCount}) }}
      </v-card-subtitle>
    </v-card-text>

    <v-card-actions class="spaceCardActions">
      <exo-confirm-dialog
        ref="confirmDialog"
        :title="confirmTitle"
        :message="confirmMessage"
        :ok-label="$t('spacesList.label.ok')"
        :cancel-label="okMethod && $t('spacesList.label.cancel')"
        @ok="okConfirmDialog"
        @dialog-closed="closeConfirmDialog" />
      <v-btn
        v-if="space.isMember"
        :loading="sendingAction"
        :disabled="sendingAction || space.isUserBound"
        class="btn mx-auto spaceMembershipButton leaveSpaceButton"
        depressed
        block
        @click="leaveConfirm">
        <v-icon>mdi-minus</v-icon>
        <span class="spaceMembershipButtonText d-inline">
          {{ $t('spacesList.button.leave') }}
        </span>
      </v-btn>
      <div v-else-if="space.isInvited" class="invitationButtons">
        <div class="acceptToJoinSpaceButtonParent">
          <v-btn
            :loading="sendingAction"
            :disabled="sendingAction"
            class="btn mx-auto spaceMembershipButton acceptToJoinSpaceButton"
            depressed
            @click="acceptToJoin">
            <v-icon>mdi-check</v-icon>
            <span class="d-flex">
              {{ $t('spacesList.button.acceptToJoin') }}
            </span>
          </v-btn>
          <v-btn
            class="btn spaceButtonMenu d-inline"
            depressed
            x-small
            @click="displaySecondButton = !displaySecondButton">
            <v-icon>mdi-menu-down</v-icon>
          </v-btn>
        </div>
        <v-btn
          v-show="displaySecondButton"
          :loading="sendingSecondAction"
          :disabled="sendingSecondAction"
          class="btn mx-auto spaceMembershipButton refuseToJoinSpaceButton"
          depressed
          block
          @click="refuseToJoin">
          <v-icon>mdi-close</v-icon>
          <span class="d-flex">
            {{ $t('spacesList.button.refuseToJoin') }}
          </span>
        </v-btn>
      </div>
      <v-btn
        v-else-if="space.isPending"
        :loading="sendingAction"
        :disabled="sendingAction"
        class="btn mx-auto spaceMembershipButton cancelRequestToJoinSpaceButton"
        depressed
        block
        @click="cancelRequest">
        <v-icon>mdi-close</v-icon>
        <span class="spaceMembershipButtonText d-inline">
          {{ $t('spacesList.button.cancelRequest') }}
        </span>
      </v-btn>
      <v-btn
        v-else-if="space.subscription === 'open'"
        :loading="sendingAction"
        :disabled="sendingAction"
        class="btn mx-auto spaceMembershipButton joinSpaceButton"
        depressed
        block
        @click="join">
        <v-icon>mdi-plus</v-icon>
        <span class="spaceMembershipButtonText d-inline">
          {{ $t('spacesList.button.join') }}
        </span>
      </v-btn>
      <v-btn
        v-else-if="space.subscription === 'validation'"
        :loading="sendingAction"
        :disabled="sendingAction"
        class="btn mx-auto spaceMembershipButton joinSpaceButton"
        depressed
        block
        @click="requestJoin">
        <v-icon>mdi-plus</v-icon>
        <span class="spaceMembershipButtonText d-inline">
          {{ $t('spacesList.button.requestJoin') }}
        </span>
      </v-btn>
      <div
        v-else
        :title="$t('spacesList.label.closedSpace')"
        class="joinSpaceDisabledLabel">
        <v-btn
          disabled
          class="btn mx-auto spaceMembershipButton joinSpaceButton"
          depressed
          block
          @click="join">
          <v-icon>mdi-plus</v-icon>
          <span class="spaceMembershipButtonText d-inline">
            {{ $t('spacesList.button.join') }}
          </span>
        </v-btn>
      </div>
    </v-card-actions>
  </v-card>
</template>

<script>
export default {
  props: {
    space: {
      type: Object,
      default: null,
    },
    profileActionExtensions: {
      type: Array,
      default: () => [],
    },
  },
  data: () => ({
    displayActionMenu: false,
    waitTimeUntilCloseMenu: 200,
    sendingAction: false,
    sendingSecondAction: false,
    confirmTitle: '',
    confirmMessage: '',
    okMethod: null,
    displaySecondButton: false,
  }),
  computed: {
    spaceAvatarUrl() {
      return this.space && (this.space.avatarUrl || `/portal/rest/v1/social/spaces/${this.space.prettyName}/avatar`);
    },
    spaceBannerUrl() {
      return this.space && (this.space.bannerUrl || `/portal/rest/v1/social/spaces/${this.space.prettyName}/banner`);
    },
    spaceMenuParentId() {
      return this.space && this.space.id && `spaceMenuParent-${this.space.id}` || 'spaceMenuParent';
    },
    enabledProfileActionExtensions() {
      if (!this.profileActionExtensions || !this.space || !this.space.isMember) {
        return [];
      }
      return this.profileActionExtensions.slice().filter(extension => extension.enabled(this.space) === true);
    },
    canUseActionsMenu() {
      return this.space && (this.space.canEdit || this.enabledProfileActionExtensions.length);
    },
    url() {
      if (this.space && this.space.groupId) {
        const uriPart = this.space.groupId.replace(/\//g, ':');
        return `${eXo.env.portal.context}/g/${uriPart}/`;
      } else {
        return '#';
      }
    },
  },
  watch: {
    enabledProfileActionExtensions: {
      // immediate option to trigger the callback immediately with watched property initialisation
      immediate: true,
      handler() {
        // watch extensions that have an enabled() async function
        this.asyncFilter(this.profileActionExtensions, extension => extension.enabled(this.space)).then(extensions => {
          extensions.forEach(extension => {
            if (!this.enabledProfileActionExtensions.some(enabledExtension => enabledExtension.name === extension.name)) {
              this.enabledProfileActionExtensions.push(extension);
            }
          });
        }); 
      }
    }
  },
  created() {
    $(document).on('mousedown', () => {
      if (this.displayActionMenu) {
        window.setTimeout(() => {
          this.displayActionMenu = false;
          this.displaySecondButton = false;
        }, this.waitTimeUntilCloseMenu);
      }
    });
  },
  methods: {
    editSpace() {
      this.$root.$emit('editSpace', this.space);
    },
    removeSpaceConfirm() {
      this.openConfirmDialog(
        this.$t('spacesList.title.deleteSpace'),
        this.$t('spacesList.message.deleteSpace'),
        this.removeSpace);
    },
    removeSpace() {
      this.sendingAction = true;
      this.$spaceService.removeSpace(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingAction = false;
        });
    },
    leaveConfirm() {
      const isOnlyManagrLeftInSpace = this.space.isManager && this.space.managersCount <= 1;
      if (isOnlyManagrLeftInSpace) {
        this.openConfirmDialog(
          this.$t('spacesList.warning'),
          this.$t('spacesList.warning.lastManager'));
      } else {
        this.openConfirmDialog(
          this.$t('spacesList.title.leaveSpace'),
          this.$t('spacesList.message.leaveSpace', {0: `<b>${this.space.displayName}</b>`}),
          this.leave);
      }
    },
    leave() {
      this.sendingAction = true;
      this.$spaceService.leave(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingAction = false;
        });
    },
    acceptToJoin() {
      this.sendingAction = true;
      this.$spaceService.accept(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingAction = false;
        });
    },
    refuseToJoin() {
      this.sendingSecondAction = true;
      this.$spaceService.deny(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingSecondAction = false;
        });
    },
    join() {
      this.sendingAction = true;
      this.$spaceService.join(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingAction = false;
        });
    },
    requestJoin() {
      this.sendingAction = true;
      this.$spaceService.requestJoin(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingAction = false;
        });
    },
    cancelRequest() {
      this.sendingAction = true;
      this.$spaceService.cancel(this.space.id)
        .then(() => this.$emit('refresh'))
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('Error processing action', e);
        })
        .finally(() => {
          this.sendingAction = false;
        });
    },
    openConfirmDialog(title, message, okMethod) {
      this.confirmTitle = title;
      this.confirmMessage = message;
      if (okMethod) {
        this.okMethod = okMethod;
      } else {
        this.okMethod = null;
      }
      this.$refs.confirmDialog.open();
    },
    okConfirmDialog() {
      if (this.okMethod) {
        this.okMethod();
      }
    },
    closeConfirmDialog() {
      this.confirmTitle = '';
      this.confirmMessage = '';
      this.okMethod = null;
    },
    async asyncFilter(array, predicate) {
      const results = await Promise.all(array.map(predicate));
      return array.filter((value, index) => results[index]);
    },
  },
};
</script>

