<template>
  <v-main>
    <div class="workflowTitle">
      Explore climate changes for any region of interest.
    </div>
    <div class="workflowSubtitle">
      This workflow supports the exploration and assessment of climate change
      between historic and projected regional climate model simulations.
    </div>
    <v-flex pa-1>
      <v-card pa-1>
        <v-card-title>
          <span class="headline">Directions</span>
        </v-card-title>
        <v-card-text>
          <br />
          <ol>
            <li>
              Define Earth System Grid Federation (ESGF) search criteria. Preset
              CORDEX dataset available. Interpolated CORDEX domain experiments not supported.
            </li>
            <li>
              Create climate model ensembles by adding experiments from search results.
            </li>
            <li>
              Adjust time ranges and averaging intervals. Averaging periods must
              be at least 30 years.
            </li>
            <li>
              Define region of interest (ROI) by drawing a ploygon or providing a geometry file via
              drag'n'drop. Geometry files with single feature and single ploygon
              currently supported (GeoJSON). A ROI can be created by clicking a
              polygon on the map. 
            </li>
            <li>
              Activate ROI using 'globe' icon in thematic
              layer, which will turn green.
            </li>
            <li>
              Edit data processing pipeline if needed. Press Start to begin
              Analysis. Warning: Each projected climate model ensemble member
              can take up to 5 min processing time.
            </li>
            <li>Download processed data or plot.</li>
          </ol>
        </v-card-text>
      </v-card>
    </v-flex>

    <!-- <v-flex pa-1 xs5>
        <v-card style="margin-bottom: 100px;">
          <ChangeMap :workflowName="name"></ChangeMap>
        </v-card>
      </v-flex>

      <v-flex xs7>
        <v-layout col wrap>
          <v-flex pa-1 xs12>
            <daterangepicker ref="daterangepicker" title="Select time range"></daterangepicker>
          </v-flex>
          <v-flex pa-1 xs12>
            <event-severity-timeseries-chart :workflowName="name"></event-severity-timeseries-chart>
    </v-flex>-->
    <v-flex pa-1>
      <v-expansion-panels multiple :value="activePanels" class="mb-10">
        <v-expansion-panel>
          <v-expansion-panel-header class="title">
            Datasets
            <!-- Add overview chip to the header -->
            <v-chip
              class="ml-5"
              :color="settings.getSelectedDatasetCount() == 0 ? 'red' : 'green'"
              v-text="settings.getSelectedDatasetCount()"
              style="max-width: max-content"
            />
            <v-spacer />
            <v-select
              class="mr-10"
              :items="settings.getDatasetPresetNames()"
              dense
              clearable
              persistent-hint
              hint="Dataset Presets"
              style="max-width: 200px"
              @change="loadDatasetPreset"
              @click.native.stop
            ></v-select>
          </v-expansion-panel-header>

          <v-expansion-panel-content>
            <v-row v-if="settings.getSelectedDatasetCount() > 0" no-gutters>
              <v-col cols="6">
                <dataset-list-panel
                  class="ma-1"
                  title="Selected Datasets"
                  is-result-panel
                  :ensembles="settings.ensembles"
                  style="height: 100%; max-height: -webkit-fill-available"
                ></dataset-list-panel>
              </v-col>
              <v-col cols="6">
                <v-card
                  v-for="(group, g) of [
                    settings.refDatasetGroup,
                    settings.compDatasetGroup,
                  ]"
                  class="ma-1"
                  :key="g"
                >
                  <v-card-title
                    class="vert-text"
                    v-text="group.name"
                    :style="'color: ' + group.color"
                  />
                  <daterangepicker
                    class="ml-10"
                    :model="group.dateRange"
                    :allow-extension="false"
                    title="Select time range"
                  ></daterangepicker>
                  <date-interval-picker
                    class="mt-2 ml-10"
                    :intervals="group['averagingIntervals']"
                    :min-date="group.dateRange.selectedMinDate"
                    :max-date="group.dateRange.selectedMaxDate"
                  ></date-interval-picker>
                </v-card>
              </v-col>
            </v-row>
            <v-row style="flex-wrap: nowrap" no-gutters>
              <v-col style="max-width: 440px; min-width: 440px; width: 440px">
                <dataset-search-panel
                  class="ma-1 pa-2"
                  :workflow-name="workflowName"
                ></dataset-search-panel>
              </v-col>
              <v-col
                cols="1"
                class="flex-grow-1 flex-shrink-0"
                style="min-width: 100px; max-width: 100%"
              >
                <dataset-list-panel
                  class="ma-1 overflow-y-auto"
                  v-if="
                    settings.ensembles.length > 0 &&
                    settings.getSelectedDatasetCount() !=
                      settings.ensembles.length
                  "
                  title="Dataset Search Results"
                  :ensembles="settings.ensembles"
                  style="max-height: 636px"
                ></dataset-list-panel>
              </v-col>
            </v-row>
          </v-expansion-panel-content>
        </v-expansion-panel>

        <v-expansion-panel>
          <v-expansion-panel-header class="title">
            Region of Interest
            <!-- Add overview chip to the header -->
            <v-chip
              pill
              class="ml-5"
              style="max-width: max-content"
              :color="settings.roiWgs84 ? 'green' : 'grey'"
              ><v-icon>public</v-icon></v-chip
            >
            <v-spacer />
            <v-select
              class="mr-10"
              :items="roiPresets"
              item-text="name"
              return-object
              dense
              clearable
              persistent-hint
              hint="Region of Interest Presets"
              style="max-width: 200px"
              @change="loadRoiPreset"
              @click.native.stop
            ></v-select>
          </v-expansion-panel-header>
          <v-expansion-panel-content>
            <ChangeMap
              ref="map"
              :wf-settings="settings"
              :workflow-name="workflowName"
            ></ChangeMap>
          </v-expansion-panel-content>
        </v-expansion-panel>
        <v-expansion-panel>
          <v-expansion-panel-header class="title"
            >Analysis</v-expansion-panel-header
          >

          <!-- <v-overlay :value="progressReport != null && showProgress">

          </v-overlay> -->

          <v-expansion-panel-content>
            <v-row>
              <v-col md="auto">
                <v-card outlined class="pa-3">
                  <v-card-title> Configure Analysis Pipeline </v-card-title>
                  <v-card-subtitle>
                    Select steps to execute...
                  </v-card-subtitle>
                  <v-stepper v-model="analysisSteps" vertical>
                    <v-stepper-step
                      v-for="(pipelineStep, s) in analysisPipeline"
                      :key="s"
                      :step="pipelineStep.step + 1"
                      :complete="analysisSteps > pipelineStep.step"
                      :editable="!pendingRequest"
                      edit-icon="settings"
                    >
                      {{ pipelineStep.name }}
                      <small>{{ pipelineStep.subtitle }}</small>
                      <v-tooltip right>
                        <template v-slot:activator="{ on, attrs }">
                          <v-btn
                            :disabled="!isDownloadAvailable(pipelineStep.step)"
                            :loading="pipelineStep.requestPending"
                            color="primary"
                            small
                            absolute
                            right
                            v-bind="attrs"
                            v-on="on"
                            @click.native="downloadAnalysisData(pipelineStep)"
                            @click.stop
                            ><v-icon>download</v-icon></v-btn
                          >
                        </template>
                        <span
                          >Download Data for step
                          <strong>{{ pipelineStep.name }}</strong></span
                        >
                      </v-tooltip>
                    </v-stepper-step>
                  </v-stepper>
                  <v-card-actions>
                    <v-spacer />
                    <v-btn
                      display="inline-block"
                      :loading="pendingRequest"
                      :disabled="pendingRequest || !isBackendConnected()"
                      color="primary"
                      @click="sendBackendModuleRequest"
                    ><div v-if="isBackendConnected()">
                      <v-icon class="mr-2">bar_chart</v-icon>Start
                      </div>
                      <div v-else>
                      <v-icon class="mr-2">perm_scan_wifi</v-icon>Connecting...
                      </div>
                    </v-btn>
                    <v-spacer />
                  </v-card-actions>
                </v-card>
              </v-col>
              <v-col md="auto" v-if="progressReport != null">
                <v-card outlined style="height: 100%" class="pa-3">
                  <progress-tree
                    :progress="progressReport"
                    title="Request Progress"
                    :subtitle="'request reference: ' + requestReference"
                    style="width: 100%"
                  />
                </v-card>
              </v-col>
            </v-row>
            <v-row>
              <v-col md="auto">
                <v-card outlined v-if="base64SVG.length > 0" class="pa-3">
                  <v-card-title> Analysis Result </v-card-title>
                  <v-card-text>
                    <img
                      width="100%"
                      :src="
                        `data:image/svg+xml;base64,` + base64SVG
                      " /></v-card-text
                ></v-card>
              </v-col>
            </v-row>
          </v-expansion-panel-content>
        </v-expansion-panel>
      </v-expansion-panels>
    </v-flex>
  </v-main>
