<template>
  <div :style="pageStyle">
    <q-card
      v-if="showSearchPanel"
      style="margin-bottom: 15px;"
    >
      <q-resize-observable @resize="onSearchPanelResize"></q-resize-observable>
      <q-card-main>
        <slot name="search-form"></slot>
      </q-card-main>
      <q-card-actions align="center">
        <div class="w3-container">
          <q-btn
            color="primary"
            @click="searchOk"
            :label="$t('sys.search')"
            style="min-width:80px;"
          ></q-btn>
          <q-btn
            color="secondary"
            v-if="showDownloadBtn"
            @click="downloadCsv"
            :label="$t('sys.export')"
            style="min-width:80px;"
          ></q-btn>
          <slot name="search-panel-actions"></slot>
        </div>
      </q-card-actions>
    </q-card>
    <q-modal
      position="top"
      no-backdrop-dismiss
      no-esc-dismiss
      v-model="searchOpened"
    >
      <div style="min-width:300px;min-height:100px;">
        <div class="w3-padding">
          <slot name="search-form"></slot>
        </div>
        <div class="w3-padding w3-center">
          <q-btn
            color="primary"
            @click="searchOk"
            :label="$t('sys.search')"
            style="width:100px;"
          ></q-btn>
          <q-btn
            color="secondary"
            @click="searchCancel"
            :label="$t('sys.cancel')"
            style="width:100px;"
          ></q-btn>
        </div>
      </div>
    </q-modal>
    <q-card :style="{'height':chartCardHeight.toString()+'px'}">
      <echart
        ref="myChart"
        :options="chartOptions"
        :style="{'width': '100%','flex': 1,height:(chartCardHeight-30).toString()+'px'}"
        autoresize
      ></echart>
    </q-card>
    <q-page-sticky
      position="top-right"
      :offset="[10, 10]"
    >
      <!-- 預設有一個 search button //-->
      <q-btn
        round
        v-if="showSearchBtn"
        color="primary"
        @click="searchOpened=true"
        icon="search"
      ></q-btn>
      <q-btn
        round
        v-if="showSearchBtn && showDownloadBtn"
        color="primary"
        @click="downloadCsv"
        icon="download"
      ></q-btn>
      <slot name="page-sticky">
      </slot>
    </q-page-sticky>
  </div>
</template>

