<template>
  <div class="card-container">
    <div class="card-content">
      <div class="ocpp-content">
        <div class="section-title">Selected Stations</div>
        <div class="flexc">
          <span style="width: 200px;">Site: </span>
          <el-select
            class="flex-item"
            filterable
            remote
            v-model="listQuery.pageVo.sitePk"
            :remote-method="filterSite"
            :loading="siteLoading"
            placeholder="Select with search"
            @change="changeSite">
            <el-option
              v-for="(item, index) in siteList"
              :key="index"
              :label="item.siteName"
              :value="item.sitePk"/>
          </el-select>
        </div>
        <div class="flexc" style="padding: 20px 0; justify-content: flex-end;">
          <el-button
            type="primary"
            @click="selectNone">
            Select None
          </el-button>
          <el-button
            style="margin-left: 15px;"
            type="primary"
            @click="selectAll">
            Select All
          </el-button>
        </div>
        <el-table
          style="width: 100%;min-height: 50vh;"
          v-loading="listLoading"
          :data="stationList">
          <el-table-column
            :label="item.label"
            align="center"
            class-name="fixed-width"
            v-for="(item, index) in columns"
            :key="index"
            :width="item.width">
            <template slot-scope="{row, $index}">
              <el-checkbox 
                v-if="item.action"
                v-model="row[item.key]"
                @change="checked => changeRow($index, checked)"/>
              <span v-else>{{ row[item.key] }}</span>
            </template>
          </el-table-column>
        </el-table>
        <div class="right">
          <pagination
            v-show="total > 0"
            :total="total"
            :page.sync="listQuery.pageNo"
            :limit.sync="listQuery.pageSize"
            @pagination="handlePageChange" />
        </div>
      </div>
      <div class="ocpp-content">
      <el-form 
        :model="operationForm"
        :rules="rule"
        ref="operationForm"
        label-width="200px"
        label-position="left">
        <div class="section-title">OCPP Operation</div>
        <el-form-item
          label="Operation:"
          prop="operation">
          <el-select
            class="flex-item"
            v-model="operationForm.operation"
            @change="changeOperation">
            <el-option
              v-for="(item, index) in operationList"
              :key="index"
              :label="item.name"
              :value="index"
              v-if="item.api"/>
          </el-select>
        </el-form-item>
        <div class="section-title" style="padding-top: 20px;" v-loading="paramLoading">Parameters</div>
        <el-form-item
          label="Filter Type:"
          prop="filterType"
          v-if="paramsOption.filterTypeOption.length > 0">
          <el-select
            v-model="operationForm.filterType"
            class="flex-item"
            @change="changeFilterType">
            <el-option
              v-for="(item, index) in paramsOption.filterTypeOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Charging Profile ID:"
          prop="chargingProfilePk"
          v-if="paramsOption.needChargingProfile">
          <el-select
            v-model="operationForm.chargingProfilePk"
            class="flex-item">
            <el-option
              v-for="(item, index) in paramsOption.chargingProfileOption"
              :key="index"
              :label="item.value + ' (' + item.name + ')'"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Connector ID:"
          prop="connectorId"
          v-if="paramsOption.needConnector">
          <el-select
            v-model="operationForm.connectorId"
            class="flex-item">
            <el-option
              v-for="(item, index) in paramsOption.connectorIds"
              :key="index"
              :label="item"
              :value="item"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Transaction ID:"
          prop="transactionId"
          v-if="paramsOption.needActConnector">
          <el-select
            v-model="operationForm.transactionId"
            class="flex-item">
            <el-option
              v-for="(item, index) in paramsOption.connectorActIds"
              :key="index"
              :label="item"
              :value="item"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Mobile Number:"
          prop="idTagInfo"
          v-if="paramsOption.idTagAll.length > 0">
          <el-select
            v-model="operationForm.idTagInfo"
            filterable
            remote
            :remote-method="filterMobile"
            class="flex-item"
            :loading="tagLoading">
            <el-option
              v-for="(item, index) in paramsOption.idTags"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Availability Type:"
          prop="availType"
          v-if="paramsOption.availTypeOption.length > 0">
          <el-select
            v-model="operationForm.availType"
            class="flex-item"
            placeholder="Select">
            <el-option
              v-for="(item, index) in paramsOption.availTypeOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Charging Profile Purpose:"
          prop="chargingProfilePurpose"
          v-if="paramsOption.needChargingProfilePurpose">
          <el-select
            v-model="operationForm.chargingProfilePurpose"
            class="flex-item">
            <el-option
              v-for="(item, index) in paramsOption.chargingPurposeOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Stack Level (integer):"
          v-if="paramsOption.needChargingProfilePurpose">
          <el-input
            v-model="operationForm.stackLevel"
            class="flex-item"/>
        </el-form-item>
        <el-form-item
          label="Key Type:"
          prop="keyType"
          v-if="paramsOption.keyTypeOption.length > 0">
          <el-select
            v-model="operationForm.keyType"
            class="flex-item"
            placeholder="Select"
            @change="changeKeyType">
            <el-option
              v-for="(item, index) in paramsOption.keyTypeOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <div
          class="multi-select"
          v-if="paramsOption.confKeyOption.length > 0 && paramsOption.selectMultConfig">
        <span class="note-span">Info: If none selected, the charge point returns a list of all configuration settings.</span>
        <el-form-item
          label="Configuration Key:">
          <el-select
            v-model="operationForm.confKeyList"
            class="flex-item"
            style="align-items: flex-start;"
            placeholder="Select multiple"
            :multiple="true">
            <el-option
              v-for="(item, index) in paramsOption.confKeyOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        </div>
        <el-form-item
          label="Configuration Key:"
          prop="confKey"
          v-else-if="paramsOption.confKeyOption.length > 0 && operationForm.keyType == 'PREDEFINED'">
          <el-select
            v-model="operationForm.confKey"
            class="flex-item"
            placeholder="Select">
            <el-option
              v-for="(item, index) in paramsOption.confKeyOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          label="Custom Configuration Key:"
          prop="customConfKey"
          label-width="205px"
          v-if="paramsOption.keyTypeOption.length > 0 && operationForm.keyType == 'CUSTOM'">
          <el-input
            v-model="operationForm.customConfKey"
            class="flex-item"/>
        </el-form-item>
        <el-form-item
          label="Value:"
          v-if="paramsOption.keyTypeOption.length > 0">
          <el-input
            v-model="operationForm.value"
            class="flex-item"/>
        </el-form-item>
        <el-form-item
          label="Reset Type:"
          prop="resetType"
          v-if="paramsOption.resetTypeOption.length > 0">
          <el-select
            class="flex-item"
            v-model="operationForm.resetType">
            <el-option
              v-for="(item, index) in paramsOption.resetTypeOption"
              :key="index"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <template v-if="operationInfo.value == 'UF'">
          <el-form-item
            label="Location(directory URI):"
            prop="location">
            <el-input
              v-model="operationForm.location"
              class="flex-item"/>
          </el-form-item>
          <el-form-item
            label="Retries(integer):">
            <el-input
              v-model="operationForm.retries"
              class="flex-item"/>
          </el-form-item>
          <el-form-item
            label="Retry Interval(integer):">
            <el-input
              v-model="operationForm.retryInterval"
              class="flex-item"/>
          </el-form-item>
          <el-form-item
            label="Retrieve Date/Time:"
            prop="retrieve">
            <el-date-picker
              v-model="operationForm.retrieve"
              type="datetime"
              format="yyyy-MM-dd HH:mm"
              value-format="yyyy-MM-dd HH:mm"
              default-time="12:00:00"
              class="flex-item"/>
          </el-form-item>
        </template>
        <div class="perform">
          <el-button
            style="margin-left: 15px;"
            type="primary"
            :loading="btnLoading"
            @click="perform">
            Perform
          </el-button>
        </div>
      </el-form>
      </div>
    </div>
  </div>
