<template>
  <el-tabs v-model="activeTab" type="card">
    <el-tab-pane :label="$t(key('setting_value'))" name="process">
      <el-divider content-position="left">{{ $t(key('global_config')) }}</el-divider>
      <el-form :model="globalSetting" size="mini" label-width="130px" class="formation-global-form">
        <el-row :gutter="12">
          <el-col v-for="item in globalFields" :key="item.prop" :span="8">
            <el-form-item :label="$t(key(item.labelKey))">
              <el-input v-model="globalSetting[item.prop]" :placeholder="$t(key('enter_content'))" clearable>
                <el-button slot="append">{{ item.unit }}</el-button>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-divider content-position="left">{{ $t(key('set_process_step')) }}</el-divider>
      <el-button type="primary" icon="el-icon-plus" size="mini" style="margin-bottom:10px" @click="addRow">{{ $t(key('add_row')) }}</el-button>
      <el-table
        :data="tableData"
        border
        stripe
        size="mini"
        height="350"
        :row-class-name="rowClassName"
        style="width:100%"
      >
        <el-table-column width="56" fixed>
          <template slot-scope="{ $index }">
            <i v-if="$index > 0" class="el-icon-sort-up formation-sort" @click="moveUp($index)" />
            <i v-if="$index < tableData.length - 1" class="el-icon-sort-down formation-sort" @click="moveDown($index)" />
          </template>
        </el-table-column>
        <el-table-column :label="$t(key('process_step_no'))" width="56" fixed>
          <template slot-scope="{ $index }">{{ $index + 1 }}</template>
        </el-table-column>
        <el-table-column
          v-for="column in processColumns"
          :key="column.prop"
          :label="$t(key(column.labelKey))"
          :width="column.width"
          :fixed="column.prop === 'station'"
        >
          <template slot-scope="{ row }">
            <el-select
              v-if="column.type === 'select'"
              v-model="row[column.prop]"
              size="mini"
              clearable
              @change="column.prop === 'station' ? stationChange(row) : undefined"
            >
              <el-option
                v-for="option in $data[column.options]"
                :key="option.value"
                :label="option.labelKey ? $t(key(option.labelKey)) : option.label"
                :value="option.value"
              />
            </el-select>
            <el-input v-else v-model="row[column.prop]" size="mini" type="number" clearable />
          </template>
        </el-table-column>
        <el-table-column :label="$t(key('operation'))" width="80" fixed="right">
          <template slot-scope="{ $index }">
            <el-button type="text" size="mini" style="color:#F56C6C" @click="removeRow($index)">{{ $t(key('delete')) }}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-tab-pane>
    <el-tab-pane label="json" name="json">
      <tree-view :data="json" />
    </el-tab-pane>
  </el-tabs>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'

function parseSetting (value, fallback) {
  if (value === undefined || value === null || value === '') return JSON.parse(JSON.stringify(fallback))
  if (typeof value === 'object') return JSON.parse(JSON.stringify(value))
  try {
    return JSON.parse(value)
  } catch (e) {
    return JSON.parse(JSON.stringify(fallback))
  }
}

