<!-- Search for events -->

<template>
  <LayoutContainer>
    <!-- Header -->
    <v-row>
      <v-layout>
        <h2 v-if="!hideTitle">
          {{ $t("events") }}
        </h2>
      </v-layout>
    </v-row>

    <!-- Search form -->
    <v-row>
      <v-form method="get" class="mt-8 w100">
        <v-container>
          <v-row>
            <v-col cols="12" md="6" class="py-2 px-1">
              <UiSearchDateRangePicker
                ref="dateSearch"
                v-model="dateRangeFilter"
                :start-label="$t('start_date')"
                :end-label="$t('end_date')"
                preset-label=""
                separator-label="~"
                :presets="dateRangePresets"
                :min="dateRangeMin"
                locale="fr-FR"
                no-title
                display-format="dd/MM/yyyy"
                :inputProps="{outlined: true}"
                :menuProps="{offsetY: true, closeOnContentClick: false}"
                :actionLabels="{apply: $t('apply'), cancel: $t('cancel'), reset: $t('reset')}"
              >
              </UiSearchDateRangePicker>
            </v-col>

            <v-col cols="12" md="6" class="py-2 px-1">
              <UiSearchAddress
                ref="addressSearch"
                type="municipality"
                @change="locationFilterChanged"
              />
            </v-col>

            <v-col cols="12" md="6" class="py-2 px-1">
              <v-text-field
                v-model="textFilter"
                type="text"
                outlined
                clearable
                hide-details
                append-icon="mdi-magnify"
                :label="$t('what') + ' ?'"
                @click:append="search"
                @keydown.enter="search"
              />
            </v-col>
          </v-row>

          <v-row>
            <v-col cols="2" class="py-2 px-1">
              <v-btn class="h100" @click="reinitializeFilters">
                {{ $t('reinitialize') }}
              </v-btn>
            </v-col>
            <v-col cols="2" class="py-2 px-1 d-flex justify-end">
              <v-btn class="h100" @click="test()">
                {{ $t('search') }}
              </v-btn>
            </v-col>
          </v-row>
        </v-container>
      </v-form>
    </v-row>

    <v-row>
      <!-- loading skeleton -->
      <v-container v-if="$fetchState.pending">
        <v-row v-for="i in 3" :key="i" justify="space-between" class="mt-1 mb-3">
          <v-col v-for="j in 2" :key="j" cols="12" :md="12" class="py-2 px-1">
            <v-skeleton-loader type="card" :loading="true" />
          </v-col>
        </v-row>
      </v-container>

      <!-- Results -->
      <v-data-iterator
        v-else
        :items="filteredEvents"
        :page.sync="page"
        :items-per-page="itemsPerPage"
        sort-by="name"
        hide-default-footer
        no-data-text=""
      >
        <template #header>
          <i class="results-count">{{ totalRecords }} {{ $t('results') }}</i>
        </template>
        <template #default="props">
          <v-row justify="space-between" class="mt-1 mb-3">
            <v-col
              v-for="event in props.items"
              :key="event.uuid"
              cols="12"
              sm="12"
              :lg="12"
              class="py-2 px-1"
            >
              <v-card
                elevation="1"
                outlined
                :class="'event-card pa-3 d-flex ' + ($vuetify.breakpoint.smAndDown ? 'flex-column' : 'flex-row align-items-center')"
              >
                <div class="d-flex justify-center max-w100">
                  <v-img
                    v-if="event.imageId"
                    :src="'https://api.opentalent.fr/app.php/_internal/secure/files/' + event.imageId"
                    alt="poster"
                    height="80"
                    width="240"
                    max-height="100%"
                    :contain="true"
                    style="margin: 12px;"
                  />
                  <div v-else style="height: 104px; width: 264px" />
                </div>

                <div class="d-flex flex-column flex-grow-1">
                  <v-card-title class="title">
                    <nuxt-link :to="{path: '/events/' + event.uuid, query: { theme: theme }}">
                      {{ event.name }}
                    </nuxt-link>
                  </v-card-title>

                  <v-card-text class="infos">
                  </v-card-text>
                </div>

                <v-card-actions class="align-self-end">
                  <v-btn
                    class="see"
                    :to="{path: '/event/' + event.uuid, query: { theme: theme, hideTitle: hideTitle }}"
                    nuxt
                  >
                    <span style="margin-right: 6px;">{{ $t("see_more") }}</span>
                    <font-awesome-icon :icon="['fa', 'caret-right']" />
                  </v-btn>
                </v-card-actions>
              </v-card>
            </v-col>
          </v-row>
        </template>
        <template #footer>
          <v-pagination
            v-model="page"
            :length="pageCount"
            total-visible="9"
            color="primary"
          />
        </template>
      </v-data-iterator>
    </v-row>
  </LayoutContainer>
</template>