</template>

<script>
  import Pagination from '@/components/Pagination'
  import site from '../../http/api/site'
  import ocpp from '../../http/api/ocpp'
  import util from './operationUtil'
  const NOT_SPECIFIC = 'Not for a specific connector'
  export default {
    data() {
      return {
        tagLoading: false,
        listLoading: false,
        siteLoading: false,
        paramLoading: false,
        btnLoading: false,
        siteList: [],
        siteKeyword: '',
        stationList: [],
        total: 0,
        listQuery: {
          pageNo: 1,
          pageSize: 10,
          pageVo: {
            sitePk: '',
            stationId: ''
          }
        },
        operationInfo: {},
        operationList: ocpp.getOperationList(),
        operationForm: {
          value: '',
          confKey: '',
          keyType: '',
          resetType: '',
          operation: '',
          availType: '',
          idTagInfo: '',
          filterType: '',
          location: "",
          retrieve: "",
          retries: "",
          retryInterval: "",
          confKeyList: [],
          stationIds: [],
          stackLevel: '',
          connectorId: '',
          transactionId: '',
          customConfKey: '',
          chargingProfilePk: '',
          chargingProfilePurpose: undefined
        },
        paramsOption: {
          idTags: [],
          idTagAll: [],
          connectorIds: [],
          connectorActIds: [],
          needConnector: false,
          needActConnector: false,
          selectMultConfig: false,
          confKeyOption: [],
          keyTypeOption: [],
          availTypeOption: [],
          resetTypeOption: [],
          filterTypeOption: [],
          needCustomCoinfig: false,
          needChargingProfile: false,
          chargingProfileOption: [],
          chargingPurposeOption: [],
          needChargingProfilePurpose: false
        },
        rule: {
          idTagInfo: {
            required: true,
            trigger: 'change',
            message: 'Please select ID tag'
          },
          operation: {
            required: true,
            trigger: 'change',
            message: 'Please select operation'
          },
          confKey: {
            required: true,
            trigger: 'change',
            message: 'Please select configuration key'
          },
          keyType: {
            required: true,
            trigger: 'change',
            message: 'Please select key type'
          },
          resetType: {
            required: true,
            trigger: 'change',
            message: 'Please select reset type'
          },
          availType: {
            required: true,
            trigger: 'change',
            message: 'Please select availability type'
          },
          filterType: {
            required: true,
            trigger: 'change',
            message: 'Please select filter type'
          },
          connectorId: {
            required: true,
            trigger: 'change',
            message: 'Please select a connector ID'
          },
          confKeyList: {
            required: true,
            trigger: 'change',
            message: 'Please select at last least 1 config key'
          },
          transactionId: {
            required: true,
            trigger: 'change',
            message: 'Please select a active transaction ID'
          },
          customConfKey: {
            required: true,
            trigger: 'blur',
            message: 'Please input custom configuration key'
          },
          chargingProfilePk: {
            required: true,
            trigger: 'change',
            message: 'Please select Charging Profile ID'
          },
          chargingProfilePurpose: {
            required: true,
            trigger: 'change',
            message: 'Please select Charging Profile Purpose'
          },
          location: {
            required: true,
            trigger: 'blur',
            message: 'Please input location'
          },
          retrieve: {
            required: true,
            trigger: 'change',
            message: 'Please select retrieve date time'
          }
        },
        columns: [{
          key: 'siteName',
          label: 'Site Name'
        }, {
          key: 'stationId',
          label: 'Station ID'
        }, {
          key: 'lastHeartbeat',
          label: 'Last Heartbeat'
        }, {
          key: 'checked',
          label: 'Select',
          action: true,
          width: 70
        }],
        searchTag: ""
      }
    },
    components: { Pagination },
    created() {
      this.getAllSite();
    },
    methods: {
      filterSite(word) {
        this.siteKeyword = word;
        this.siteLoading = true;
        this.getAllSite();
      },
      getAllSite() {
        site.getAllSiteList({siteName: this.siteKeyword}).then(res => {
          var list = []
          if (this.siteKeyword == '') {
            list = [{siteName: 'All', sitePk: ''}]
          }
          if (res.data && res.data.length > 0) {
            this.siteList = list.concat(res.data)
          } else {
            this.siteList = []
          }
          this.siteLoading = false;
          this.changeSite();
        }).catch(err => {
          this.siteLoading = false;
        });
      },
      async changeSite() {
        this.listLoading = true;
        const res = await ocpp.getStationPages(this.listQuery);
        if (res.success) {
          this.total = res.total;
          this.stationList = res.data;
        }
        this.listLoading = false;
      },
      async changeOperation(index) {
        this.paramLoading = true;
        this.operationForm = {
          operation: this.operationForm.operation,
          value: '',
          confKey: '',
          keyType: '',
          resetType: '',
          availType: '',
          idTagInfo: '',
          filterType: '',
          location: "",
          retrieve: "",
          retries: "",
          retryInterval: "",
          confKeyList: [],
          stationIds: [],
          stackLevel: '',
          connectorId: '',
          transactionId: '',
          customConfKey: '',
          chargingProfilePk: '',
          chargingProfilePurpose: undefined
        }
        this.operationInfo = this.operationList[index];
        this.selectNone();
        this.paramsOption = await util.getOperationParams(this.operationInfo, /*this.getCheckedStation()*/);
        //console.log('-----', paramsOption);
        this.paramLoading = false;
        this.$refs['operationForm'].clearValidate()
      },
      async changeRow(index, checked) {
        if (checked && this.operationInfo.singleStation) {
          this.selectNone();
          this.stationList[index].checked = true;
        }
        this.operationForm.stationIds = this.getCheckedStation();
        if (this.paramsOption.needConnector) {
          this.operationForm.connectorId = '';
          let list = await util.getConnectorIds(this.operationForm.stationIds);
          if (this.operationInfo.value == 'RSTART') {
            list.unshift(NOT_SPECIFIC)
          }
          this.paramsOption.connectorIds = list
        }
        if (this.paramsOption.needActConnector) {
          this.operationForm.transactionId = '';
          let list = await util.getActiveConnectorIds(this.operationForm.stationIds);
          this.paramsOption.connectorActIds = list;
        }
      },
      changeKeyType() {
        if (this.operationForm.keyType == 'PREDEFINED') {
          this.operationForm.confKey = '';
        } else {
          this.operationForm.customConfKey = '';
        }
        this.$refs['operationForm'].clearValidate()
      },
      changeFilterType() {
        if (this.operationForm.filterType == 'ChargingProfileId') {
          this.operationForm.connectorId = '';
          this.paramsOption.needConnector = false;
          this.paramsOption.needChargingProfile = true;
          this.operationForm.chargingProfilePurpose = undefined;
          this.paramsOption.needChargingProfilePurpose = false;
        } else {
          this.paramsOption.needConnector = true;
          this.operationForm.chargingProfilePk = '';
          this.paramsOption.needChargingProfile = false;
          this.paramsOption.needChargingProfilePurpose = true;
          if (this.paramsOption.connectorIds.length == 0) {
            this.changeRow();
          }
        }
        this.$refs['operationForm'].clearValidate()
      },
      getCheckedStation() {
        let list = [];
        this.stationList.forEach(item => {
          if (item.checked)
            list.push(item.stationId)
        })
        return list;
      },
      selectNone() {
        this.stationList.forEach(item => {
          item.checked = false;
        })
        this.paramsOption.connectorIds = [];
        this.operationForm.connectorId = '';
        this.operationForm.stationIds = [];
      },
      selectAll() {
        if (!this.operationInfo.singleStation) {
          this.stationList.forEach(item => {
            item.checked = true;
          })
        } else {
          this.stationList[0].checked = true;
        }
        this.changeRow();
      },
      handlePageChange() {
        this.changeSite()
      },
      perform() {
        this.$forceUpdate();
        this.$refs['operationForm'].validate(result => {
          if (result) {
            //this.addStation();
            if (this.operationForm.stationIds.length == 0) {
              this.$message({
                type: 'error',
                message: 'Please select at least 1 charge point'
              })
            } else if (this.operationInfo.api) {
              this.btnLoading = true;
              const params = Object.assign({}, this.operationForm)
              //对参数做特殊处理
              if (params.connectorId === NOT_SPECIFIC) {
                params.connectorId = ''
              }
              if (params.idTagInfo !== '') {
                params.idTagInfo = JSON.parse(params.idTagInfo)
              }
              ocpp.sendPerform(this.operationInfo.api, params).then(res => {
                this.btnLoading = false;
                if (res.data.taskId) {
                  this.$router.push({path: '/ocpp-operations/result/' + res.data.taskId});
                }
              }).catch(err => {
                this.btnLoading = false;
                this.$message({
                  type: 'error',
                  message: err
                })
              });
            }
          }
        })
      },
      filterMobile(word) {
        if (word) {
          this.searchTag = word;
          setTimeout(() => {
            this.searchMobile(word)
          }, 300)
        } else {
          this.paramsOption.idTags = []
          this.paramsOption.idTags.push(...this.paramsOption.idTagAll)
        }
      },
      searchMobile(word) {
        console.log(this.searchTag, word);
        if (this.searchTag === word) {
          this.tagLoading = true;
          util.filterMobile(word, tags => {
            this.paramsOption.idTags = tags;
            this.tagLoading = false;
          })
        }
      }
    }
  }