export default {
  name: 'ProcessStepFormationSettingPlugin',
  mixins: [i18nMixin('page.production_master_data.process_model.process_step')],
  props: {
    settingJson: { default: '' },
    workingsubclassCode: { type: String, default: '' }
  },
  data () {
    return {
      activeTab: 'process',
      json: { action: 'start', time: new Date(), process: [], setting: {} },
      globalSetting: {},
      tableData: [],
      stationList: [
        { labelKey: 'step_end', value: '6' },
        { labelKey: 'constant_current_charge', value: '1' },
        { labelKey: 'constant_current_voltage_charge', value: '2' },
        { labelKey: 'rest', value: '3' },
        { labelKey: 'constant_current_discharge', value: '4' },
        { labelKey: 'cycle', value: '5' },
        { labelKey: 'constant_current_voltage_discharge', value: '12' }
      ],
      timeOverList: [
        { label: '', value: '' },
        { label: 'OFF', value: 'OFF' },
        { label: 'TYPE_A', value: 'TYPE_A' },
        { label: 'TYPE_B', value: 'TYPE_B' }
      ],
      globalFields: [
        { prop: 'contact_check', labelKey: 'contact_check_alarm', unit: 'PIN' },
        { prop: 'curve_sampling_time', labelKey: 'curve_sampling_time', unit: 's' },
        { prop: 'device_emg_voltage', labelKey: 'emergency_stop_voltage', unit: 'mV' },
        { prop: 'alarm_temperature_upper', labelKey: 'slot_temperature_upper', unit: '℃' },
        { prop: 'fire_temperature_upper', labelKey: 'slot_fire_upper', unit: '℃' },
        { prop: 'upper_charging_voltage', labelKey: 'charge_voltage_upper', unit: 'mV' },
        { prop: 'lower_charging_voltage', labelKey: 'charge_voltage_lower', unit: 'mV' },
        { prop: 'upper_charging_current', labelKey: 'charge_current_upper', unit: 'mA' },
        { prop: 'lower_charging_current', labelKey: 'charge_current_lower', unit: 'mA' },
        { prop: 'upper_charging_capacity', labelKey: 'charge_capacity_upper', unit: 'mA/h' },
        { prop: 'lower_charging_capacity', labelKey: 'charge_capacity_lower', unit: 'mA/h' },
        { prop: 'upper_discharge_voltage', labelKey: 'discharge_voltage_upper', unit: 'mV' },
        { prop: 'lower_discharge_voltage', labelKey: 'discharge_voltage_lower', unit: 'mV' },
        { prop: 'upper_discharge_current', labelKey: 'discharge_current_upper', unit: 'mA' },
        { prop: 'lower_discharge_current', labelKey: 'discharge_current_lower', unit: 'mA' },
        { prop: 'upper_discharge_capacity', labelKey: 'discharge_capacity_upper', unit: 'mA/h' },
        { prop: 'lower_discharge_capacity', labelKey: 'discharge_capacity_lower', unit: 'mA/h' }
      ],
      processColumns: [
        { prop: 'station', labelKey: 'step_status', width: 120, type: 'select', options: 'stationList' },
        { prop: 'time', labelKey: 'time_seconds', width: 120 },
        { prop: 'current', labelKey: 'current_ma', width: 120 },
        { prop: 'upperVoltage', labelKey: 'upper_voltage_mv', width: 120 },
        { prop: 'lowerVoltage', labelKey: 'lower_voltage_mv', width: 120 },
        { prop: 'stop_DeltaVoltage', labelKey: 'delta_voltage_mv', width: 100 },
        { prop: 'stop_Current', labelKey: 'stop_current_ma', width: 120 },
        { prop: 'stop_Capacity', labelKey: 'stop_capacity_mah', width: 130 },
        { prop: 'cct_begin', labelKey: 'cct_lower_s', width: 100 },
        { prop: 'cct_end', labelKey: 'cct_upper_s', width: 100 },
        { prop: 'time_over', labelKey: 'timeover', width: 120, type: 'select', options: 'timeOverList' },
        { prop: 'temperature', labelKey: 'temperature_c', width: 100 },
        { prop: 'upperTemperature', labelKey: 'temperature_upper_c', width: 120 },
        { prop: 'lowerTemperature', labelKey: 'temperature_lower_c', width: 120 },
        { prop: 'pressure', labelKey: 'pressure_kg', width: 100 }
      ]
    }
  },
  watch: {
    settingJson: {
      handler (val) {
        const parsed = parseSetting(val, {
          action: 'start',
          time: new Date(),
          process: [],
          setting: { contact_check: '0', curve_sampling_time: 10 }
        })
        parsed.process = Array.isArray(parsed.process) ? parsed.process : []
        parsed.setting = parsed.setting || {}
        this.json = parsed
        this.globalSetting = { ...parsed.setting }
        for (const key of this.globalFields.map(item => item.prop)) {
          if (Object.prototype.hasOwnProperty.call(parsed, key) && !Object.prototype.hasOwnProperty.call(this.globalSetting, key)) {
            this.$set(this.globalSetting, key, parsed[key])
          }
        }
        this.tableData = parsed.process.map(row => ({
          ...row,
          station: row.station !== undefined && row.station !== null ? String(row.station) : '',
          time_over: row.time_over !== undefined && row.time_over !== null ? String(row.time_over) : ''
        }))
      },
      immediate: true
    },
    globalSetting: {
      handler () {
        this.syncJson()
      },
      deep: true
    },
    tableData: {
      handler () {
        this.syncJson()
      },
      deep: true
    }
  },
  methods: {
    syncJson () {
      const setting = {}
      Object.keys(this.globalSetting || {}).forEach(key => {
        const value = this.globalSetting[key]
        if (value !== '' && value !== undefined && value !== null) {
          setting[key] = this.toNumberIfNumeric(value)
        }
      })
      const process = this.tableData.map(row => {
        const item = {}
        Object.keys(row).forEach(key => {
          const value = row[key]
          if (value !== '' && value !== undefined && value !== null) {
            item[key] = key === 'time_over' ? value : this.toNumberIfNumeric(value)
          }
        })
        return item
      })
      if (process[0] && setting.contact_check !== undefined) {
        process[0].contact_check = setting.contact_check
      }
      this.json = {
        ...this.json,
        process,
        setting
      }
    },
    toNumberIfNumeric (value) {
      if (value === '' || value === null || value === undefined) return value
      return /^-?\d+(\.\d+)?$/.test(String(value)) ? Number(value) : value
    },
    rowClassName ({ row }) {
      const station = String(row.station)
      if (station === '5') return 'formation-row-cycle'
      if (station === '1') return 'formation-row-charge'
      if (station === '2') return 'formation-row-charge-cv'
      if (station === '3') return 'formation-row-rest'
      if (station === '4') return 'formation-row-discharge'
      return ''
    },
    addRow () {
      if (this.tableData.some(row => String(row.station) === '6')) {
        this.$message.info(this.$t(this.key('end_step_exists')))
        return
      }
      this.tableData.push({ station: '' })
    },
    removeRow (index) {
      this.tableData.splice(index, 1)
    },
    moveUp (index) {
      if (index <= 0) return
      const row = this.tableData.splice(index, 1)[0]
      this.tableData.splice(index - 1, 0, row)
    },
    moveDown (index) {
      if (index >= this.tableData.length - 1) return
      const row = this.tableData.splice(index, 1)[0]
      this.tableData.splice(index + 1, 0, row)
    },
    stationChange (row) {
      if (String(row.station) === '5') {
        Object.keys(row).forEach(key => {
          if (key !== 'station') this.$set(row, key, '')
        })
      }
      if (String(row.station) === '6') {
        const index = this.tableData.indexOf(row)
        this.tableData = this.tableData.slice(0, index + 1)
      }
    },
    showMsg (message) {
      this.$message.warning(message)
    },
    validateProcess () {
      if (!this.tableData.some(row => String(row.station) === '6')) {
        this.$message.info(this.$t(this.key('missing_end_step')))
        return false
      }
      const process = this.json.process || []
      for (let n = 0; n < process.length; n++) {
        const row = process[n]
        const station = Number(row.station)
        const miss = labelKey => {
          this.showMsg(this.$t(this.key('required_step_field_missing'), { step: n + 1, name: this.$t(this.key(labelKey)) }))
          return false
        }
        if ((this.workingsubclassCode === 'HC' || this.workingsubclassCode === 'FR') && station !== 6) {
          if (row.pressure === undefined || row.pressure === '') return miss('pressure')
          if (row.temperature === undefined || row.temperature === '') return miss('temperature')
        }
        if (station === 3) {
          if (row.time === undefined || row.time === '') return miss('work_time')
        } else if (station === 12 || station === 2) {
          if (row.time === undefined || row.time === '') return miss('work_time')
          if (row.current === undefined || row.current === '') return miss('current')
          if (row.stop_Current === undefined || row.stop_Current === '') return miss('stop_current')
          if (station === 12 && (row.lowerVoltage === undefined || row.lowerVoltage === '')) return miss('lower_voltage')
          if (station === 2 && (row.upperVoltage === undefined || row.upperVoltage === '')) return miss('upper_voltage')
        } else if (station === 4 || station === 1) {
          if (row.time === undefined || row.time === '') return miss('work_time')
          if (row.current === undefined || row.current === '') return miss('current')
          if (station === 4 && (row.lowerVoltage === undefined || row.lowerVoltage === '')) return miss('lower_voltage')
          if (station === 1 && (row.upperVoltage === undefined || row.upperVoltage === '')) return miss('upper_voltage')
        }
      }
      return true
    },
    handleFormSubmit () {
      this.syncJson()
      if (!this.validateProcess()) return
      this.$emit('submit', this.json)
    }
  }
}
</script>

<style scoped>
.formation-global-form /deep/ .el-form-item--mini.el-form-item {
  margin-bottom: 8px;
}
.formation-sort {
  cursor: pointer;
  margin-right: 4px;
  color: #409EFF;
}
/deep/ .formation-row-cycle {
  background-color: #ffc0ff !important;
}
/deep/ .formation-row-charge {
  background-color: #ffff00 !important;
}
/deep/ .formation-row-charge-cv {
  background-color: #ffffc0 !important;
}
/deep/ .formation-row-rest {
  background-color: #e0e0e0 !important;
}
/deep/ .formation-row-discharge {
  background-color: #c0c0c0 !important;
}
</style>
