<template>
  <fieldset class="ie-fieldset ie-conv-preview-panel">
    <!-- Legende cliquable : replie/deplie le formulaire pour gagner de l'espace
         une fois l'echantillon charge. -->
    <legend class="ie-conv-collapsible" @click="collapsed = !collapsed">
      <i class="fa fa-2x ie-conv-caret" :class="collapsed ? 'fa-angle-right' : 'fa-angle-down'" aria-hidden="true"></i>
      {{ messages.get('importexport', 'ie_conv_preview_title') }}
    </legend>
    <div v-show="!collapsed">
    <p class="ie-conv-hint">{{ messages.get('importexport', 'ie_conv_preview_hint') }}</p>

    <!-- Choix du scenario puis de la source qui l'alimente. -->
    <div class="row ie-row ie-flex">
      <div class="ie-conv-inline-field">
        <label>{{ messages.get('importexport', 'ie_conv_preview_scenario') }}</label>
        <select class="ie-select" v-model="selectedScenarioId" @change="onScenarioChange()">
          <option value="">{{ messages.get('importexport', 'ie_conv_select') }}</option>
          <option v-for="s in scenarios" :key="s.id" :value="s.id">
            {{ (s.usesConversion ? ' * ' : '') + s.name }}
          </option>
        </select>
      </div>
      <div class="ie-conv-inline-field">
        <label>{{ messages.get('importexport', 'ie_conv_preview_source') }}</label>
        <select class="ie-select" v-model="selectedSourceId" :disabled="!scenarioSources.length">
          <option value="">{{ messages.get('importexport', 'ie_conv_select') }}</option>
          <option v-for="src in scenarioSources" :key="src.id" :value="src.id">{{ src.sourceName }}</option>
        </select>
      </div>
    </div>

    <!-- Parametres contextuels : MEME formulaire qu'a l'execution d'un scenario
         (sourcesEditForm en mode execution). Re-cree a chaque changement de
         source (key) afin de reinitialiser proprement ses champs. -->
    <fieldset v-if="selectedSource && currentSourceType" class="ie-fieldset">
      <legend>{{ messages.get('importexport', 'ie_scenario_execution_context_parameters') }}</legend>
      <sources-edit-form :key="selectedSourceId" :source="selectedSource"
        :current-source-type="currentSourceType" :execution="true"
        :context-parameters="contextParameters"></sources-edit-form>
    </fieldset>

    <div class="row ie-row ie-conv-preview-actions">
      <button type="button" class="bouton ie-conv-primary" :disabled="!canLoad || loadingSample"
        @click="loadSample()">
        <i v-if="loadingSample" class="fa fa-spinner fa-spin" aria-hidden="true"></i>
        {{ messages.get('importexport', 'ie_conv_preview_load') }}
      </button>
    </div>
    </div>
  </fieldset>
</template>

<script>
import sourcesEditForm from '@importexport/sources/sourcesEditForm.vue';

/**
 * Panneau de previsualisation : choix d'un scenario et d'une de ses sources,
 * saisie des parametres contextuels (comme a l'execution), puis chargement d'un
 * echantillon des premiers enregistrements source. Emet "loaded" avec les
 * arbres source reconstruits, par correspondance d'entites (cf. backend
 * loadSampleSource).
 *
 * La conversion DOIT etre enregistree : le backend lit ses entites source pour
 * savoir quels sujets extraire (les expressions, elles, sont testees telles
 * qu'editees, sans enregistrement prealable).
 */
export default {
  name: "PreviewPanel",
  components: { sourcesEditForm },
  props: {
    /** Conversion testee (doit etre enregistree). */
    conversionId: { type: Number, default: 0 }
  },
  data() {
    return {
      scenarios: [],
      sourcesTypes: [],
      selectedScenarioId: "",
      selectedSourceId: "",
      contextParameters: {},
      loadingSample: false,
      // Repli du formulaire (gain de place une fois l'echantillon charge).
      collapsed: false
    };
  },
  async created() {
    const res = await this.ws.post("conversions", "getPreviewSources", { conversionId: this.conversionId });
    if (res && !res.error) {
      this.scenarios = Array.isArray(res.scenarios) ? res.scenarios : [];
      this.sourcesTypes = Array.isArray(res.sourcesTypes) ? res.sourcesTypes : [];
    }
  },
  computed: {
    /** Scenario selectionne (ou null). */
    selectedScenario() {
      return this.scenarios.find((s) => String(s.id) === String(this.selectedScenarioId)) || null;
    },
    /** Sources du scenario selectionne. */
    scenarioSources() {
      return this.selectedScenario && Array.isArray(this.selectedScenario.sources)
        ? this.selectedScenario.sources
        : [];
    },
    /** Source selectionnee (objet complet, avec sourceSettings). */
    selectedSource() {
      return this.scenarioSources.find((s) => String(s.id) === String(this.selectedSourceId)) || null;
    },
    /** Type de source correspondant (porte la declaration des parametres contextuels). */
    currentSourceType() {
      if (!this.selectedSource) {
        return null;
      }
      return this.sourcesTypes.find((t) => t.namespace === this.selectedSource.sourceType) || null;
    },
    /** Chargement possible ? (scenario + source + conversion enregistree). */
    canLoad() {
      return !!(this.selectedScenarioId && this.selectedSourceId && this.conversionId);
    }
  },
  watch: {
    /** Changement de source : on repart de parametres contextuels vierges. */
    selectedSourceId() {
      this.contextParameters = {};
    }
  },
  methods: {
    /** Changement de scenario : reinitialise la source et les parametres. */
    onScenarioChange() {
      this.selectedSourceId = "";
      this.contextParameters = {};
    },
    /**
     * Synchronise l'echantillon et emet les arbres source reconstruits.
     */
    async loadSample() {
      if (!this.canLoad) {
        return;
      }
      this.loadingSample = true;
      try {
        const res = await this.ws.post("conversions", "loadSampleSource", {
          scenarioId: this.selectedScenarioId,
          sourceId: this.selectedSourceId,
          conversionId: this.conversionId,
          contextParameters: this.contextParameters
        });
        if (res && res.success) {
          this.$emit("loaded", Array.isArray(res.mappings) ? res.mappings : []);
          // Repli automatique : l'echantillon est charge, on rend l'espace au formulaire.
          this.collapsed = true;
          this.notif.info(this.messages.get("importexport", "ie_conv_preview_loaded"));
        } else {
          this.notif.error((res && res.errorMessage) || this.messages.get("importexport", "ie_conv_preview_load_error"));
        }
      } catch (e) {
        this.notif.error(this.messages.get("importexport", "ie_conv_preview_load_error"));
      } finally {
        this.loadingSample = false;
      }
    }
  }
};
</script>