</script>

<style scoped="scoped" lang='scss'>
  @import '../../styles/variables.scss';
  
  .card-container {
    width: 100%;
    padding: 20px 40px;
    min-height: $mainAppMinHeight;
    background-color: #F0F5FC;
  }
  .card-content {
    display: flex;
    overflow-x: auto;
    padding: 15px 5px;
    border-radius: 6px;
    flex-direction: row;
    flex-wrap: wrap-reverse;
    background-color: white;
  }
  .ocpp-content {
    flex: 1;
    min-width: 520px;
    padding: 0 35px 0 15px;
  }
  .section-title {
    color: #333;
    margin-top: 20px;
    margin-bottom: 30px;
    font-size: 16px;
    user-select: none;
    line-height: 24px;
    font-weight: 500;
    white-space: nowrap;
    font-family: sans-serif;
    text-transform: uppercase;
  }
  .perform {
    text-align: center;
    padding: 20px 80px 30px 0;
  }
  .multi-select {
    position: relative;
    min-height: 200px;
  }
  .note-span {
    top: 40px;
    left: 0px;
    width: 180px;
    color: #333333;
    padding: 6px 10px;
    font-size: 12px;
    border-radius: 3px;
    position: absolute;
    background-color: #56D905;
  }
  .flex-item {
    width: 100%;
    max-width: 320px;
  }
  @media screen and (max-width: 500px) {
    .card-container {
      padding: 0px;
    }
    .card-content {
      padding: 10px;
    }
    .ocpp-content {
      flex: 1;
      min-width: 320px;
      padding-right: 20px;
    }
    .perform {
      padding: 20px 0;
    }
  }
</style>