<template>
  <d2-container>
    <template #header>
      <div class="search-bar">
        <el-form ref="searchForm" :inline="true" :model="search" size="mini">
          <el-form-item :label="$t(key('tray_code'))" prop="tray">
            <el-input
              v-model="search.tray"
              prefix-icon="el-icon-search"
              :placeholder="$t(key('tray_code_placeholder'))"
              clearable
              style="width:220px"
              @keyup.enter.native="onSearch"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">
              {{ $t(key('query')) }}
            </el-button>
            <el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">
              {{ $t(key('reset')) }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </template>

    <div v-loading="loading" class="tray-management">
      <el-empty v-if="!hasTrayData" :description="$t(key('enter_tray_to_query'))" />
      <el-container v-else class="tray-layout">
        <el-aside width="260px" class="process-aside">
          <el-menu :default-active="activeProcessIndex" @select="selectProcess">
            <el-menu-item
              v-for="(item, index) in dateLog"
              :key="index"
              :index="String(index)"
            >
              <div class="process-item">
                <p class="process-title">
                  {{ item.flow_process_code || item.name }}
                  <span v-if="Number(item.idx) === Number(trayData.process_idx) + 1">
                    [{{ $t(key('current_process')) }}]
                  </span>
                </p>
                <p>{{ $t(key('start_time')) }}: {{ item.beginTime }}</p>
                <p>{{ $t(key('end_time')) }}: {{ item.endTime }}</p>
                <p>{{ $t(key('device_code')) }}: {{ item.device_code }}</p>
              </div>
            </el-menu-item>
          </el-menu>
        </el-aside>

        <el-container>
          <el-header height="auto" class="tray-header">
            <el-form label-width="90px" size="small">
              <el-row :gutter="10">
                <el-col :span="6">
                  <el-form-item :label="$t(key('batch'))">
                    <el-input :value="trayData.batch" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item :label="$t(key('lot'))">
                    <el-input :value="trayData.lot" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item :label="$t(key('input_battery_count'))">
                    <el-input :value="trayData.actual_input_battery_count" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item :label="$t(key('input_time'))">
                    <el-input :value="trayData.create_time" disabled />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="10">
                <el-col :span="6">
                  <el-form-item :label="$t(key('previous_process'))">
                    <el-input :value="trayData.process_code" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item :label="$t(key('current_process'))">
                    <el-input :value="trayData.next_process_code" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item :label="$t(key('status'))">
                    <el-input :value="trayData.process_code ? $t(key('activated')) : ''" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item :label="$t(key('tray_ng'))">
                    <el-input
                      :value="trayData.ngclassname"
                      :class="{ 'is-ng': Number(trayData.is_ng) === 1 }"
                      disabled
                    />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-form>
          </el-header>

          <el-main class="tray-main">
            <div class="actions">
              <el-button v-if="auth.stop" type="danger" size="mini" @click="handleStopTray">
                {{ $t(key('stop_tray')) }}
              </el-button>
              <el-button v-if="auth.ALLNG" type="warning" size="mini" @click="handleNgTray">
                {{ $t(key('tray_ng')) }}
              </el-button>
              <el-button v-if="auth.FX" type="primary" size="mini" @click="handleRangeFx">
                {{ $t(key('capacity_sorting')) }}
              </el-button>
              <el-button v-if="auth.TRAY_NG" type="danger" size="mini" @click="handleCleanTrayNg">
                {{ $t(key('clear_tray_ng')) }}
              </el-button>
            </div>

            <div class="tray-grid-wrap">
              <div class="tray-row tray-head">
                <div :class="breachClass('left_top')" />
                <div class="tray-cols">
                  <span v-for="item in trayCol" :key="item">{{ item }}</span>
                </div>
                <div :class="breachClass('right_top')" />
              </div>

              <div
                v-for="(row, rowIndex) in trayRows"
                :key="rowIndex"
                class="tray-row"
                :style="{ height: cellHeight + 'px' }"
              >
                <div class="row-label">{{ rowIndex + 1 }}</div>
                <div class="tray-cells">
                  <div
                    v-for="idx in row"
                    :key="idx"
                    class="tray-cell"
                    :style="{ background: batteryBackground(batteryInfo[idx - 1]) }"
                    @click="openBattery(idx)"
                  >
                    <span class="cell-index">{{ idx }}</span>
                    <span v-if="batteryInfo[idx - 1] && batteryInfo[idx - 1].classname" class="cell-class">
                      {{ batteryInfo[idx - 1].classname }}
                    </span>
                  </div>
                </div>
                <div class="row-label">{{ rowIndex + 1 }}</div>
              </div>

              <div class="tray-row tray-head">
                <div :class="breachClass('left_bottom')" />
                <div class="tray-cols">
                  <span v-for="item in trayCol" :key="item">{{ item }}</span>
                </div>
                <div :class="breachClass('right_bottom')" />
              </div>
            </div>
          </el-main>
        </el-container>
      </el-container>
    </div>

    <el-dialog :title="batteryDialogTitle" :visible.sync="batteryDialogVisible" width="420px">
      <el-descriptions :column="1" border size="mini">
        <el-descriptions-item :label="$t(key('battery_id'))">
          {{ selectedBattery.battery_id }}
        </el-descriptions-item>
        <el-descriptions-item :label="$t(key('grade'))">
          {{ selectedBattery.classname }}
        </el-descriptions-item>
        <el-descriptions-item :label="$t(key('activation_status'))">
          {{ Number(selectedBattery.active) === 1 ? $t(key('activated')) : $t(key('not_activated')) }}
        </el-descriptions-item>
      </el-descriptions>
      <span slot="footer">
        <el-button size="mini" @click="batteryDialogVisible = false">{{ $t(key('cancel')) }}</el-button>
      </span>
    </el-dialog>
  </d2-container>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import {
  getTrayManageInfo,
  changeFlowProcess,
  trayNg,
  rangeFx,
  cleanTrayNg
} from '@/api/planning-production/tray-management'
import { sendWorkerman } from '@/api/production-master-data/workerman'

export default {
  name: 'planning-production-tray-management',
  mixins: [i18nMixin('page.planning_production.production_monitoring.tray_management')],
  data () {
    return {
      loading: false,
      search: {
        tray: this.$route.query.tray || ''
      },
      trayData: {},
      auth: {
        stop: false,
        ALLNG: false,
        FX: false,
        TRAY_NG: false
      },
      batteryDialogVisible: false,
      batteryDialogTitle: '',
      selectedBattery: {}
    }
  },
  computed: {
    hasTrayData () {
      return !!(this.trayData && this.trayData.tray)
    },
    dateLog () {
      const value = this.trayData.date_log
      if (Array.isArray(value)) return value
      if (!value) return []
      try {
        return JSON.parse(value)
      } catch (e) {
        return []
      }
    },
    trayFormat () {
      return this.trayData.tary_format_data || {}
    },
    trayCol () {
      return Number(this.trayFormat.tray_col || 14)
    },
    trayRow () {
      return Number(this.trayFormat.tray_row || 14)
    },
    breach () {
      return this.trayFormat.breach || 'left_bottom'
    },
    dataBreach () {
      return this.trayFormat.data_breach || 'left_top'
    },
    direction () {
      return this.trayFormat.direction || 'horizontal'
    },
    shape () {
      return this.trayFormat.shape || 'NU'
    },
    cellHeight () {
      return Number(this.trayFormat.cellheight || 35)
    },
    batteryInfo () {
      return this.trayData.battery_info || []
    },
    activeProcessIndex () {
      return String(Number(this.trayData.process_idx || 0) + 1)
    },
    trayRows () {
      const rows = []
      for (let x = 0; x < this.trayRow; x++) {
        const row = []
        for (let y = 0; y < this.trayCol; y++) {
          let idx
          if (this.direction === 'vertical') {
            idx = x + 1 + this.trayRow * y
            if (this.shape !== 'NU' && y % 2 === 1) {
              idx = this.trayRow - x + this.trayRow * y
            }
          } else {
            idx = this.trayCol * x + y + 1
          }
          row.push(idx)
        }
        if (this.direction === 'horizontal' && this.shape !== 'NU' && x % 2 === 1) {
          row.reverse()
        }
        rows.push(row)
      }

      if (this.dataBreach === 'left_bottom') {
        rows.reverse()
      } else if (this.dataBreach === 'right_top') {
        rows.forEach(row => row.reverse())
      } else if (this.dataBreach === 'right_bottom') {
        rows.reverse()
        rows.forEach(row => row.reverse())
      }

      return rows
    }
  },
  watch: {
    '$route.query.tray' (tray) {
      this.search.tray = tray || ''
    }
  },
  mounted () {
    this.initAuth()
    if (this.search.tray) this.fetchData()
  },
  methods: {
    initAuth () {
      const can = key => (this.$permission ? this.$permission(key) : true)
      this.auth.stop = can('/produce/monitor/trayManage/stop')
      this.auth.ALLNG = can('/produce/monitor/trayManage/ALLNG')
      this.auth.FX = can('/produce/monitor/trayManage/FX')
      this.auth.TRAY_NG = can('/produce/monitor/trayManage/TRAY_NG')
    },
    fetchData () {
      if (!this.search.tray) {
        this.trayData = {}
        return
      }
      this.loading = true
      getTrayManageInfo({ ...this.search })
        .then(res => {
          const payload = res && res.data ? res.data : res
          this.trayData = payload && payload.data ? payload.data : (payload || {})
        })
        .finally(() => {
          this.loading = false
        })
    },
    onSearch () {
      this.fetchData()
    },
    onReset () {
      this.$refs.searchForm.resetFields()
      this.trayData = {}
    },
    refreshTray () {
      this.fetchData()
    },
    confirmAction (message, handler) {
      this.$confirm(message, this.$t(this.key('prompt')), {
        confirmButtonText: this.$t(this.key('confirm')),
        cancelButtonText: this.$t(this.key('cancel')),
        type: 'warning'
      })
        .then(handler)
        .catch(() => {
          this.$message.info(this.$t(this.key('operation_cancelled')))
        })
    },
    handleStopTray () {
      this.confirmAction(this.$t(this.key('confirm_stop_tray')), () => {
        return sendWorkerman({
          sendData: {
            action: 'set_tray_inactivity',
            param: { tray: this.trayData.tray }
          }
        }).then(() => {
          this.$message.success(this.$t(this.key('operation_success')))
          this.refreshTray()
        })
      })
    },
    handleNgTray () {
      this.confirmAction(this.$t(this.key('confirm_full_tray_ng')), () => {
        return trayNg({ tray: this.trayData.tray }).then(() => {
          this.$message.success(this.$t(this.key('full_tray_ng_success')))
          this.refreshTray()
        })
      })
    },
    handleCleanTrayNg () {
      this.confirmAction(this.$t(this.key('confirm_clear_tray_ng')), () => {
        return cleanTrayNg({
          lot: this.trayData.lot,
          subbatch: this.trayData.subbatch,
          tray: this.trayData.tray,
          next_process_code: this.trayData.next_process_code
        }).then(() => {
          this.$message.success(this.$t(this.key('operation_success')))
          this.refreshTray()
        })
      })
    },
    handleRangeFx () {
      this.confirmAction(this.$t(this.key('confirm_capacity_resort')), () => {
        return rangeFx({
          lot: this.trayData.lot,
          subbatch: this.trayData.subbatch,
          tray: this.trayData.tray
        }).then(() => {
          this.$message.success(this.$t(this.key('operation_success')))
          this.refreshTray()
        })
      })
    },
    selectProcess (index) {
      const currentIndex = Number(this.trayData.process_idx || 0) + 1
      if (Number(index) === currentIndex) return
      if (Number(index) === 0) {
        this.$message.info(this.$t(this.key('cannot_adjust_to_initial_process')))
        return
      }
      this.confirmAction(this.$t(this.key('confirm_adjust_tray_process')), () => {
        const prev = this.dateLog[Number(index) - 1] || {}
        const next = this.dateLog[Number(index)] || {}
        return changeFlowProcess({
          variable: 1,
          lot: this.trayData.lot,
          subbatch: this.trayData.subbatch,
          tray: this.trayData.tray,
          process_code: prev.flow_process_code || '',
          process_idx: prev.idx || 0,
          next_process_code: next.flow_process_code || '',
          clear_ng: false
        }).then(() => {
          this.$message.success(this.$t(this.key('adjust_process_success')))
          this.refreshTray()
        })
      })
    },
    batteryBackground (item = {}) {
      if (item && item.battery_id) {
        if (Number(item.active) === 1) {
          if (item.class === 'NG') return '#F56C6C'
          if (item.class === 'RC') return 'yellowgreen'
          return '#317894'
        }
        return '#908D8D'
      }
      return '#F5F7FA'
    },
    openBattery (idx) {
      const battery = this.batteryInfo[idx - 1]
      if (!battery || !battery.battery_id) return
      this.selectedBattery = battery
      this.batteryDialogTitle = this.$t(this.key('channel_battery_info'), { index: idx })
      this.batteryDialogVisible = true
    },
    breachClass (position) {
      return this.breach === position ? `tray-breach tray-breach--${position}` : 'tray-corner'
    }
  }
}
</script>

<style lang="scss" scoped>
.search-bar {
  margin-bottom: -18px;
}
.tray-management,
.tray-layout {
  height: 100%;
}
.process-aside {
  background: #eef1f6;
  overflow: auto;
}
.process-item {
  line-height: 22px;
  font-size: 12px;
  white-space: normal;
}
.process-item p {
  margin: 0;
}
.process-title {
  font-size: 14px;
  font-weight: 600;
}
.tray-header {
  padding: 10px 12px 0;
}
.tray-header ::v-deep .el-form-item {
  margin-bottom: 8px;
}
.tray-header ::v-deep .is-ng .el-input__inner {
  color: #F56C6C;
}
.tray-main {
  padding: 10px 12px;
  overflow: auto;
}
.actions {
  margin-bottom: 10px;
}
.tray-grid-wrap {
  width: 100%;
  min-width: 760px;
  border-top: 1px solid #ddd;
  border-left: 1px solid #ddd;
}
.tray-row {
  display: flex;
}
.tray-head {
  height: 28px;
  line-height: 28px;
}
.tray-corner,
.tray-breach {
  width: 26px;
  flex: 0 0 26px;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
  background: #fff;
}
.tray-breach {
  background: #303133;
}
.tray-cols,
.tray-cells {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(var(--tray-col), 1fr);
}
.tray-cols {
  display: flex;
}
.tray-cols span {
  flex: 1;
  text-align: center;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
  background: #fafafa;
}
.row-label {
  width: 26px;
  flex: 0 0 26px;
  text-align: center;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
  background: #fafafa;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tray-cells {
  grid-template-columns: repeat(auto-fit, minmax(24px, 1fr));
}
.tray-cell {
  position: relative;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
  color: #fff;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  overflow: hidden;
}
.cell-index {
  font-size: 12px;
  line-height: 14px;
}
.cell-class {
  font-size: 12px;
  line-height: 14px;
}
</style>