</template>

<style scoped>
.vert-text {
  position: absolute;
  top: 0;
  left: 0;

  /* Rotate from top left corner (not default) */
  transform-origin: 9% 66%;
  transform: rotate(90deg);
}
</style>

<script lang='ts'>
import _, { filter } from 'lodash';
import axios from 'axios';
import Daterangepicker from 'dasf-web/lib/dateSelection/daterangepicker/Daterangepicker.vue';
import DateIntervalPicker from 'dasf-web/lib/dateSelection/DateIntervalPicker/DateIntervalPicker.vue';
import { ChangeWorkflowSettings } from '~/components/change/model/ChangeWorkflowSettings';
import { Component, Vue, Watch, Ref } from 'vue-property-decorator';
import {
  userSetting,
  WorkflowSettingsObserver,
} from 'dasf-web/lib/model/UserSetting';
import ChangeMap from '~/components/change/ChangeMap.vue';
import { HighPrecipDataAcquisition } from '~/components/change/model/HighPrecipDataAcquisition';
import { HighPrecipEventTimeseries } from '~/components/change/model/HighPrecipEvent';
import EventSeverityTimeseriesChart from '~/components/change/EventSeverityTimeseriesChart.vue';
import { DatasetGroup } from 'dasf-web/lib/dataDiscovery/DataArchive';
import { EsgfDataArchive } from 'dasf-web/lib/dataDiscovery/EsgfDataArchive';
import DatasetSearchPanel from 'dasf-web/lib/dataDiscovery/DatasetSearchPanel.vue';
import DatasetListPanel from 'dasf-web/lib/dataDiscovery/DatasetListPanel.vue';
import BackendModule from '~/components/change/model/ChangeModuleMessaging';
import FileUtils from 'dasf-web/lib/util/FileUtils';
import ProgressTree from 'dasf-web/lib/messaging/ProgressTree.vue';
import { PulsarProgressReport } from 'dasf-web/lib/messaging/PulsarMessages';
import b64a from 'base64-arraybuffer';

