<!-- Search for member structures -->

<template>
  <LayoutContainer class="map-view">
    <!-- Header -->
    <v-row>
      <v-layout>
        <h2 class="flex">
          {{ $t("member_companies") }}
        </h2>
        <v-btn-toggle mandatory dense @change="viewChanged">
          <v-btn>
            {{ $t("map") }}
          </v-btn>
          <v-btn>
            {{ $t("list") }}
          </v-btn>
        </v-btn-toggle>
      </v-layout>
    </v-row>

    <v-row>
      <!-- Map Column (hidden in 'list-view' mode)-->
      <v-col v-show="mapview" cols="6">
        <UiMapStructures
          ref="map"
          :structures="filteredStructures"
          @boundsUpdated="mapBoundsFilterChanged"
        />
      </v-col>

      <!-- Results column -->
      <v-col :cols="mapview ? 6 : 12">
        <!-- Search form -->
        <v-row>
          <v-form method="get" class="mt-8 w100">
            <v-container>
              <v-row>
                <v-col cols="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-col cols="6" class="py-2 px-1">
                  <UiSearchAddress
                    ref="addressSearch"
                    type="municipality"
                    @change="locationFilterChanged"
                  />
                </v-col>
              </v-row>

              <v-row>
                <v-col v-if="listview" cols="2" class="py-2 px-1">
                  <v-btn class="h100" @click="reinitializeFilters">
                    {{ $t('reinitialize') }}
                  </v-btn>
                </v-col>
                <v-col :cols="listview ? 8 : 12">
                  <v-row class="filters">
                    <v-col :cols="3" class="py-2 px-1">
                      <v-select
                        v-model="practicesFilter"
                        :label="$t('type')"
                        :items="translatedPractices"
                        item-value="id"
                        item-text="label"
                        filled
                        hide-details
                        @change="search"
                      />
                    </v-col>
                    <v-col :cols="3" class="py-2 px-1">
                      <v-select
                        v-model="departmentFilter"
                        :items="departments"
                        item-value="code"
                        item-text="label"
                        :label="$t('department')"
                        filled
                        hide-details
                        @change="search"
                      />
                    </v-col>
                    <v-col :cols="3" class="py-2 px-1">
                      <v-select
                        v-model="federationFilter"
                        :items="federations"
                        item-value="id"
                        item-text="name"
                        :label="$t('federation')"
                        filled
                        hide-details
                        @change="search"
                      />
                    </v-col>
                    <v-col :cols="3" class="py-2 px-1">
                      <v-select
                        v-model="distanceFilter"
                        :label="$t('distance')"
                        :items="[
                          {distance: 10, label: '10km'},
                          {distance: 30, label: '30km'},
                          {distance: 100, label: '100km'},
                          {distance: 200, label: '200km'}
                        ]"
                        item-value="distance"
                        item-text="label"
                        filled
                        hide-details
                        @change="search"
                      />
                    </v-col>
                  </v-row>
                </v-col>
                <v-col v-if="listview" cols="2" class="py-2 px-1 d-flex justify-end">
                  <v-btn class="h100">
                    {{ $t('search') }}
                  </v-btn>
                </v-col>
              </v-row>

              <v-row v-show="mapview" class="px-2 pt-2">
                <v-btn @click="reinitializeFilters">
                  {{ $t('reinitialize') }}
                </v-btn>
                <v-spacer />
                <v-btn @click="search">
                  {{ $t('search') }}
                </v-btn>
              </v-row>
            </v-container>
          </v-form>
        </v-row>

        <!-- loading skeleton -->
        <div class="pt-4 mt-6">
          <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"
                sm="12"
                :md="mapview ? 6 : 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="onMapFilteredStructures"
            :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="structure in props.items"
                  :key="structure.name"
                  cols="12"
                  sm="12"
                  :md="mapview ? 6 : 12"
                  class="py-2 px-1"
                >
                  <v-card
                    elevation="1"
                    outlined
                    :class="'structure-card pa-3 d-flex ' + (mapview ? 'flex-column' : 'flex-row align-items-center')"
                  >
                    <div class="d-flex justify-center">
                      <v-img
                        :src="structure.logoId ? ('https://api.opentalent.fr/app.php/_internal/secure/files/' + structure.logoId) : '/images/default.jpg'"
                        alt="poster"
                        height="80px"
                        min-width="160px"
                        max-width="80%"
                        max-height="100%"
                        :contain="true"
                        style="margin: 12px;"
                      />
                    </div>

                    <div class="d-flex flex-column">
                      <v-chip-group v-if="structure.practices" active-class="primary--text">
                        <v-chip v-for="practice in structure.practices" :key="practice" outlined small pill>
                          {{ $t(practice) }}
                        </v-chip>
                      </v-chip-group>

                      <v-card-title class="title">
                        {{ structure.name }}
                      </v-card-title>

                      <v-card-text class="infos">
                        <table>
                          <tr>
                            <td class="py-1 pr-2">
                              <font-awesome-icon class="icon" :icon="['fas', 'map-marker-alt']" />
                            </td>
                            <td class="py-1">
                              {{ structure.address }}
                            </td>
                          </tr>
                          <tr>
                            <td class="py-1 pr-2">
                              <font-awesome-icon class="icon" :icon="['fas', 'project-diagram']" />
                            </td>
                            <td class="py-1">
                              {{ structure.n1Name }}
                            </td>
                          </tr>
                        </table>
                      </v-card-text>
                    </div>
                    <span class="flex-fill" />

                    <v-card-actions :class="listview ? 'align-self-end' : ''">
                      <v-btn class="see" :to="'/structures/' + structure.id" 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="#e4611b"
              />
            </template>
          </v-data-iterator>
        </div>
      </v-col>
    </v-row>
  </LayoutContainer>
