<template>
  <div>
    <div
      v-if="permissions && permissions.can_view_project && project"
      id="project-detail"
    >
      <div
        id="message"
        class="fullwidth"
      >
        <div
          v-if="tempMessage"
          class="ui positive message"
        >
          <p>
            <i
              class="check icon"
              aria-hidden="true"
            />
            {{ tempMessage }}
          </p>
        </div>
      </div>

      <ProjectHeader
        :arrays-offline="arraysOffline"
        @retrieveInfo="retrieveProjectInfo"
        @updateLocalStorage="updateLocalStorage"
      />

      <div class="ui grid stackable">
        <div class="row">
          <div class="eight wide column">
            <ProjectFeatureTypes
              :loading="projectInfoLoading"
              :project="project"
              @delete="toggleDeleteFeatureTypeModal"
            />
          </div>

          <div class="eight wide column map-container">
            <div
              :class="{ active: mapLoading }"
              class="ui inverted dimmer"
            >
              <div class="ui text loader">
                Chargement de la carte...
              </div>
            </div>

            <div
              id="map"
              ref="map"
            />

            <router-link
              id="features-list"
              :to="{
                name: 'liste-signalements',
                params: { slug: slug },
              }"
              custom
            >
              <div
                class="ui button fluid teal"
              >
                <i class="ui icon arrow right" />
                Voir tous les signalements
              </div>
            </router-link>

            <div 
              id="popup" 
              class="ol-popup"
            >
              <a 
                id="popup-closer" 
                href="#" 
                class="ol-popup-closer"
              />
              <div 
                id="popup-content"
              />
            </div>
          </div>
        </div>

        <div class="row">
          <div class="sixteen wide column">
            <div class="ui two stackable cards">
              <ProjectLastFeatures
                :loading="featuresLoading"
              />
              <ProjectLastComments
                :loading="projectInfoLoading"
              />
            </div>
          </div>
        </div>

        <div class="row">
          <div class="sixteen wide column">
            <ProjectParameters
              :project="project"
            />
          </div>
        </div>
      </div>
    </div>

    <span v-else-if="!projectInfoLoading">
      <i
        class="icon exclamation triangle"
        aria-hidden="true"
      />
      <span>Vous ne disposez pas des droits nécessaires pour consulter ce
        projet.</span>
    </span>

    <ProjectModal
      :is-subscriber="is_suscriber"
      :feature-type-to-delete="featureTypeToDelete"
      @action="handleModalAction"
    />
  </div>
</template>

<script>
import mapService from '@/services/map-service';
import { mapGetters, mapState, mapActions, mapMutations } from 'vuex';

import projectAPI from '@/services/project-api';
import featureTypeAPI from '@/services/featureType-api';
import featureAPI from '@/services/feature-api';

import ProjectHeader from '@/components/Project/Detail/ProjectHeader';
import ProjectFeatureTypes from '@/components/Project/Detail/ProjectFeatureTypes';
import ProjectLastFeatures from '@/components/Project/Detail/ProjectLastFeatures';
import ProjectLastComments from '@/components/Project/Detail/ProjectLastComments';
import ProjectParameters from '@/components/Project/Detail/ProjectParameters';
import ProjectModal from '@/components/Project/Detail/ProjectModal';