const VERSION: number[] = [0, 0, 1];

@Component({
  components: {
    Daterangepicker,
    DateIntervalPicker,
    ChangeMap,
    EventSeverityTimeseriesChart,
    DatasetSearchPanel,
    DatasetListPanel,
    ProgressTree,
  },
})
export default class ChangeWorkflow
  extends Vue
  implements WorkflowSettingsObserver {
  workflowName: string = 'ChangeWorkflow';
  settings!: ChangeWorkflowSettings;

  @Ref('map') readonly map!: ChangeMap;

  static readonly roiPresetsUrl = 'geojson/region_of_interests.json';
  roiPresets: object[] = [];

  activePanels: number[] = [1];

  base64SVG: string = '';
  private requestReference: string = undefined;

  pendingRequest: boolean = false;

  private analysisSteps = 4;
  private progressReport: PulsarProgressReport = null;
  private showProgress = false;
  esfgSearchDefaults: object = {
    project: ['CORDEX-Reklies', 'CORDEX-ESD', 'CORDEX'],
    domain: ['EUR-11'],
    experiment: ['historical', 'rcp85', 'rcp45', 'rcp26'],
    // ensemble: ['r1i1p1'],
    // eslint-disable-next-line @typescript-eslint/camelcase
    // rcm_name: ['REMO2015'],
    variable: ['pr'],
    // eslint-disable-next-line @typescript-eslint/camelcase
    time_frequency: ['day'],
  };

  private analysisPipeline: object[] = [
    {
      name: 'Download',
      id: 'download',
      subtitle: 'Dataset Download',
      step: 0,
      requestPending: false,
    },
    {
      name: 'Merge',
      id: 'merge',
      subtitle: 'Dataset Merge',
      step: 1,
      requestPending: false,
    },
    {
      name: 'Statistics',
      id: 'statistics',
      subtitle: 'Calculate Statistics',
      step: 2,
      requestPending: false,
    },
    {
      name: 'Plotting',
      id: 'plot',
      subtitle: 'Plot Result Chart',
      step: 3,
      requestPending: false,
    },
  ];


  constructor() {
    super();

    if (userSetting.hasWorkflowSettings(this.workflowName)) {
      this.settings = userSetting.getWorkflowSettings(
        this.workflowName
      ) as ChangeWorkflowSettings;
    } else {
      // create workflow specific settings
      this.settings = new ChangeWorkflowSettings();

      // registered the settings at the global userSettings
      userSetting.registerWorkflowSettings(this.workflowName, this.settings);

      // set esgf archive as data archive
      this.settings.dataArchive = new EsgfDataArchive(
        'esgf-data.dkrz.de',
        new Map(Object.entries(this.esfgSearchDefaults))
      );
      this.settings.dataArchiveQueryProps = [
        'project',
        'domain',
        'experiment',
        'ensemble',
        'rcm_name',
        'time_frequency',
        'variable',
        'driving_model',
        'model',
      ];
    }

    this.settings.addListener(this);

    this.loadRoiPresets();
  }

  settingsUpdate(type: string) {
    console.log('settings update: ' + type);

    // let wfSet = userSetting.getWorkflowSettings(
    //   this.name
    // ) as ChangeWorkflowSettings;

    switch (type) {
      case ChangeWorkflowSettings.ROI_UPDATED:
        this.sendEventDataRequest();
        break;
    }
  }

  protected mounted() {
    // trigger backend module ping-pong
    BackendModule;
  }

  protected sendEventDataRequest() {
    let wfSet = userSetting.getWorkflowSettings(
      this.workflowName
    ) as ChangeWorkflowSettings;

    HighPrecipDataAcquisition.getEvents(wfSet).then(
      (value: HighPrecipEventTimeseries) => {
        wfSet.eventTimeseries = value;
      }
    );
  }

  protected isBackendConnected(): boolean {
    return BackendModule.isConnected();
  }

  protected sendBackendModuleRequest() {
    this.base64SVG = '';
    this.requestReference = undefined;
    this.pendingRequest = true;

    const groups: [DatasetGroup, DatasetGroup] = this.settings.getDatasetGroups();

    console.log('groups for analysis', groups);
    

    BackendModule.sendAnalysisRequest(
      groups[0],
      groups[1],
      this.settings.getRoiWgs84Wkt(),
      (svg: string) => {
        this.base64SVG = svg;
        this.pendingRequest = false;
      },
      (progressReport: PulsarProgressReport, msgProps: object) => {
        this.progressReport = progressReport;
        // extract request_reference from msgProps
        if (
          this.requestReference == undefined &&
          msgProps &&
          msgProps.hasOwnProperty('request_reference')
        ) {
          this.requestReference = msgProps['request_reference'];
        }
      }
    );
    this.pendingRequest = false;
  }

  protected loadDatasetPreset(presetName: string): void {
    this.settings.loadPreset(presetName);
  }

  protected loadRoiPresets(): void {
    let url = ChangeWorkflow.roiPresetsUrl;
    console.log('loading roi preset data from ', url);
    axios.get(url).then((response) => {
      this.roiPresets = response.data;
    });
  }

  protected loadRoiPreset(roiPreset: object): void {
    this.map.clearLayers();

    if (roiPreset) {
      console.log('load roi preset: ', roiPreset);
      this.map.addAsRoi(roiPreset['name'], roiPreset['url']);
    }
  }

  protected destroyed() {
    let wfSet = userSetting.getWorkflowSettings(
      this.workflowName
    ) as ChangeWorkflowSettings;
    if (wfSet) {
      wfSet.clearListeners();
    }
    console.log('destroyed: ' + this.toString());
  }

  public toString(): string {
    return this.workflowName + ' V' + VERSION.join('.');
  }

  protected isDownloadAvailable(step: number): boolean {
    if (this.requestReference) {
      // we have a request reference - check wether the analysis step is already finished
      if (
        this.progressReport &&
        this.progressReport.children &&
        this.progressReport.children.length > step
      ) {
        return this.progressReport.children[step].completed;
      }
    }

    return false;
  }

  protected downloadAnalysisData(pipelineStep: object): void {
    let step: number = pipelineStep['step'];

    if (this.requestReference && step > -1 && step < 4) {
      pipelineStep['requestPending'] = true;
      BackendModule.sendDownloadRequest(
        this.requestReference,
        step,
        (status: string, data: string, filename?: string) => {
          console.log('got download data ', status, filename, data.length);

          if (filename == undefined || filename.trim().length == 0) {
            filename =
              pipelineStep['id'] + '_' + this.requestReference + '.zip';
          }

          FileUtils.forceFileDownload(filename, b64a.decode(data));
          pipelineStep['requestPending'] = false;
        }
      );
    }
  }
}
</script>