<script lang="ts">
import Vue from 'vue'
import sphericDistance from '@/services/utils/geo'
import EventsProvider from "~/services/data/EventsProvider"
import { today, todayIso, formatIso } from '@/services/utils/date'
import { addDays, nextSunday, addMonths } from "date-fns";

const defaultDateRange: DateRange = { start: '', end: '' }

export default Vue.extend({
  data () {
    return {
      theme: this.$route.query.theme ?? 'orange',
      hideTitle: this.$route.query.hideTitle === 'true',
      events: [] as Array<PublicEvent>,
      filteredEvents: [] as Array<PublicEvent>,
      loading: true,
      page: 1,
      itemsPerPage: 8,
      textFilter: null as string | null,
      locationFilter: null as Coordinates | null,
      dateRangeFilter: defaultDateRange
    }
  },
  async fetch () {
    await new EventsProvider(this.$axios).getBy().then(
      (res) => {
        this.events = res
        this.filteredEvents = res
      })
  },
  computed: {
    totalRecords (): number {
      return this.filteredEvents.length
    },
    pageCount (): number {
      return Math.floor(this.totalRecords / this.itemsPerPage) + 1
    },
    dateRangeMin(): string {
      return todayIso()
    },
    dateRangePresets(): Array<DateRangePreset> {
      // Today
      const today_preset: DateRangePreset = {
        label: this.$t('today').toString(),
        range: {start: todayIso(), end: todayIso()}
      }

      // Cette semaine
      const week_preset: DateRangePreset = {
        label: this.$t('next_week').toString(),
        range: {start: todayIso(), end: formatIso(addDays(today(), 7))}
      }

      // Ce week-end
      const sunday: Date = nextSunday(today())
      const weekend_preset: DateRangePreset = {
        label: this.$t('next_weekend').toString(),
        range: {start: formatIso(addDays(sunday, -2)), end: formatIso(sunday)}
      }

      // Ce mois
      const month_preset: DateRangePreset = {
        label: this.$t('next_month').toString(),
        range: {start: todayIso(), end: formatIso(addMonths(today(), 1))}
      }

      return [today_preset, week_preset, weekend_preset, month_preset]
    }
  },
  methods: {
    test () {
      console.log(this.dateRangeFilter)
    },
    textFilterChanged (newVal: string) {
      this.textFilter = newVal
    },
    locationFilterChanged (newVal: Coordinates) {
      this.locationFilter = newVal
      this.search()
    },
    dateRangeFilterChanged (newVal: DateRange) {
      this.dateRangeFilter = newVal
      this.search()
    },
    reinitializeFilters (): void {
      this.textFilter = null
      this.locationFilter = null
      this.dateRangeFilter = defaultDateRange
      const addressSearch = this.$refs.addressSearch as any
      addressSearch.clear()
      this.filteredEvents = this.events
    },
    /**
     * Does the event match the current textFilter
     * @param event
     * @returns {boolean}
     */
    matchTextFilter (event: PublicEvent): boolean {
      if (!this.textFilter) { return true }

      return normalize(event.name).includes(normalize(this.textFilter))
    },
    /**
     * Does the event match the current locationFilter
     * @param event
     * @returns {boolean}
     */
    matchLocationFilter (event: PublicEvent): boolean {
      if (!this.locationFilter) { return true }
      if (event.address === null || !event.address.latitude || !event.address.longitude) { return false }

      const radius = 30

      return sphericDistance(
        this.locationFilter.latitude,
        this.locationFilter.longitude,
        event.address.latitude,
        event.address.longitude
      ) <= radius
    },
    /**
     * Does the event match each of the page filters
     * @param event
     * @returns {boolean}
     */
    matchFilters (event: PublicEvent): boolean {
      return this.matchTextFilter(event) &&
        this.matchLocationFilter(event)
    },
    /**
     * Update the filteredEvents array
     */
    search (): void {
      this.filteredEvents = this.events.filter((e) => { return this.matchFilters(e) })
    },
    /**
     * Enhanced filter for v-autocomplete components
     *
     * @param _
     * @param queryText
     * @param itemText
     */
    enhancedAutocompleteFilter (_: any, queryText: string, itemText: string): boolean {
      return normalize(itemText).includes(normalize(queryText))
    }
  }
})
</script>

<style scoped lang="scss">
@import 'assets/style/variables.scss';

h2 {
  color: var(--v-primary-base);
}

.event-card {
  height: 100%;
  color: #666666;
}

.infos .col {
  padding: 6px 12px;
}

.infos td {
  padding: 4px;
  vertical-align: top;
}
.infos td:first-child {
  padding-top: 6px;
  text-align: center;
}

.title {
  word-break: normal;
  color: var(--v-primary-base);
  font-size: 18px;
  font-weight: 500;
  line-height: 1.6rem;
}

.title a {
  text-decoration: none;
}

.icon {
  color: var(--v-primary-base);
}

.results-count {
  font-size: .8em;
  color: #666;
}
</style>
