<template>
  <div>
    <div v-if="!loaded && loading" class="loading-absolute-center" />
    <template v-else>
      <div class="row-history">
        <div v-if="entriesWithContents.length > 0">
          <InfiniteScroll
            ref="infiniteScroll"
            :current-count="currentCount"
            :max-count="totalCount"
            :loading="loading"
            :reverse="true"
            :render-end="false"
            @load-next-page="loadNextPage"
          >
            <template #default>
              <div
                v-for="(entry, index) in entriesWithContents"
                :key="entry.id"
              >
                <div
                  v-if="
                    shouldDisplayDateSeparator(
                      entriesWithContents,
                      'timestamp',
                      index
                    )
                  "
                  class="row-history__day-separator"
                >
                  <span>{{ formatDateSeparator(entry.timestamp) }}</span>
                </div>
                <RowHistoryEntry
                  :entry="entry"
                  :fields="fields"
                  :class="{
                    'row-history-entry--first':
                      index === 0 ||
                      shouldDisplayDateSeparator(
                        entriesWithContents,
                        'timestamp',
                        index - 1
                      ),
                  }"
                >
                </RowHistoryEntry>
              </div>
            </template>
          </InfiniteScroll>
        </div>
        <div v-else class="row-history__empty">
          <i class="row-history__empty-icon baserow-icon-history"></i>
          <div class="row-history__empty-text">
            {{ $t('rowHistorySidebar.empty') }}
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
import {
  shouldDisplayDateSeparator,
  formatDateSeparator,
} from '@baserow/modules/database/utils/date'
import { mapGetters } from 'vuex'
import { notifyIf } from '@baserow/modules/core/utils/error'
import InfiniteScroll from '@baserow/modules/core/components/helpers/InfiniteScroll'
import RowHistoryEntry from '@baserow/modules/database/components/row/RowHistoryEntry.vue'

export default {
  name: 'RowHistorySidebar',
  components: {
    InfiniteScroll,
    RowHistoryEntry,
  },
  props: {
    database: {
      type: Object,
      required: true,
    },
    table: {
      type: Object,
      required: true,
    },
    fields: {
      type: Array,
      required: true,
    },
    row: {
      type: Object,
      required: true,
    },
  },
  computed: {
    ...mapGetters({
      entries: 'rowHistory/getSortedEntries',
      loading: 'rowHistory/getLoading',
      loaded: 'rowHistory/getLoaded',
      currentCount: 'rowHistory/getCurrentCount',
      totalCount: 'rowHistory/getTotalCount',
    }),
    entriesWithContents() {
      const fieldIds = this.fields.map((f) => f.id)
      const entriesToRender = this.entries.filter((entry) => {
        const entryFields = new Set(
          Object.keys(entry.before).concat(Object.keys(entry.after))
        )
        const validEntryFieldIds = entryFields
          .map((fieldIdentifier) => entry.fields_metadata[fieldIdentifier]?.id)
          .filter((entryFieldId) => fieldIds.includes(entryFieldId))
        return validEntryFieldIds.size > 0
      })
      return entriesToRender
    },
  },
  watch: {
    row(newRow, oldRow) {
      this.initialLoad()
    },
  },
  async created() {
    await this.initialLoad()
  },
  methods: {
    async initialLoad() {
      try {
        const tableId = this.table.id
        const rowId = this.row.id

        // If the row is not an integer, it can mean that the row hasn't been created
        // in the backend yet. It's fine to not do anything then, because there is no
        // history available anyway.
        if (Number.isInteger(rowId)) {
          await this.$store.dispatch('rowHistory/fetchInitial', {
            tableId,
            rowId,
          })
        }
      } catch (e) {
        notifyIf(e, 'application')
      }
    },
    async loadNextPage() {
      try {
        const tableId = this.table.id
        const rowId = this.row.id
        await this.$store.dispatch('rowHistory/fetchNextPage', {
          tableId,
          rowId,
        })
      } catch (e) {
        notifyIf(e, 'application')
      }
    },
    shouldDisplayDateSeparator,
    formatDateSeparator,
  },
}
</script>