<template>
  <!-- Show user source list -->
  <div
    v-if="!showCreateForm && editedUserSource === null"
    class="user-sources-settings"
  >
    <h2 class="box__title">{{ $t('userSourceSettings.titleOverview') }}</h2>
    <Error :error="error"></Error>
    <div v-if="!error.visible" class="actions actions--right">
      <Button prepend-icon="baserow-icon-plus" @click="showForm()">
        {{ $t('userSourceSettings.addUserSource') }}
      </Button>
    </div>
    <div
      v-if="$fetchState.pending && !error.visible"
      class="user-source-settings__loader"
    />
    <template v-else>
      <div
        v-for="userSource in userSources"
        :key="userSource.id"
        class="user-source-settings__user-source"
        @delete="deleteUserSource(userSource)"
      >
        <Presentation
          :image="getUserSourceType(userSource).image"
          :title="userSource.name"
          :subtitle="getUserSourceType(userSource).getSummary(userSource)"
          avatar-color="ghost"
          style="flex: 1"
        />
        <div class="user-source-settings__user-source-actions">
          <Button
            icon="iconoir-edit"
            type="light"
            @click="showForm(userSource)"
          />
          <Button
            icon="iconoir-trash"
            type="light"
            @click="deleteUserSource(userSource)"
          />
        </div>
      </div>
    </template>
    <p
      v-if="!error.visible && !$fetchState.pending && userSources.length === 0"
      class="margin-top-3"
    >
      {{ $t('userSourceSettings.noUserSourceMessage') }}
    </p>
  </div>
  <!-- Edit user source -->
  <div v-else-if="editedUserSource">
    <h2 class="box__title">
      {{ $t('userSourceSettings.titleUpdateUserSource') }}
    </h2>
    <Error :error="error"></Error>

    <Presentation
      :image="getUserSourceType(editedUserSource).image"
      :title="getUserSourceType(editedUserSource).name"
      avatar-color="ghost"
      style="flex: 1; margin-bottom: 18px"
      icon-size="tiny"
    />

    <UpdateUserSourceForm
      ref="userSourceForm"
      :builder="builder"
      :integrations="integrations"
      :user-source-type="getUserSourceType(editedUserSource)"
      :default-values="editedUserSource"
      @submitted="updateUserSource"
      @values-changed="onValueChange"
    />
    <div class="actions">
      <Button
        type="link"
        prepend-icon="iconoir-nav-arrow-left"
        @click="editedUserSource = null"
      >
        {{ $t('action.back') }}
      </Button>
      <Button
        :disabled="actionInProgress || invalidForm"
        :loading="actionInProgress"
        size="large"
        @click="$refs.userSourceForm.submit()"
      >
        {{ $t('action.save') }}
      </Button>
    </div>
  </div>
  <!-- Create user source -->
  <div v-else>
    <h2 class="box__title">
      {{ $t('userSourceSettings.titleAddUserSource') }}
    </h2>
    <Error :error="error"></Error>
    <CreateUserSourceForm
      ref="userSourceForm"
      :builder="builder"
      :integrations="integrations"
      @submitted="createUserSource"
      @values-changed="onValueChange"
    />
    <div class="actions">
      <Button
        type="link"
        prepend-icon="iconoir-nav-arrow-left"
        @click="hideForm"
      >
        {{ $t('action.back') }}
      </Button>
      <Button
        :disabled="actionInProgress || invalidForm"
        :loading="actionInProgress"
        size="large"
        @click="$refs.userSourceForm.submit()"
      >
        {{ $t('action.create') }}
      </Button>
    </div>
  </div>
</template>

<script>
import { mapActions, mapGetters } from 'vuex'
import error from '@baserow/modules/core/mixins/error'
import { clone } from '@baserow/modules/core/utils/object'
import { notifyIf } from '@baserow/modules/core/utils/error'
import CreateUserSourceForm from '@baserow/modules/builder/components/userSource/CreateUserSourceForm'
import UpdateUserSourceForm from '@baserow/modules/builder/components/userSource/UpdateUserSourceForm'

export default {
  name: 'UserSourceSettings',
  components: { CreateUserSourceForm, UpdateUserSourceForm },
  mixins: [error],
  props: {
    builder: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      showCreateForm: false,
      editedUserSource: null,
      actionInProgress: false,
      invalidForm: false,
    }
  },
  async fetch() {
    try {
      await this.actionFetchIntegrations({ applicationId: this.builder.id })
      await this.actionFetchUserSources({ applicationId: this.builder.id })
      this.hideError()
    } catch (error) {
      this.handleError(error)
    }
  },
  computed: {
    ...mapGetters({
      userSources: 'userSource/getUserSources',
      integrations: 'integration/getIntegrations',
    }),
    userSourceTypes() {
      return this.$registry.getAll('userSource')
    },
  },
  methods: {
    ...mapActions({
      actionFetchIntegrations: 'integration/fetch',
      actionFetchUserSources: 'userSource/fetch',
      actionCreateUserSource: 'userSource/create',
      actionUpdateUserSource: 'userSource/update',
      actionDeleteUserSource: 'userSource/delete',
    }),
    getUserSourceType(userSource) {
      return this.$registry.get('userSource', userSource.type)
    },
    onValueChange() {
      this.invalidForm = !this.$refs.userSourceForm.isFormValid()
    },
    async showForm(userSourceToEdit) {
      if (userSourceToEdit) {
        this.editedUserSource = userSourceToEdit
      } else {
        this.showCreateForm = true
      }
      await this.$nextTick()
      this.onValueChange()
    },
    hideForm() {
      this.showCreateForm = false
      this.editedUserSource = null
      this.hideError()
      this.invalidForm = false
    },
    async createUserSource(values) {
      this.actionInProgress = true
      const { type, ...rest } = values
      try {
        const createdUserSource = await this.actionCreateUserSource({
          applicationId: this.builder.id,
          userSourceType: type,
          values: rest,
        })

        this.hideForm()
        // immediately select this user source to edit it.
        this.editedUserSource = createdUserSource
      } catch (error) {
        this.handleError(error)
      }
      this.actionInProgress = false
    },
    async updateUserSource(newValues) {
      this.actionInProgress = true
      try {
        await this.actionUpdateUserSource({
          page: this.page,
          userSourceId: this.editedUserSource.id,
          values: clone(newValues),
        })
        this.hideForm()
      } catch (error) {
        // Restore the previously saved values from the store
        this.$refs.userSourceForm.reset()
        this.handleError(error)
      }
      this.actionInProgress = false
    },
    async deleteUserSource(userSource) {
      try {
        await this.actionDeleteUserSource({ userSourceId: userSource.id })
      } catch (error) {
        notifyIf(error)
      }
    },
  },
}
</script>