export default {
  name: 'ProjectDetail',

  components: {
    ProjectHeader,
    ProjectFeatureTypes,
    ProjectLastFeatures,
    ProjectLastComments,
    ProjectParameters,
    ProjectModal
  },

  filters: {
    setDate(value) {
      const date = new Date(value);
      const d = date.toLocaleDateString('fr', {
        year: '2-digit',
        month: 'numeric',
        day: 'numeric',
      });
      return d;
    },
  },

  props: {
    message: {
      type: String,
      default: ''
    }
  },

  data() {
    return {
      infoMessage: '',
      importMessage: null,
      arraysOffline: [],
      arraysOfflineErrors: [],
      slug: this.$route.params.slug,
      is_suscriber: false,
      tempMessage: null,
      projectInfoLoading: true,
      featureTypeToDelete: null,
      featuresLoading: true,
      mapLoading: true,
    };
  },

  computed: {
    ...mapGetters([
      'permissions'
    ]),
    ...mapState('projects', [
      'project'
    ]),
    ...mapState([
      'configuration',
    ]),
    ...mapState('feature', [
      'features'
    ]),
    ...mapState('feature-type', [
      'feature_types'
    ]),
    ...mapState([
      'last_comments',
      'user',
      'user_permissions',
      'reloadIntervalId',
    ]),
    ...mapState('map', [
      'map'
    ]),
    API_BASE_URL() {
      return this.configuration.VUE_APP_DJANGO_API_BASE;
    },
  },

  created() {
    if (this.user) {
      projectAPI
        .getProjectSubscription({
          baseUrl: this.$store.state.configuration.VUE_APP_DJANGO_API_BASE,
          projectSlug: this.$route.params.slug
        })
        .then((data) => (this.is_suscriber = data.is_suscriber));
    }
    this.$store.commit('feature/SET_FEATURES', []); //* empty features remaining in case they were in geojson format and will be fetch after map initialization anyway
    this.$store.commit('feature-type/SET_FEATURE_TYPES', []); //* empty feature_types remaining from previous project
  },

  mounted() {
    this.retrieveProjectInfo();

    if (this.message) {
      this.tempMessage = this.message;
      document
        .getElementById('message')
        .scrollIntoView({ block: 'end', inline: 'nearest' });
      setTimeout(() => (this.tempMessage = null), 5000); //* hide message after 5 seconds
    }
  },

  beforeDestroy() {
    this.$store.dispatch('CANCEL_CURRENT_SEARCH_REQUEST');
    this.CLEAR_RELOAD_INTERVAL_ID();
    this.CLOSE_PROJECT_MODAL();
  },

  methods: {
    ...mapMutations([
      'CLEAR_RELOAD_INTERVAL_ID',
      'DISPLAY_MESSAGE',
      'DISPLAY_LOADER',
      'DISCARD_LOADER',
    ]),
    ...mapMutations('modals', [
      'OPEN_PROJECT_MODAL',
      'CLOSE_PROJECT_MODAL'
    ]),
    ...mapActions('projects', [
      'GET_PROJECT_INFO',
      'GET_PROJECT',
    ]),
    ...mapActions('map', [
      'INITIATE_MAP'
    ]),
    ...mapActions('feature', [
      'GET_PROJECT_FEATURES'
    ]),
    ...mapActions('feature-type', [
      'GET_IMPORTS'
    ]),

    retrieveProjectInfo() {
      this.DISPLAY_LOADER('Projet en cours de chargement.');
      Promise.all([
        this.GET_PROJECT(this.slug),
        this.GET_PROJECT_INFO(this.slug)
      ])
        .then(() => {
          this.DISCARD_LOADER();
          this.projectInfoLoading = false;
          this.$nextTick(() => {
            let map = mapService.getMap();
            if (map) mapService.destroyMap();
            this.initMap();
          });
        })
        .catch((err) => {
          console.error(err);
          this.DISCARD_LOADER();
          this.projectInfoLoading = false;
        });
    },

    checkForOfflineFeature() {
      let arraysOffline = [];
      const localStorageArray = localStorage.getItem('geocontrib_offline');
      if (localStorageArray) {
        arraysOffline = JSON.parse(localStorageArray);
        this.arraysOffline = arraysOffline.filter(
          (x) => x.project === this.slug
        );
      }
    },

    updateLocalStorage() {
      let arraysOffline = [];
      const localStorageArray = localStorage.getItem('geocontrib_offline');
      if (localStorageArray) {
        arraysOffline = JSON.parse(localStorageArray);
      }
      const arraysOfflineOtherProject = arraysOffline.filter(
        (x) => x.project !== this.slug
      );
      this.arraysOffline = [];
      arraysOffline = arraysOfflineOtherProject.concat(
        this.arraysOfflineErrors
      );
      localStorage.setItem('geocontrib_offline', JSON.stringify(arraysOffline));
    },

    subscribeProject() {
      projectAPI
        .subscribeProject({
          baseUrl: this.$store.state.configuration.VUE_APP_DJANGO_API_BASE,
          suscribe: !this.is_suscriber,
          projectSlug: this.$route.params.slug,
        })
        .then((data) => {
          this.is_suscriber = data.is_suscriber;
          this.CLOSE_PROJECT_MODAL();
          if (this.is_suscriber) {
            this.DISPLAY_MESSAGE({
              comment: 'Vous êtes maintenant abonné aux notifications de ce projet.', level: 'positive'
            });
          } else {
            this.DISPLAY_MESSAGE({
              comment: 'Vous ne recevrez plus les notifications de ce projet.', level: 'negative'
            });
          }
        });
    },

    deleteProject() {
      projectAPI.deleteProject(this.API_BASE_URL, this.slug)
        .then((response) => {
          if (response === 'success') {
            this.$router.push('/');
            this.DISPLAY_MESSAGE({
              comment: `Le projet ${this.project.title} a bien été supprimé.`, level: 'positive'
            });
          } else {
            this.DISPLAY_MESSAGE({
              comment: `Une erreur est survenu lors de la suppression du projet ${this.project.title}.`,
              level: 'negative'
            });
          }
        });
    },

    deleteFeatureType() {
      featureTypeAPI.deleteFeatureType(this.featureTypeToDelete.slug)
        .then((response) => {
          this.CLOSE_PROJECT_MODAL();
          if (response === 'success') {
            this.GET_PROJECT(this.slug);
            this.retrieveProjectInfo();
            this.DISPLAY_MESSAGE({
              comment: `Le type de signalement ${this.featureTypeToDelete.title} a bien été supprimé.`,
              level: 'positive',
            });
          } else {
            this.DISPLAY_MESSAGE({
              comment: `Une erreur est survenu lors de la suppression du type de signalement ${this.featureTypeToDelete.title}.`,
              level: 'negative',
            });
          }
          this.featureTypeToDelete = null;
        })
        .catch(() => {
          this.DISPLAY_MESSAGE({
            comment: `Une erreur est survenu lors de la suppression du type de signalement ${this.featureTypeToDelete.title}.`,
            level: 'negative',
          });
          this.CLOSE_PROJECT_MODAL();
        });
    },

    handleModalAction(e) {
      switch (e) {
      case 'subscribe':
        this.subscribeProject();
        break;
      case 'deleteProject':
        this.deleteProject();
        break;
      case 'deleteFeatureType':
        this.deleteFeatureType();
        break;
      }
    },

    toggleDeleteFeatureTypeModal(featureType) {
      this.featureTypeToDelete = featureType;
      this.OPEN_PROJECT_MODAL('deleteFeatureType');
    },

    async initMap() {
      if (this.project && this.permissions.can_view_project) {
        await this.INITIATE_MAP({ el: this.$refs.map });
        this.checkForOfflineFeature();
        const project_id = this.$route.params.slug.split('-')[0];
        const mvtUrl = `${this.API_BASE_URL}features.mvt`;
        mapService.addVectorTileLayer(
          mvtUrl,
          project_id,
          this.feature_types
        );
        this.mapLoading = false;
        this.arraysOffline.forEach((x) => (x.geojson.properties.color = 'red'));
        const featuresOffline = this.arraysOffline.map((x) => x.geojson);
        this.GET_PROJECT_FEATURES({
          project_slug: this.slug,
          ordering: '-created_on',
          limit: null,
          geojson: true,
        })
          .then(() => {
            this.featuresLoading = false;
            console.log('addFeatures');
            mapService.addFeatures({
              features: [...this.features, ...featuresOffline],
              featureTypes: this.feature_types,
              addToMap: true,
              queryParams: {
                ordering: this.project.feature_browsing_default_sort,
                filter: this.project.feature_browsing_default_filter,
              }
            });
          })
          .catch((err) => {
            console.error(err);
            this.featuresLoading = false;
          });

        featureAPI.getFeaturesBbox(this.slug).then((bbox) => {
          if (bbox) {
            mapService.fitBounds(bbox);
          }
        });
      }
    },
  },
};
</script>

<style lang="less" scoped>

.fullwidth {
  width: 100%;
}

.map-container {
  display: flex !important;
  flex-direction: column;

  .button {
    margin-top: 0.5em;
  }
}

</style>