<script>
module.exports = {
  name: "multi-yaxis-chart",
  components: {
    "echart": VueECharts,
  },
  props: {
    "show-search-btn": { // 是否顯示查詢按鈕
      "type": "Boolean",
      "default": false
    },
    "show-search-panel": { // 是否顯示查詢面版
      "type": "Boolean",
      "default": false
    },
    "show-download-btn": { // 是否顯示下載按鈕
      "type": "Boolean",
      "default": false
    },
    "page-style": { // 放在頁面 template / div 的 style
      "type": "String",
      "default": "",
    },
    "title": {
      "type": "String", // chart 的主標題
    },
    "sub-title": { // chart 的副標題, 通常顯示日期區間
      "type": "String",
    },
    "y-axis-offset": {
      "type": "Number",
      "default": 70,
    },
    "y-axis-group": { // 傳入Y軸的群組名稱定義
      "type": "Object",
      "default": {
        'temperature': 'Temperature',
        'voltage': 'Voltage',
        'dc_current': 'DC Current',
        'dc_power': 'DC Power',
      }
    },
    "y-axis-select-options": { // 傳入Y軸下拉選單的項目清單
      "type": "Array",
      "default": [
        {
          value: 'REAL_TEMP',
          y_axis_group: 'temperature', // 對應的Y軸群組
          label: 'Temperature'
        },
        { value: 'REAL_VOLT', y_axis_group: 'voltage', label: 'Voltage' },
        { value: 'STR_A_01', y_axis_group: 'dc_current', label: 'DC Current1' },
        { value: 'STR_A_02', y_axis_group: 'dc_current', label: 'DC Current2' },
        { value: 'STR_A_03', y_axis_group: 'dc_current', label: 'DC Current3' },
        { value: 'STR_W_01', y_axis_group: 'dc_power', label: 'DC Power(W)-01' },
        { value: 'STR_W_02', y_axis_group: 'dc_power', label: 'DC Power(W)-02' },
        { value: 'STR_W_03', y_axis_group: 'dc_power', label: 'DC Power(W)-03' },
      ]
    },
    "y-axis-selected": { // 下拉選單選擇的值
      "type": "Array",
      "default": ["REAL_TEMP", "REAL_VOLT", "STR_A_01", "STR_A_02", "STR_W_01"],
    },
    "x-axis": { // x軸的值(日期或時間等...)
      "type": "Array", "default": ['01/01', '01/02', '01/03', '01/04', '01/05', '01/06', '01/07', '01/08', '01/09', '01/10']
    },
    "x-axis-col-name": { // x軸匯成csv的欄位名(日期或時間等...)
      "type": "String",
      "default": "row-key"
    },
    "series": { // 資料清單
      "type": "Array",
      "default": [
        {
          'name': "series 1",
          'select_value': 'REAL_TEMP',
          'data': [['01/01', 1], ['01/02', 2], ['01/03', 3]]
        },
        {
          'name': "series 2",
          'select_value': 'REAL_VOLT',
          'data': [['01/04', 4], ['01/05', 5], ['01/06', 6]]
        },
        {
          'name': "series 3",
          'select_value': 'STR_A_01',
          'data': [['01/01', 7], ['01/03', 8], ['01/05', 9]]
        },
        {
          'name': "series 4",
          'select_value': 'STR_A_02',
          'data': [['01/01', 17], ['01/05', 18], ['01/06', 19]]
        },
        {
          'name': "series 5",
          'select_value': 'STR_A_03',
          'data': [['01/01', 17], ['01/05', 18], ['01/06', 19]]
        },
        {
          'name': "series 6",
          'select_value': 'STR_W_01',
          'data': [['01/01', 17], ['01/05', 18], ['01/06', 19]]
        }
      ]
    },
  },
  data () {
    return {
      "searchOpened": false,
      "searchPanelHeight": 0,
      "yAxisSelectedValues": [], // 從 y-axis-selected props 傳入後, 再 series變更後才會寫入此值(避免切換select時不斷重畫chat)
    }
  },
  computed: {
    isDesktop () { // 是否為桌面平台
      return this.$root.VarIsDesktop;
    },
    isMobile () { // 是否為手機平台
      return this.$root.VarIsMobile;
    },
    isTablet () { // 是否為平板平台
      return this.$root.VarIsTablet;
    },
    isMenuOpen () { // 是否開啟選單
      return this.$root.VarIsMenuOpen;
    },
    screenIsVertical () { // 螢幕是否直立
      return this.$root.VarScreenIsVertical;
    },
    layoutScreenHeight () { // 螢幕的高
      return this.$root.VarLayoutScreenHeight;
    },
    layoutContainerHeight () { // 螢幕的寬
      return this.$root.VarLayoutContainerHeight;
    },
    chartCardHeight () { // chart card 長度
      if (this.isMobile && !this.screenIsVertical) {
        return 300;
      } else {
        return this.layoutScreenHeight - this.searchPanelHeight - 100;
      }
    },
    columns () {
      try {
        return [{ 'label': this.xAxisColName, 'field': this.xAxisColName }, ..._.map(this.series, (row) => {
          return { 'label': row['name'], 'field': row['name'] };
        })];
      } catch (e) {
        return []
      }
    },
    tableData () {
      return _.map(this.xAxis, (rowKey) => {
        var obj = {};
        obj[this.xAxisColName] = rowKey;
        _.each(this.series, (row) => {
          var col = row['name'];
          var val = _.find(row['data'], (d) => d[0] === rowKey);
          obj[col] = val ? val[1] : '-';
        })
        return obj;
      })
    },
    yAxisSelectOptionsMap () { // 下拉選單的選項變成MAP比對好處理
      return _.reduce(this.yAxisSelectOptions, (obj, val) => {
        obj[val["value"]] = val;
        return obj
      }, {})
    },
    yAxisSelectedValuesMap () { // 下拉選單的值與選項變成MAP
      return _.reduce(this.yAxisSelectedValues, (obj, val, idx) => {
        if (!_.isUndefined(this.yAxisSelectOptionsMap[val])) {
          obj[val] = this.yAxisSelectOptionsMap[val];
        }
        return obj;
      }, {});
    },
    yAxisChartOptions () { // 供 echart options 的 yAxis 使用 (根據下拉選單對應 y axis group 而得)
      try {
        var list = _.map(this.yAxisGroup, (val, key) => {
          let that = this;
          return {
            "type": "value",
            "nameRotate": 90,
            "nameGap": 40,
            "nameLocation": "center",
            // "alignTicks": true,
            "axisLine": {
              "show": true
            },
            "axisTick": {
              "show": true
            },
            "axisPointer": {
              "snap": true,
              "type": 'shadow'
            },
            /*"axisLabel": {
              "interval": function (index, value) { // 想作到若label在中間為了避開axis name則不顯示, 但不知如何得yAxis.max與yAxis.interval故放棄
                return index === 0 || index === (this.yAxis.max / this.yAxis.interval);
              },
              "formatter": (val) => { // 會顯示重覆的 2k, 故不採用
                if (val >= 1000) {
                  return that.$root.FnFormatNumber(val / 1000, 0) + 'k';
                } else if (val < 1 && val > 0) {
                  return that.$root.FnFormatNumber(val);
                } else {
                  return that.$root.FnFormatNumber(val, 0);
                }
              }
            },*/
            "name": val, "id": key
          };
        });
        var selectedValuesList = _.values(this.yAxisSelectedValuesMap);
        list = _.filter(list, (row) => {
          return _.findIndex(selectedValuesList, (obj) => {
            return obj["y_axis_group"] == row["id"];
          }) >= 0
        });
        return _.map(list, (row, idx) => {
          row["offset"] = idx > 1 ? (idx - 1) * this.yAxisOffset : 0;
          return row;
        });
      } catch (e) {
        console.log("yAxisChartOptions" + JSON.stringify(e));
        return [];
      }
    },
    legendChartDataOptions () {
      try {
        var defaultObj = { icon: 'circle' };
        return _.map(this.series, (val) => _.defaults({ 'name': val['name'] }, defaultObj));
      } catch (e) {
        console.log("legendChartDataOptions" + JSON.stringify(e));
        return [];
      }
    },
    seriesChartOptions () {
      try {
        var defaultObj = {
          type: 'line'
        };
        var list = [];
        _.each(this.series, (val) => {
          var obj = _.defaults(val, defaultObj);
          var selectValObj = this.yAxisSelectedValuesMap[val['select_value']];
          var yAxisGroup = selectValObj ? selectValObj['y_axis_group'] : "";
          obj['yAxisIndex'] = _.findIndex(this.yAxisChartOptions, (val) => {
            return val['id'] === yAxisGroup;
          }) || 0;
          if (obj['yAxisIndex'] < 0) { // 若該值沒有對應到任何yaxis則不顯示(應可能series傳入所有欄位,但下拉選單只有幾項)
            return;
          }
          list.push(obj);
        });
        return list;
      } catch (e) {
        console.log("seriesChartOptions" + JSON.stringify(e));
        return [];
      }
    },
    chartOptions () {
      var yAxisCount = _.size(this.yAxisChartOptions);
      if (yAxisCount <= 0) {
        return {
          title: {
            text: this.title,
            left: 'center', // 置中
            subtext: this.subTitle,
            top: 10,
          },
          xAxis: {
            type: 'category',
            nameLocation: 'start', // 名稱置放位置
            boundaryGap: true, // X軸與Y軸有間隔
            data: this.xAxis
          },
          yAxis: {
            type: 'value',
          },
        }
      }
      return {
        title: {
          text: this.title,
          left: 'center', // 置中
          subtext: this.subTitle,
          top: 10,
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        legend: { // 圖例
          type: 'scroll',
          top: 'bottom', // 圖例置下
          selectedMode: false, // 不可取消
          data: this.legendChartDataOptions // 圖例項目
        },
        xAxis: {
          type: 'category',
          nameLocation: 'start', // 名稱置放位置
          boundaryGap: true, // X軸與Y軸有間隔
          axisPointer: {
            type: 'shadow'
          },
          data: this.xAxis
        },
        yAxis: _.isEmpty([this.yAxisChartOptions]) ? { type: 'value' } : this.yAxisChartOptions,
        tooltip: {
          trigger: 'axis'
        },
        dataZoom: [
          {
            show: true,
            type: 'inside',
            rangeMode: ['percent', 'percent']
          },
          {
            show: true,
            type: 'slider',
            rangeMode: ['percent', 'percent']
          }
        ],
        grid: {
          left: 80,
          right: yAxisCount > 2 ? (((yAxisCount - 1) * this.yAxisOffset) + 20) : 100
        },
        series: this.seriesChartOptions
      };
    },
  },
  watch: {
    series () { // 傳入蒐尋後的資料,將下拉選單選擇值設定後,就會驅動若干計算值,最終更新chartOptions後,再此執行重繪chart動作
      this.yAxisSelectedValues = this.yAxisSelected;
      this.$refs.myChart.chart.setOption(this.chartOptions);
    },
  },
  mounted () {
  },
  methods: {
    searchOk (evt) {
      this.$emit("search-ok", evt);
      this.searchOpened = false;
    },
    searchCancel (evt) {
      this.$emit("search-cancel", evt);
      this.searchOpened = false;
    },
    downloadCsv () {
      this.$root.FnReportDownload("csv", this.tableData, this.columns);
    },
    onSearchPanelResize (props) {
      if (this.showSearchPanel) { // 若不顯示 search panel 則不需要取得它的高度
        this.searchPanelHeight = props.height;
      }
    }
  }
}
</script>

<style scoped>
.q-select .q-input-target {
  width: 10px !important;
}
</style>