</template>

<script>
import departments from '@/enums/departments'
import practices from '@/enums/practices'
import sphericDistance from '@/lib/geo'

export default {
  data () {
    return {
      structures: [],
      filteredStructures: [],
      federations: [],
      loading: true,
      page: 1,
      itemsPerPage: 8,
      mapview: true,
      departments,
      practices,
      textFilter: '',
      locationFilter: null,
      practicesFilter: null,
      departmentFilter: null,
      federationFilter: null,
      distanceFilter: null,
      mapBoundsFilter: null,
      mapBoundsFilterStarted: false // map bounds filter is only activated when the map bounds are updated
    }
  },
  async fetch () {
    await fetch(
      `${this.$config.baseURL}/api/public/federation_structures/all`
    ).then(
      res => res.json()
    ).then(
      res => res.map((s) => {
        s.n1Id = s.n1Id ? parseInt(s.n1Id) : null
        s.n2Id = s.n2Id ? parseInt(s.n2Id) : null
        s.n3Id = s.n3Id ? parseInt(s.n3Id) : null
        s.n4Id = s.n4Id ? parseInt(s.n4Id) : null
        s.n5Id = s.n5Id ? parseInt(s.n5Id) : null
        s.practices = s.practices !== null ? s.practices.split(',') : []
        s.latitude = s.latitude ? parseFloat(s.latitude) : null
        s.longitude = s.longitude ? parseFloat(s.longitude) : null
        s.address = [s.streetAddress, s.postalCode, s.addressCity].join(' ')
        return s
      })
    ).then((res) => {
      this.structures = res
      this.filteredStructures = res

      // populate federations filter
      for (const s of res) {
        const f = {
          id: s.n1Id,
          name: s.n1Name
        }
        if (!this.federations.includes(f)) {
          this.federations.push(f)
        }
      }
    })
  },
  computed: {
    totalRecords () {
      return this.onMapFilteredStructures.length
    },
    pageCount () {
      return Math.floor(this.totalRecords / this.itemsPerPage) + 1
    },
    listview () {
      return !this.mapview
    },
    translatedPractices () {
      const tPractices = []
      for (const practice of this.practices) {
        tPractices.push({ id: practice.id, label: this.$t(practice.id) })
      }
      return tPractices
    },
    onMapFilteredStructures () {
      if (this.mapBoundsFilterStarted) {
        return this.filteredStructures.filter((s) => {
          return this.matchMapBounds(s)
        })
      } else {
        return this.filteredStructures
      }
    }
  },
  methods: {
    viewChanged (e) {
      this.mapview = (e === 0)
    },
    textFilterChanged (newVal) {
      this.textFilter = newVal
    },
    locationFilterChanged (newVal) {
      this.locationFilter = newVal
      if (this.distanceFilter === null) {
        this.distanceFilter = 10
      }
      this.search()
    },
    fitMapToResults () {
      this.$refs.map.zoomOnResults()
    },
    mapBoundsFilterChanged (newBounds) {
      this.mapBoundsFilterStarted = true
      this.mapBoundsFilter = newBounds
    },
    reinitializeFilters () {
      this.textFilter = null
      this.locationFilter = null
      this.practicesFilter = null
      this.departmentFilter = null
      this.federationFilter = null
      this.distanceFilter = null
      this.mapBoundsFilter = null
      this.$refs.addressSearch.clear()
      this.$refs.map.resetBounds()
      this.filteredStructures = this.structures
    },
    /**
     * Does the structure match the current textFilter
     * @param structure
     * @returns {boolean}
     */
    matchTextFilter (structure) {
      if (!this.textFilter) { return true }

      return structure.name.toLowerCase().includes(this.textFilter.toLowerCase())
    },
    /**
     * Does the structure match the current locationFilter
     * @param structure
     * @returns {boolean}
     */
    matchLocationFilter (structure) {
      if (!this.locationFilter) { return true }
      if (!structure.latitude || !structure.longitude) { return false }

      const radius = Number(this.distanceFilter) ?? 5

      return sphericDistance(
        this.locationFilter.latitude, this.locationFilter.longitude, structure.latitude, structure.longitude
      ) <= radius
    },
    /**
     * Does the structure match the current practicesFilter
     * @param structure
     * @returns {boolean}
     */
    matchPracticesFilter (structure) {
      if (!this.practicesFilter) { return true }
      return structure.practices && structure.practices.includes(this.practicesFilter)
    },
    /**
     * Does the structure match the current departmentFilter
     * @param structure
     * @returns {boolean}
     */
    matchDepartmentFilter (structure) {
      if (!this.departmentFilter) { return true }
      return structure.postalCode.startsWith(this.departmentFilter)
    },
    /**
     * Does the structure match the current federationFilter
     * @param structure
     * @returns {boolean}
     */
    matchFederationFilter (structure) {
      if (!this.federationFilter) { return true }
      return structure.parents.includes(Number(this.federationFilter))
    },
    /**
     * Does the structure match the current federationFilter
     * @param structure
     * @returns {boolean}
     */
    matchMapBounds (structure) {
      if (!this.mapBoundsFilter) { return true }
      return this.mapBoundsFilter.getSouth() <= structure.latitude &&
           structure.latitude <= this.mapBoundsFilter.getNorth() &&
           this.mapBoundsFilter.getWest() <= structure.longitude &&
           structure.longitude <= this.mapBoundsFilter.getEast()
    },
    /**
     * Does the structure match each of the page filters
     * @param structure
     * @returns {boolean}
     */
    matchFilters (structure) {
      return this.matchTextFilter(structure) &&
        this.matchLocationFilter(structure) &&
        this.matchPracticesFilter(structure) &&
        this.matchDepartmentFilter(structure) &&
        this.matchFederationFilter(structure)
        // this.matchMapBounds(structure)
    },
    /**
     * Update the filteredStructures array
     */
    search () {
      this.filteredStructures = this.structures.filter((s) => { return this.matchFilters(s) })
      this.fitMapToResults()
    }
  }
}
</script>

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

  h2 {
    color: $theme;
  }

  .structure-card {
    height: 100%;
  }

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

  .title {
    word-break: normal;
    color: $theme;
    font-size: 18px;
    font-weight: 500;
    line-height: 1.6rem;
  }

  .icon {
    color: $theme;
  }

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